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