Browse Source

Haversine distance and some changes

Change workload to float and coordinated to Double
master
Rohan Sircar 4 years ago
parent
commit
a6a366b62c
  1. 31
      src/main/scala/Main.scala
  2. 6
      src/main/scala/model/Coord.scala
  3. 2
      src/main/scala/model/Customer.scala
  4. 6
      src/main/scala/model/HHCEdge.scala
  5. 47
      src/main/scala/util/Util.scala

31
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
}
}

6
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
}

2
src/main/scala/model/Customer.scala

@ -1,3 +1,3 @@
package model
case class Customer(location: Coord, workload: Int)
case class Customer(location: Coord, workload: Float)

6
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)
}

47
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
}
}
Loading…
Cancel
Save