Prim's algo produces adj list

This commit is contained in:
Rohan Sircar 2020-04-15 17:15:36 +05:30
parent fda1352963
commit ab02a1e495
4 changed files with 96 additions and 14 deletions

View File

@ -7,6 +7,8 @@ resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots")
)
scalacOptions ++= Seq("-deprecation", "-feature")
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-core" % "2.0.0",
"com.softwaremill.quicklens" %% "quicklens" % "1.4.12",

View File

@ -27,9 +27,11 @@ class HHCSim(
.map(
e =>
e match {
case (mst, centroids, removed) =>
case (mst, centroids, removed) => {
printGraph(mst)
Util.findClusters(mst, centroids, removed)
}
}
)
.tap(logClusters)
.map(

View File

@ -17,24 +17,39 @@ object Main {
bufferedSource.close()
val hhc = new HHCSim(epsilonMax = 40, iterations = 10, WLDMax = 10)
val fnl2 = hhc.go(customers)
val adjList2 =
customers
.map(Util.formAdjMatrix)
.map(e => Util.mstUsingPrims2(e))
.map(_._1)
// .map(e => Util.makeAdjacencyList2(e._1))
adjList2.map(adjl => {
for (i <- 0 until adjl.size) {
print(s"$i -> ")
adjl(i).foreach(e => {
print(f"(${e._1}, ${e._2}%.2f), ")
})
println
}
})
// val fnl2 = hhc.go(customers)
// customers.map(println(_))
// val edges3 = customers.map(Util.formAdjMatrix)
// val fnl2 = go(customers)
fnl2 match {
case Left(value) => println(value)
case Right(groups) =>
groups.foreach(c => {
print(s"${c._1} -> ")
c._2.foreach(e => {
print(f"(${e._1}%d, ${e._2}%.2f), ")
})
println
})
}
// fnl2 match {
// case Left(value) => println(value)
// case Right(groups) =>
// groups.foreach(c => {
// print(s"${c._1} -> ")
// c._2.foreach(e => {
// print(f"(${e._1}%d, ${e._2}%.2f), ")
// })
// println
// })
// }
// edges3 match {
// case Right(e) =>

View File

@ -9,6 +9,7 @@ import scala.io.BufferedSource
import scala.reflect.ClassTag
import com.typesafe.scalalogging.Logger
import com.typesafe.scalalogging.LazyLogging
import scala.collection.immutable.ArraySeq
object Util extends LazyLogging {
private val r = 6471.00 // km
@ -129,6 +130,46 @@ object Util extends LazyLogging {
(mst, num.fromInt(sum / n))
}
def mstUsingPrims2[T: ClassTag](
edges: Array[Array[T]]
)(implicit num: Numeric[T]): (IndexedSeq[Seq[(Int, T)]], T) = {
val n = edges.length
val selected: ArrayBuffer[Boolean] = ArrayBuffer.fill(n)(false)
selected(0) = true
val adjList: Array[mutable.ListBuffer[(Int, T)]] =
Array.fill(n)(mutable.ListBuffer())
var sum = 0
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 (num.gt(num.fromInt(min), edges(i)(j))) {
min = num.toInt(edges(i)(j))
x = i
y = j
}
}
}
}
}
sum += num.toInt(edges(x)(y))
adjList(x) += ((y, edges(x)(y)))
adjList(y) += ((x, edges(x)(y)))
selected(y) = true
}
// val map = list.foldLeft(Map[String, Int]()) { (m, s) => m(s) = s.length }
val adjList2 = adjList.map(_.toList)
(ArraySeq.unsafeWrapArray(adjList2), num.fromInt(sum / n))
}
def findClusters[T](
mst: Array[Array[T]],
centroids: IndexedSeq[Int],
@ -167,6 +208,27 @@ object Util extends LazyLogging {
buf
}
def makeAdjacencyList2(
mst: Array[Array[Double]]
): ArrayBuffer[ArrayBuffer[(Int, Double)]] = {
val n = mst.length
// val selected: ArrayBuffer[Boolean] = ArrayBuffer.fill(n)(false)
val buf: ArrayBuffer[ArrayBuffer[(Int, Double)]] =
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, mst(i)(j)))
}
}
}
buf
}
def findCentroids[T](
mst: Array[Array[T]],
epsilon: T
@ -181,7 +243,8 @@ object Util extends LazyLogging {
if (ev.gt(mst(i)(j), epsilon) && mst(i)(j) != 0) {
// println(s" $i $j = ${mst(i)(j)}")
centroids += i
centroids += j
// centroids += j
// if (j < n / 2)
removed.append((i, j, mst(i)(j)))
mst(i)(j) = ev.zero
}