You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
4.9 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. import model.Coord
  2. import model.Customer
  3. import model.HHCEdge
  4. import scala.collection.mutable.ArrayBuffer
  5. import util.Util
  6. import config.Conf
  7. import java.io.File
  8. object Main {
  9. def main(args: Array[String]): Unit = {
  10. val conf = new Conf(args.toIndexedSeq)
  11. val bufferedSource = io.Source.fromFile(conf.infile())
  12. val customers = Util.getCustomers(bufferedSource)
  13. bufferedSource.close()
  14. // customers.map(println(_))
  15. // val edges3 = customers.map(Util.formAdjMatrix)
  16. // val fnl2 = go(customers)
  17. // fnl2 match {
  18. // case Left(value) => println(value)
  19. // case Right(value) => println(value)
  20. // }
  21. // edges3 match {
  22. // case Right(e) =>
  23. // e.foreach { d =>
  24. // d.foreach(g => print(f"$g%.2f, "))
  25. // println()
  26. // }
  27. // case Left(e) =>
  28. // println(s"Oops, an error occured. The error message was: $e")
  29. // }
  30. val coord1 = Coord(3, 4)
  31. println(s"Distance from origin = ${coord1.distance}")
  32. val cust1 = Customer(coord1, 5)
  33. val cust2 = Customer(Coord(2, 5), 7)
  34. println(s"Customer 1 = ${cust1}")
  35. println(s"Customer 2 = ${cust2}")
  36. val cust3 = Customer(Coord(3, 5), 6)
  37. val cust4 = Customer(Coord(6, 8), 9)
  38. val cust5 = Customer(Coord(5, 4), 6)
  39. val edge1 = HHCEdge(cust1, cust2)
  40. val edge2 = HHCEdge(cust3, cust4)
  41. println(s"Edge 1 = ${edge1}")
  42. println(s"Edge 1 weight = ${edge1.weight}")
  43. val V = Array(cust1, cust2, cust3, cust4, cust5)
  44. val E = Array(edge1, edge2)
  45. V.foreach(println(_))
  46. // prints
  47. // Customer(Coord(3, 4), 5)
  48. // Customer(Coord(2, 5), 7)
  49. // Customer(Coord(3, 5), 6)
  50. // Customer(Coord(6, 8), 9)
  51. // Customer(Coord(5, 4), 6)
  52. E.foreach(println(_))
  53. //prints
  54. // HHCEdge(Customer(Coord(3, 4), 5), Customer(Coord(2, 5), 7))
  55. // HHCEdge(Customer(Coord(3, 5), 6), Customer(Coord(6, 8), 9))
  56. // sample adjacency
  57. // format: off
  58. val edgesSeq = Seq(
  59. Seq(0 , 9 , 75, 0 , 0),
  60. Seq(9 , 0 , 95, 19, 42),
  61. Seq(75, 95, 0 , 51, 66),
  62. Seq(0 , 19, 51, 0 , 31),
  63. Seq(0 , 42, 66, 31, 0)
  64. );
  65. // adjacency list form
  66. // 0 -> 1 -> 2
  67. // 1 -> 0 -> 2 -> 3 -> 4
  68. // 2 -> 0 -> 1 -> 3 -> 4
  69. // 3 -> 1 -> 2 -> 4
  70. // 4 -> 1 -> 2 -> 3
  71. val edges = edgesSeq.map(e => {
  72. e.toArray
  73. }).toArray
  74. val mst = Util.mstUsingPrims(edges)
  75. // mst
  76. // 0, 9 , 0 , 0 , 0
  77. // 9, 0 , 0 , 19, 0
  78. // 0, 0 , 0 , 51, 0
  79. // 0, 19, 51, 0 , 31
  80. // 0, 0 , 0 , 31, 0
  81. // format: on
  82. // Prim's algorithm
  83. // Prim's algorithm result
  84. // Edge selected 0 - 1: 9
  85. // Edge selected 1 - 3: 19
  86. // Edge selected 3 - 4: 31
  87. // Edge selected 3 - 2: 51
  88. // Verify the result with the one at https://www.programiz.com/dsa/prim-algorithm
  89. val edges2: Array[Array[Double]] = Array.ofDim(5, 5)
  90. // create adjacency matrix from given customers
  91. for (i <- 0 to 4) {
  92. for (j <- 0 to 4) {
  93. edges2(i)(j) = Util.getHaversineDistance(V(i).location, V(j).location)
  94. }
  95. }
  96. edges2.foreach { e =>
  97. e.foreach { d =>
  98. print(f"$d%.2f, ")
  99. }
  100. println()
  101. }
  102. // prints
  103. // 0.00 , 159.64, 112.79, 563.55, 225.88
  104. // 159.64, 0.00 , 112.94, 564.16, 357.08
  105. // 112.79, 112.94, 0.00 , 478.40, 252.42
  106. // 563.55, 564.16, 478.40, 0.00 , 463.64
  107. // 225.88, 357.08, 252.42, 463.64, 0.00
  108. println()
  109. println("Initial graph:")
  110. edgesSeq.foreach { e =>
  111. e.foreach { d =>
  112. print(s"$d, ")
  113. }
  114. println()
  115. }
  116. println("MST: ")
  117. mst.foreach { e =>
  118. e.foreach { d =>
  119. print(s"$d, ")
  120. }
  121. println()
  122. }
  123. // 0, 9, 0 , 0 , 0
  124. // 0, 0, 0 , 19, 0
  125. // 0, 0, 0 , 0 , 0
  126. // 0, 0, 51, 0 , 31
  127. // 0, 0, 0 , 0 , 0
  128. val (mst2, centr, removed) = Util.findCentroids(mst)
  129. // val (centr2, eds2) = Util.findCentroids(edges2)
  130. println()
  131. println(s"Centroids: \n$centr")
  132. println(s"Removed: \n$removed")
  133. val (_, clust, _) = Util.findClusters(mst, centr, removed)
  134. val adjList = Util.makeAdjacencyList(edges, centr)
  135. println(s"Clusters:")
  136. clust.foreach(c => {
  137. val (e, d) = c
  138. print(s"$e: ")
  139. d.foreach(f => {
  140. print(s"-> $f ")
  141. })
  142. println()
  143. })
  144. println()
  145. val fnl = Util.groupClusters(centr, clust, removed)
  146. println(s"Final cluster groups: \n$fnl")
  147. // Output
  148. //
  149. // Initial graph:
  150. // 0, 9, 75, 0, 0,
  151. // 9, 0, 95, 19, 42,
  152. // 75, 95, 0, 51, 66,
  153. // 0, 19, 51, 0, 31,
  154. // 0, 42, 66, 31, 0,
  155. // MST:
  156. // 0, 9, 0, 0, 0,
  157. // 9, 0, 0, 19, 0,
  158. // 0, 0, 0, 51, 0,
  159. // 0, 19, 51, 0, 31,
  160. // 0, 0, 0, 31, 0,
  161. // Centroids:
  162. // Vector(2, 3, 4)
  163. // Removed:
  164. // Vector((2,3,51), (3,2,51), (3,4,31), (4,3,31))
  165. // Clusters:
  166. // 2: -> 2
  167. // 3: -> 3 -> 1 -> 0
  168. // 4: -> 4
  169. // Final cluster groups:
  170. // Map(2 -> Vector((3,51)), 3 -> Vector((4,31), (2,51)), 4 -> Vector((3,31)))
  171. }
  172. }