diff --git a/build.sbt b/build.sbt index 1094105..c7ee72b 100644 --- a/build.sbt +++ b/build.sbt @@ -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", diff --git a/src/main/scala/HHCSim.scala b/src/main/scala/HHCSim.scala index 849724a..62fba0b 100644 --- a/src/main/scala/HHCSim.scala +++ b/src/main/scala/HHCSim.scala @@ -27,8 +27,10 @@ class HHCSim( .map( e => e match { - case (mst, centroids, removed) => + case (mst, centroids, removed) => { + printGraph(mst) Util.findClusters(mst, centroids, removed) + } } ) .tap(logClusters) diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala index d716308..7b5835f 100644 --- a/src/main/scala/Main.scala +++ b/src/main/scala/Main.scala @@ -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) => diff --git a/src/main/scala/util/Util.scala b/src/main/scala/util/Util.scala index e23e0fe..486689f 100644 --- a/src/main/scala/util/Util.scala +++ b/src/main/scala/util/Util.scala @@ -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 }