import model.Coord import model.Customer import model.HHCEdge import scala.collection.mutable.ArrayBuffer import util.Util import config.Conf import java.io.File import scala.io.Source object Main { def main(args: Array[String]): Unit = { val conf = new Conf(args.toIndexedSeq) val bufferedSource = Source.fromFile(conf.infile()) val customers = Util.getCustomers(bufferedSource) bufferedSource.close() val hhc = new HHCSim(epsilonMax = 40, iterations = 10, WLDMax = 10) val fnl2 = hhc.go(customers) // customers.map(println(_)) // val edges3 = customers.map(Util.formAdjMatrix) // val fnl2 = go(customers) fnl2 match { case Left(value) => println(value) case Right(groups) => groups.foreach(c => { print(s"${c._1} -> ") c._2.foreach(e => { print(f"(${e._1}%d, ${e._2}%.2f), ") }) println }) } // edges3 match { // case Right(e) => // e.foreach { d => // d.foreach(g => print(f"$g%.2f, ")) // println() // } // case Left(e) => // println(s"Oops, an error occured. The error message was: $e") // } val coord1 = Coord(3, 4) println(s"Distance from origin = ${coord1.distance}") val cust1 = Customer(coord1, 5) val cust2 = Customer(Coord(2, 5), 7) println(s"Customer 1 = ${cust1}") println(s"Customer 2 = ${cust2}") val cust3 = Customer(Coord(3, 5), 6) val cust4 = Customer(Coord(6, 8), 9) val cust5 = Customer(Coord(5, 4), 6) val edge1 = HHCEdge(cust1, cust2) val edge2 = HHCEdge(cust3, cust4) println(s"Edge 1 = ${edge1}") println(s"Edge 1 weight = ${edge1.weight}") val V = Array(cust1, cust2, cust3, cust4, cust5) val E = Array(edge1, edge2) V.foreach(println(_)) // prints // Customer(Coord(3, 4), 5) // Customer(Coord(2, 5), 7) // Customer(Coord(3, 5), 6) // Customer(Coord(6, 8), 9) // Customer(Coord(5, 4), 6) E.foreach(println(_)) //prints // HHCEdge(Customer(Coord(3, 4), 5), Customer(Coord(2, 5), 7)) // HHCEdge(Customer(Coord(3, 5), 6), Customer(Coord(6, 8), 9)) // sample adjacency // format: off val edgesSeq = Seq( Seq(0 , 9 , 75, 0 , 0), Seq(9 , 0 , 95, 19, 42), Seq(75, 95, 0 , 51, 66), Seq(0 , 19, 51, 0 , 31), Seq(0 , 42, 66, 31, 0) ); // adjacency list form // 0 -> 1 -> 2 // 1 -> 0 -> 2 -> 3 -> 4 // 2 -> 0 -> 1 -> 3 -> 4 // 3 -> 1 -> 2 -> 4 // 4 -> 1 -> 2 -> 3 val edges = edgesSeq.map(e => { e.toArray }).toArray val mst = Util.mstUsingPrims(edges) // mst // 0, 9 , 0 , 0 , 0 // 9, 0 , 0 , 19, 0 // 0, 0 , 0 , 51, 0 // 0, 19, 51, 0 , 31 // 0, 0 , 0 , 31, 0 // format: on // Prim's algorithm // Prim's algorithm result // Edge selected 0 - 1: 9 // Edge selected 1 - 3: 19 // Edge selected 3 - 4: 31 // Edge selected 3 - 2: 51 // Verify the result with the one at https://www.programiz.com/dsa/prim-algorithm val edges2: Array[Array[Double]] = Array.ofDim(5, 5) // create adjacency matrix from given customers for (i <- 0 to 4) { for (j <- 0 to 4) { edges2(i)(j) = Util.getHaversineDistance(V(i).location, V(j).location) } } edges2.foreach { e => e.foreach { d => print(f"$d%.2f, ") } println() } // prints // 0.00 , 159.64, 112.79, 563.55, 225.88 // 159.64, 0.00 , 112.94, 564.16, 357.08 // 112.79, 112.94, 0.00 , 478.40, 252.42 // 563.55, 564.16, 478.40, 0.00 , 463.64 // 225.88, 357.08, 252.42, 463.64, 0.00 println() println("Initial graph:") edgesSeq.foreach { e => e.foreach { d => print(s"$d, ") } println() } println("MST: ") mst.foreach { e => e.foreach { d => print(s"$d, ") } println() } // 0, 9, 0 , 0 , 0 // 0, 0, 0 , 19, 0 // 0, 0, 0 , 0 , 0 // 0, 0, 51, 0 , 31 // 0, 0, 0 , 0 , 0 val (mst2, centr, removed) = Util.findCentroids(mst) // val (centr2, eds2) = Util.findCentroids(edges2) println() println(s"Centroids: \n$centr") println(s"Removed: \n$removed") val (_, clust, _) = Util.findClusters(mst, centr, removed) val adjList = Util.makeAdjacencyList(edges, centr) println(s"Clusters:") clust.foreach(c => { val (e, d) = c print(s"$e: ") d.foreach(f => { print(s"-> $f ") }) println() }) println() val fnl = Util.groupClusters(centr, clust, removed) println(s"Final cluster groups: \n$fnl") // Output // // Initial graph: // 0, 9, 75, 0, 0, // 9, 0, 95, 19, 42, // 75, 95, 0, 51, 66, // 0, 19, 51, 0, 31, // 0, 42, 66, 31, 0, // MST: // 0, 9, 0, 0, 0, // 9, 0, 0, 19, 0, // 0, 0, 0, 51, 0, // 0, 19, 51, 0, 31, // 0, 0, 0, 31, 0, // Centroids: // Vector(2, 3, 4) // Removed: // Vector((2,3,51), (3,2,51), (3,4,31), (4,3,31)) // Clusters: // 2: -> 2 // 3: -> 3 -> 1 -> 0 // 4: -> 4 // Final cluster groups: // Map(2 -> Vector((3,51)), 3 -> Vector((4,31), (2,51)), 4 -> Vector((3,31))) } }