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.

268 lines
6.2 KiB

package util
import model.Coord
import scala.math._
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable
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
}
def primTraverse(
arr1: Array[Array[Int]],
comp: Int,
cond: (Int, Int) => Boolean,
cb: (Int, Int, Array[Array[Int]], Array[Array[Int]]) => Array[Array[Int]]
): Unit = {
val n = arr1.length
val selected = Array.ofDim[Boolean](n)
val arr2: Array[Array[Int]] = Array.ofDim(n, n)
selected(0) = true
// val mst: Array[Array[Int]] = Array.ofDim(5, 5)
for (_ <- 0 until n - 1) {
// var min = 999999
var x = 0
var y = 0
for (i <- 0 until n) {
if (selected(i) == true) {
for (j <- 0 until n) {
if (selected(j) == false && arr1(i)(j) != 0) {
if (cond(comp, arr1(i)(j))) {
x = i
y = j
cb(x, y, arr1, arr2)
}
}
}
}
}
// mst(x)(y) = mst(x)(y)
selected(y) = true
}
}
def mstUsingPrims(
edges: Array[Array[Int]]
): Array[Array[Int]] = {
val n = edges.length
val selected: ArrayBuffer[Boolean] = ArrayBuffer.fill(n)(false)
selected(0) = true
val mst: Array[Array[Int]] = Array.ofDim(n, n)
for (_ <- 0 until n - 1) {
var min = 999999
var x = 0
var y = 0
for (i <- 0 until n) {
if (selected(i) == true) {
for (j <- 0 until n) {
if (selected(j) == false && edges(i)(j) != 0) {
if (min > edges(i)(j)) {
min = edges(i)(j)
x = i
y = j
}
}
}
}
}
// println(s"Edge selected $x - $y : ${edges(x)(y)}")
mst(x)(y) = edges(x)(y)
mst(y)(x) = edges(x)(y)
selected(y) = true
}
mst
}
def findClusters(
mst: Array[Array[Int]],
centroids: IndexedSeq[Int]
): Map[Int, ArrayBuffer[Int]] = {
val n = mst.length
val x: Map[Int, ArrayBuffer[Int]] = centroids
.map(d => {
val y = DFS(d, mst)
y(0) -> y
})
.toMap
x
}
def makeAdjacencyList(
mst: Array[Array[Int]],
centroids: IndexedSeq[Int]
): ArrayBuffer[ArrayBuffer[Int]] = {
val n = mst.length
// val selected: ArrayBuffer[Boolean] = ArrayBuffer.fill(n)(false)
val buf: ArrayBuffer[ArrayBuffer[Int]] =
ArrayBuffer.fill(n)(ArrayBuffer.empty)
// for (_ <- 0 until n -1) {
// }
for (i <- 0 until n) {
for (j <- 0 until n) {
if (mst(i)(j) != 0) {
// println(s" $i $j = ${mst(i)(j)}")
buf(i) += j
}
}
}
buf
}
def findCentroids[T](
mst: Array[Array[T]]
)(implicit ev: Numeric[T]): (IndexedSeq[Int], IndexedSeq[(Int, Int, T)]) = {
val n = mst.length
val centroids: mutable.Set[Int] = mutable.Set.empty
val removed: ArrayBuffer[(Int, Int, T)] = ArrayBuffer.empty
for (i <- 0 until n) {
for (j <- 0 until n) {
if (ev.gt(mst(i)(j), ev.fromInt(20)) && mst(i)(j) != 0) {
// println(s" $i $j = ${mst(i)(j)}")
centroids += i
centroids += j
removed.append((i, j, mst(i)(j)))
mst(i)(j) = ev.zero
}
}
}
(centroids.toIndexedSeq, removed.toIndexedSeq)
}
// def DFS(start: Int, graph: Array[Array[Int]], visited: Array[Boolean]): Unit = {
// // if(start == 0) {
// // visited = Array.fill(graph.size)(false)
// // }
// visited(start) = true
// println(s"$start ")
// for(i <- 0 until graph.size) {
// if (graph(start)(i) > 0 && graph(start)(i) < 20 && (!visited(i))) {
// DFS(i, graph, visited);
// }
// }
// }
// val visited = Array.fill(mst.size)(false)
def DFS(
start: Int,
graph: Array[Array[Int]]
): ArrayBuffer[Int] = {
val visited = Array.fill(graph.size)(false)
val buf = ArrayBuffer[Int]()
def loop(start: Int, graph: Array[Array[Int]], visited: Array[Boolean]) {
visited(start) = true
buf += start
// print(s"$start ")
for (i <- 0 until graph.size) {
if (graph(start)(i) > 0 && (!visited(i))) {
loop(i, graph, visited);
}
}
}
loop(start, graph, visited)
// println()
buf
}
def DFS(
start: Int,
graph: Array[Array[Int]],
num: Int,
cond: (Int, Int) => Boolean
): ArrayBuffer[Int] = {
val visited = Array.fill(graph.size)(false)
val buf = ArrayBuffer[Int]()
def loop(start: Int, graph: Array[Array[Int]], visited: Array[Boolean]) {
visited(start) = true
buf += start
// print(s"$start ")
for (i <- 0 until graph.size) {
if (graph(start)(i) > 0 && cond(graph(start)(i), num) && (!visited(i))) {
loop(i, graph, visited);
}
}
}
loop(start, graph, visited)
// println()
buf
}
def groupClusters(
centroids: IndexedSeq[Int],
clusters: Map[Int, ArrayBuffer[Int]],
removed: IndexedSeq[(Int, Int, Int)]
) = {
val groups = centroids
.map(c => {
val cluster = clusters(c)
val lst = removed
.filter(r => {
c == r._1
})
.sortWith((x, y) => {
x._3 < y._3
})
.map(l => {
(l._2,l._3)
})
c -> lst
})
.toMap
groups
}
}