diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala index 06d0bb2..4310162 100644 --- a/src/main/scala/Main.scala +++ b/src/main/scala/Main.scala @@ -50,24 +50,23 @@ object Main { Array(0 , 42, 66, 31, 0) ); - //format: on + // format: on // Prim's algorithm val selected: ArrayBuffer[Boolean] = - ArrayBuffer.from(Array.ofDim[Boolean](5).toIndexedSeq) + ArrayBuffer.fill(5)(false) selected(0) = true - var numberOfEdges = 0 - for (_ <- numberOfEdges to 3) { + for (_ <- 0 until 4) { var min = 999999 var x = 0 var y = 0 - for (i <- 0 to 4) { + for (i <- 0 until 5) { if (selected(i) == true) { - for (j <- 0 to 4) { + for (j <- 0 until 5) { if (selected(j) == false && edges(i)(j) != 0) { if (min > edges(i)(j)) { min = edges(i)(j) @@ -100,15 +99,19 @@ object Main { } } - println(edges2) // prints adjacency matrix + edges2.foreach { e => + e.foreach { d => + print(f"$d%.2f, ") + } + println() + } - // ArrayBuffer( - // ArrayBuffer(0.0 , 1.4142135623730951, 1.0 , 5.0 , 2.0), - // ArrayBuffer(1.4142135623730951, 0.0 , 1.0 , 5.0 , 3.1622776601683795), - // ArrayBuffer(1.0 , 1.0 , 0.0 , 4.242640687119285, 2.23606797749979), - // ArrayBuffer(5.0 , 5.0 , 4.242640687119285, 0.0 , 4.123105625617661), - // ArrayBuffer(2.0 , 3.1622776601683795, 2.23606797749979 , 4.123105625617661, 0.0), - // ) + // 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 } } diff --git a/src/main/scala/model/Coord.scala b/src/main/scala/model/Coord.scala index 8a0981f..5754ab8 100644 --- a/src/main/scala/model/Coord.scala +++ b/src/main/scala/model/Coord.scala @@ -1,5 +1,7 @@ package model -case class Coord(latitude: Long, longitude: Long) { - lazy val distance = math.sqrt(math.pow(latitude, 2) + math.pow(longitude, 2)) // distance is automatically calculated +import util.Util + +case class Coord(latitude: Double, longitude: Double) { + lazy val distance = Util.getHaversineDistance(latitude, longitude) // distance is automatically calculated } diff --git a/src/main/scala/model/Customer.scala b/src/main/scala/model/Customer.scala index 7b7208c..c4a4289 100644 --- a/src/main/scala/model/Customer.scala +++ b/src/main/scala/model/Customer.scala @@ -1,3 +1,3 @@ package model -case class Customer(location: Coord, workload: Int) \ No newline at end of file +case class Customer(location: Coord, workload: Float) \ No newline at end of file diff --git a/src/main/scala/model/HHCEdge.scala b/src/main/scala/model/HHCEdge.scala index 4299b6a..dfc8141 100644 --- a/src/main/scala/model/HHCEdge.scala +++ b/src/main/scala/model/HHCEdge.scala @@ -1,10 +1,8 @@ package model import scala.math.{sqrt, pow} +import util.Util case class HHCEdge(v1: Customer, v2: Customer) { - val weight = sqrt( //automatically compute the distance between customers - pow(v1.location.latitude - v2.location.latitude, 2) + - pow(v1.location.longitude - v2.location.longitude, 2) - ) + val weight = Util.getHaversineDistance(v1.location, v2.location) } diff --git a/src/main/scala/util/Util.scala b/src/main/scala/util/Util.scala new file mode 100644 index 0000000..63e7eb7 --- /dev/null +++ b/src/main/scala/util/Util.scala @@ -0,0 +1,47 @@ +package util + +import model.Coord +import scala.math._ + +object Util { + private val r = 6471.00 // km + + def toRad(num: Double): Double = { + val a = num * Pi / 180 + a + } + + def getHaversineDistance(c1: Coord, c2: Coord): Double = { + val x1 = c1.latitude - c2.latitude + val x2 = c1.longitude - c2.longitude + + val dlat = toRad(x1) + val dlon = toRad(x2) + + val a = pow(sin(dlat / 2), 2) + + cos(toRad(c1.latitude)) * + cos(toRad((c2.latitude))) * + pow(sin(dlon / 2), 2) + + val c = 2 * atan2(sqrt(a), sqrt(1 - a)) + val d = r * c + d + } + + def getHaversineDistance(lat: Double, lon: Double): Double = { + val x1 = lat + val x2 = lon + + val dlat = toRad(x1) + val dlon = toRad(x2) + + val a = pow(sin(dlat / 2), 2) + + cos(toRad(x1)) * + cos(toRad((0))) * + pow(sin(dlon / 2), 2) + + val c = 2 * atan2(sqrt(a), sqrt(1 - a)) + val d = r * c + d + } +}