temp commit
This commit is contained in:
parent
ab02a1e495
commit
7d045e79b6
@ -24,23 +24,15 @@ class HHCSim(
|
||||
)
|
||||
.tap(logCentroids)
|
||||
.tap(logRemovedEdges)
|
||||
.map(
|
||||
e =>
|
||||
e match {
|
||||
case (mst, centroids, removed) => {
|
||||
printGraph(mst)
|
||||
.map {
|
||||
case (mst, centroids, removed) =>
|
||||
Util.findClusters(mst, centroids, removed)
|
||||
}
|
||||
}
|
||||
)
|
||||
.tap(logClusters)
|
||||
.map(
|
||||
e =>
|
||||
e match {
|
||||
.map {
|
||||
case (centroids, clusters, removed) =>
|
||||
Util.groupClusters(centroids, clusters, removed)
|
||||
}
|
||||
)
|
||||
|
||||
def checkEmpty(
|
||||
customers: IndexedSeq[Customer]
|
||||
|
@ -6,6 +6,7 @@ import util.Util
|
||||
import config.Conf
|
||||
import java.io.File
|
||||
import scala.io.Source
|
||||
import sim.HHCSim2
|
||||
object Main {
|
||||
def main(args: Array[String]): Unit = {
|
||||
|
||||
@ -13,25 +14,32 @@ object Main {
|
||||
|
||||
val bufferedSource = Source.fromFile(conf.infile())
|
||||
|
||||
val customers = Util.getCustomers(bufferedSource)
|
||||
val customers = HHCSim2.getCustomers(bufferedSource)
|
||||
bufferedSource.close()
|
||||
|
||||
val hhc = new HHCSim(epsilonMax = 40, iterations = 10, WLDMax = 10)
|
||||
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
|
||||
}
|
||||
})
|
||||
// import Ordering.Double.IeeeOrdering
|
||||
// val hhc = new HHCSim(epsilonMax = 40, iterations = 10, WLDMax = 10)
|
||||
// val adjList2 =
|
||||
// customers
|
||||
// .map(Util.formAdjMatrix)
|
||||
// .map(e => Util.mstUsingPrims2(e))
|
||||
// .map { case (mst, eps) => Util.removeEdges(mst)(eps) }
|
||||
// // .map(_._1)
|
||||
|
||||
// // .map(e => Util.makeAdjacencyList2(e._1))
|
||||
// adjList2.map(e => {
|
||||
// val (mst, rm) = e
|
||||
// for (i <- 0 until mst.size) {
|
||||
// print(s"$i -> ")
|
||||
// mst(i).foreach(e => {
|
||||
// print(f"(${e._1}, ${e._2}%.2f), ")
|
||||
// })
|
||||
// println
|
||||
// }
|
||||
|
||||
// println(rm)
|
||||
// })
|
||||
|
||||
// val fnl2 = hhc.go(customers)
|
||||
// customers.map(println(_))
|
||||
|
||||
@ -61,6 +69,82 @@ object Main {
|
||||
// println(s"Oops, an error occured. The error message was: $e")
|
||||
// }
|
||||
|
||||
val hhc = new HHCSim2(
|
||||
epsilonMax = 40,
|
||||
iterations = 10,
|
||||
WLDMax = 10,
|
||||
customers = customers
|
||||
)
|
||||
|
||||
val x = hhc.go()
|
||||
|
||||
x match {
|
||||
case Left(value) => println(value)
|
||||
case Right(value) =>
|
||||
}
|
||||
|
||||
x.foreach(d => {
|
||||
val (a, b, c, g) = d
|
||||
println(c)
|
||||
|
||||
println
|
||||
|
||||
for (i <- 0 until b.length) {
|
||||
if (!b(i).isEmpty) {
|
||||
print(s"$i ")
|
||||
print(b(i))
|
||||
// edgeMappings
|
||||
// b(i).foreach(e => {
|
||||
// print(f"(${e.toNode}%d, ${e.weight}%.2f), ")
|
||||
// })
|
||||
println
|
||||
}
|
||||
}
|
||||
println
|
||||
|
||||
for (i <- 0 until g.length) {
|
||||
if (!g(i)._2.isEmpty) {
|
||||
print(s"$i ")
|
||||
print(g(i))
|
||||
// edgeMappings
|
||||
// b(i).foreach(e => {
|
||||
// print(f"(${e.toNode}%d, ${e.weight}%.2f), ")
|
||||
// })
|
||||
println
|
||||
}
|
||||
}
|
||||
println
|
||||
|
||||
var i = 0
|
||||
a.foreach(e => {
|
||||
if (!e.isEmpty) {
|
||||
print(s"Cluster-$i: ")
|
||||
i += 1
|
||||
e.foreach(f => { print(s"$f ") })
|
||||
println
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
val x2 = hhc.go2()
|
||||
x2.map(_.map(println))
|
||||
|
||||
// x.map(e => {
|
||||
// val (mst, rm) = e
|
||||
// val y = HHCSim2.DFS(0)(mst)
|
||||
// println(y)
|
||||
// for (i <- 0 until mst.size) {
|
||||
// print(s"$i -> ")
|
||||
// mst(i).foreach(e => {
|
||||
// print(f"(${e.toNode}, ${e.weight}%.2f), ")
|
||||
// })
|
||||
// println
|
||||
// }
|
||||
|
||||
// println(rm)
|
||||
// })
|
||||
|
||||
val coord1 = Coord(3, 4)
|
||||
println(s"Distance from origin = ${coord1.distance}")
|
||||
|
||||
|
@ -6,3 +6,5 @@ import util.Util
|
||||
case class HHCEdge(v1: Customer, v2: Customer) {
|
||||
val weight = Util.getHaversineDistance(v1.location, v2.location)
|
||||
}
|
||||
|
||||
case class HHCEdge2[T](fromNode: Int, toNode: Int, weight: T)
|
||||
|
29
src/main/scala/model/Types.scala
Normal file
29
src/main/scala/model/Types.scala
Normal file
@ -0,0 +1,29 @@
|
||||
package model
|
||||
|
||||
import scala.collection.immutable.ArraySeq
|
||||
import scala.collection.IndexedSeqView
|
||||
|
||||
trait HHCTypes {
|
||||
|
||||
/**
|
||||
* Graph in mutable adjacency matrix form
|
||||
*/
|
||||
type GraphMatrix[T] = Array[Array[T]]
|
||||
|
||||
/**
|
||||
* Graph in mutable adjacency list form
|
||||
*/
|
||||
type MutGraph[T] = Array[Array[HHCEdge2[T]]]
|
||||
|
||||
/**
|
||||
* Graph in immutable adjacency list form
|
||||
*/
|
||||
type Graph[T] = ArraySeq[List[HHCEdge2[T]]]
|
||||
|
||||
/**
|
||||
* List of removed edges
|
||||
*/
|
||||
type RemovedEdges[T] = List[HHCEdge2[T]]
|
||||
|
||||
type Clusters = ArraySeq[List[Int]]
|
||||
}
|
395
src/main/scala/sim/HHCSim2.scala
Normal file
395
src/main/scala/sim/HHCSim2.scala
Normal file
@ -0,0 +1,395 @@
|
||||
package sim
|
||||
|
||||
import model.HHCTypes
|
||||
import scala.reflect.ClassTag
|
||||
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
|
||||
import scala.collection.immutable.ArraySeq
|
||||
import model.HHCEdge2
|
||||
import util.Util
|
||||
import model.Customer
|
||||
import scala.io.BufferedSource
|
||||
import model.Coord
|
||||
import scala.util.Random
|
||||
|
||||
class HHCSim2(
|
||||
private val epsilonMax: Int = 0,
|
||||
private val iterations: Int = 0,
|
||||
private val WLDMax: Float = 0,
|
||||
private val customers: String Either ArraySeq[Customer]
|
||||
) {
|
||||
import HHCSim2._
|
||||
import Ordering.Double.IeeeOrdering
|
||||
def go() = {
|
||||
customers
|
||||
.flatMap(checkEmpty)
|
||||
.map(formAdjMatrix)
|
||||
.map(e => mstUsingPrims(e))
|
||||
.map { case (mst, epsilon) => removeEdges(mst)(epsilon) }
|
||||
.map { case (mstUpdated, removed) => findClusters(mstUpdated)(removed) }
|
||||
.map {
|
||||
case (clusters, edgeMappings, removedEdges) =>
|
||||
groupClusters(clusters, edgeMappings, removedEdges)
|
||||
}
|
||||
}
|
||||
def go2() = {
|
||||
val res = go().flatMap(value => {
|
||||
val (clusters, edgeMappings, removed, clusterGroups) = value
|
||||
workloadBalance(clusters, edgeMappings, removed, clusterGroups)
|
||||
})
|
||||
res
|
||||
}
|
||||
|
||||
def workloadBalance[N: Numeric](
|
||||
clusters: Clusters,
|
||||
edgeMappings: ArraySeq[List[HHCEdge2[N]]],
|
||||
removedEdges: RemovedEdges[N],
|
||||
groups: ArraySeq[(Int, List[(Int, N)])]
|
||||
) = {
|
||||
customers.map { c =>
|
||||
val k = clusters.size
|
||||
val mutClusters = clusters.toArray
|
||||
val worlkLoads =
|
||||
mutClusters.map(_.map(j => c(j)).foldLeft(0f)((x, y) => x + y.workload))
|
||||
val sortedClusters =
|
||||
mutClusters.map(_.sortWith((x, y) => c(x).workload < c(y).workload))
|
||||
val minWL =
|
||||
c.foldLeft(c(0).workload)(_ min _.workload)
|
||||
val maxWL =
|
||||
c.foldLeft(0f)(_ max _.workload)
|
||||
val WLD = maxWL - minWL
|
||||
if (WLD > WLDMax) {
|
||||
var t = Random.between(((k / 2) + 1), k)
|
||||
while (!mutClusters(t).isEmpty) t = Random.between(((k / 2) + 1), k)
|
||||
val Ds = groups(t)._2(0)
|
||||
mutClusters.updated(Ds._1, t)
|
||||
}
|
||||
for (_ <- 0 until iterations) {
|
||||
// val workloads = clusters.flatMap(_.map(j => c(j)))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def checkAveragePairwiseDistance[T](
|
||||
lst: List[(Int, T)]
|
||||
)(implicit num: Numeric[T]) = {
|
||||
val sum = lst.foldLeft(0)((x, y) => x + num.toInt(y._2))
|
||||
val avg = sum / lst.length
|
||||
if (avg < epsilonMax) true else false
|
||||
}
|
||||
}
|
||||
|
||||
object HHCSim2 extends HHCTypes {
|
||||
import Ordering.Implicits._
|
||||
|
||||
val composed = (formAdjMatrix _)
|
||||
.andThen(e => mstUsingPrims(e))
|
||||
.andThen { case (mst, epsilon) => removeEdges(mst)(epsilon) }
|
||||
.andThen { case (mstUpdated, removed) => findClusters(mstUpdated)(removed) }
|
||||
|
||||
def getCustomers(
|
||||
infile: BufferedSource
|
||||
): String Either ArraySeq[Customer] = {
|
||||
var customers: String Either ArraySeq[Customer] = Right(ArraySeq.empty)
|
||||
val it = infile.getLines
|
||||
@annotation.tailrec
|
||||
def loop(
|
||||
lst: ListBuffer[Customer],
|
||||
iter: Iterator[String]
|
||||
): String Either ListBuffer[Customer] = {
|
||||
if (!iter.hasNext) Right(lst)
|
||||
else {
|
||||
val line = iter.next
|
||||
val arr = line.split(",").map(_.trim)
|
||||
arr match {
|
||||
case Array(latitude, longitude, workLoad) => {
|
||||
val cust =
|
||||
Customer(
|
||||
Coord(latitude.toDouble, longitude.toDouble),
|
||||
workLoad.toFloat
|
||||
)
|
||||
loop(lst += cust, iter)
|
||||
}
|
||||
case _ => {
|
||||
if (arr.mkString.equals(" ") || arr.mkString.contains("\n"))
|
||||
Left("Error newline")
|
||||
else {
|
||||
Left(
|
||||
"Error reading customers from" +
|
||||
s" file - ${arr.mkString(", ")}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
customers = loop(ListBuffer.empty, it).map(_.to(ArraySeq))
|
||||
} catch {
|
||||
case e: NumberFormatException =>
|
||||
customers = Left(
|
||||
s"Expected number but received string ${e.getMessage()}"
|
||||
)
|
||||
case e: NullPointerException =>
|
||||
customers = Left("Input was null")
|
||||
}
|
||||
customers
|
||||
}
|
||||
|
||||
def checkEmpty(
|
||||
customers: IndexedSeq[Customer]
|
||||
): Either[String, IndexedSeq[Customer]] =
|
||||
customers.length match {
|
||||
case 0 => Left("Error input was empty")
|
||||
case _ => Right(customers)
|
||||
}
|
||||
|
||||
def formAdjMatrix(customers: IndexedSeq[Customer]): GraphMatrix[Double] = {
|
||||
val n = customers.length
|
||||
val edges: Array[Array[Double]] = Array.ofDim(n, n)
|
||||
for (i <- 0 until n) {
|
||||
for (j <- i until n) {
|
||||
val weight =
|
||||
Util.getHaversineDistance(
|
||||
customers(i).location,
|
||||
customers(j).location
|
||||
)
|
||||
edges(i)(j) = weight
|
||||
edges(j)(i) = weight
|
||||
}
|
||||
}
|
||||
edges
|
||||
}
|
||||
|
||||
def mstUsingPrims[T: Numeric](
|
||||
edges: GraphMatrix[T]
|
||||
): (Graph[T], T) = {
|
||||
val num = implicitly[Numeric[T]]
|
||||
val n = edges.length
|
||||
val selected: Array[Boolean] = Array.fill(n)(false)
|
||||
|
||||
selected(0) = true
|
||||
|
||||
val adjList =
|
||||
Array.fill(n)(ListBuffer.empty[HHCEdge2[T]])
|
||||
|
||||
var sum = 0
|
||||
var count = 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 (min > num.toInt(edges(i)(j))) {
|
||||
min = num.toInt(edges(i)(j))
|
||||
x = i
|
||||
y = j
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sum += num.toInt(edges(x)(y))
|
||||
adjList(x) += HHCEdge2(x, y, edges(x)(y))
|
||||
adjList(y) += HHCEdge2(y, x, edges(x)(y))
|
||||
selected(y) = true
|
||||
}
|
||||
val adjList2 = adjList.map(l => {
|
||||
count += 1
|
||||
l.toList
|
||||
})
|
||||
adjList2.foreach(println)
|
||||
(ArraySeq.unsafeWrapArray(adjList2), num.fromInt(sum / count))
|
||||
}
|
||||
|
||||
def removeEdges[N: Ordering](
|
||||
mst: Graph[N]
|
||||
)(epsilon: N): (Graph[N], RemovedEdges[N]) = {
|
||||
|
||||
val removed = ListBuffer.empty[HHCEdge2[N]]
|
||||
|
||||
val result = ArraySeq.tabulate(mst.length) { i =>
|
||||
val (filtered, rm) = mst(i)
|
||||
// .view
|
||||
// .filter(e => (e.fromNode <= e.toNode))
|
||||
.partition(_.weight <= epsilon)
|
||||
|
||||
// val rm2 = rm.filter(e => (e.fromNode <= e.toNode))
|
||||
|
||||
removed ++= rm
|
||||
|
||||
filtered
|
||||
}
|
||||
println
|
||||
result.foreach(println)
|
||||
println
|
||||
(result, removed.toList)
|
||||
}
|
||||
|
||||
def DFS[T: Numeric](start: Int)(graph: Graph[T]) = {
|
||||
val visited = Array.fill(graph.size)(false)
|
||||
val buf = ListBuffer[Int]()
|
||||
def loop(
|
||||
start: Int,
|
||||
graph: Graph[T],
|
||||
visited: Array[Boolean]
|
||||
): Unit = {
|
||||
visited(start) = true
|
||||
buf += start
|
||||
// val iter = graph(start).iterator
|
||||
// while (iter.hasNext) {
|
||||
// val edge = iter.next
|
||||
// if (!visited(edge.toNode))
|
||||
// loop(edge.toNode, graph, visited)
|
||||
// }
|
||||
for (edge <- graph(start)) {
|
||||
if (!visited(edge.toNode))
|
||||
loop(edge.toNode, graph, visited)
|
||||
}
|
||||
}
|
||||
|
||||
loop(start, graph, visited)
|
||||
buf.toList
|
||||
}
|
||||
|
||||
def findClusters[T: Numeric](mstUpdated: Graph[T])(
|
||||
removedEdges: RemovedEdges[T]
|
||||
): (Clusters, ArraySeq[List[HHCEdge2[T]]], RemovedEdges[T]) = {
|
||||
val visited = Array.fill[Boolean](mstUpdated.length)(false)
|
||||
var removedEdges2 = removedEdges
|
||||
val egdeMappings =
|
||||
Array.fill(mstUpdated.length)(List.empty[HHCEdge2[T]])
|
||||
val result = ArraySeq.tabulate(mstUpdated.length) { i =>
|
||||
{
|
||||
val buf = ListBuffer[Int]()
|
||||
// mstUpdated(i).isEmpty match {
|
||||
// case true => { lst += i }
|
||||
// case false => {
|
||||
// if (!visited(i)) {
|
||||
// lst ++= DFS(i)(mstUpdated)
|
||||
// for (j <- lst) visited(j) = true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
visited(i) match {
|
||||
case true => {
|
||||
// val (nds, rms) = assignEdges(List(i), removedEdges2)
|
||||
// egdeMappings(i) = nds
|
||||
// removedEdges2 = rms
|
||||
}
|
||||
case false if (!mstUpdated(i).isEmpty) => {
|
||||
val nodes = DFS(i)(mstUpdated)
|
||||
buf ++= nodes
|
||||
val (nds, rms) = assignEdges(nodes, removedEdges2)
|
||||
removedEdges2 = rms
|
||||
egdeMappings(i) = nds
|
||||
for (j <- nodes) visited(j) = true
|
||||
}
|
||||
case false => {
|
||||
buf += i
|
||||
val (nds, rms) = assignEdges(List(i), removedEdges2)
|
||||
egdeMappings(i) = nds
|
||||
removedEdges2 = rms
|
||||
}
|
||||
}
|
||||
buf.toList
|
||||
}
|
||||
}
|
||||
|
||||
// println(s"Removed edges size: ${removedEdges2.size}")
|
||||
|
||||
// result
|
||||
(result, ArraySeq.unsafeWrapArray(egdeMappings), removedEdges)
|
||||
// (result.filterNot(_.isEmpty), ArraySeq.unsafeWrapArray(egdeMappings), removedEdges)
|
||||
}
|
||||
|
||||
def assignEdges[T: Ordering](
|
||||
nodes: List[Int],
|
||||
removedEdges: RemovedEdges[T]
|
||||
) = {
|
||||
val it = nodes.iterator
|
||||
def loop(
|
||||
nodes: List[Int],
|
||||
removedEdges: RemovedEdges[T],
|
||||
iter: Iterator[Int],
|
||||
edges: List[HHCEdge2[T]]
|
||||
): (List[HHCEdge2[T]], RemovedEdges[T]) = {
|
||||
if (!iter.hasNext) (edges, removedEdges)
|
||||
else if (!edges.isEmpty) (edges, removedEdges)
|
||||
else {
|
||||
val node = iter.next
|
||||
val (filt, rm) =
|
||||
removedEdges.partition(e => e.fromNode == node)
|
||||
// removedEdges.partition(e => e.toNode == node || e.fromNode == node)
|
||||
loop(nodes, rm, iter, filt)
|
||||
}
|
||||
}
|
||||
// val filtered = ListBuffer.empty[HHCEdge2[T]]
|
||||
// val updated = ListBuffer.empty[HHCEdge2[T]]
|
||||
// for (node <- nodes) {
|
||||
// val (filt, rm) =
|
||||
// removedEdges.partition(e => e.toNode == node || e.fromNode == node)
|
||||
// if (!filtered.isEmpty) {
|
||||
// // return (filt.toList, rm.toList)
|
||||
// } else {
|
||||
// filtered ++= filt
|
||||
// updated ++= rm
|
||||
// }
|
||||
// }
|
||||
|
||||
// print(filtered)
|
||||
// (filtered.toList, updated.toList)
|
||||
val (edges, removedEdgesUpdated) =
|
||||
loop(nodes, removedEdges, it, List.empty[HHCEdge2[T]])
|
||||
// val edges2 = edges.sortWith {
|
||||
// case (HHCEdge2(_, _, weight1), HHCEdge2(_, _, weight2)) =>
|
||||
// weight1 < weight2
|
||||
// }
|
||||
(edges, removedEdgesUpdated)
|
||||
}
|
||||
|
||||
def groupClusters[N: Ordering](
|
||||
clusters: Clusters,
|
||||
edgeMappings: ArraySeq[List[HHCEdge2[N]]],
|
||||
removed: RemovedEdges[N]
|
||||
) = {
|
||||
var k = -1
|
||||
val x = ArraySeq.tabulate(edgeMappings.size)(i => {
|
||||
val buf = ListBuffer.empty[(Int, N)]
|
||||
val lst = edgeMappings(i)
|
||||
val y = lst.foreach(e => {
|
||||
if (edgeMappings(e.toNode).isEmpty) {
|
||||
// var buf = ListBuffer.empty[(Int, N)]
|
||||
for (j <- 0 until clusters.size) {
|
||||
for (edge <- clusters(j)) {
|
||||
if (edge == e.toNode)
|
||||
buf += ((j, e.weight))
|
||||
}
|
||||
}
|
||||
// Left(buf.toList)
|
||||
} else {
|
||||
buf += ((e.toNode, e.weight))
|
||||
}
|
||||
// Right(lst.map {
|
||||
// case HHCEdge2(fromNode, toNode, weight) => (toNode, weight)
|
||||
// })
|
||||
})
|
||||
if (!clusters(i).isEmpty) k += 1
|
||||
// val lst2 = lst.map {
|
||||
// case HHCEdge2(fromNode, toNode, weight) => (toNode, weight)
|
||||
// }
|
||||
// if (buf.isEmpty) lst2 else buf.toList ::: lst2
|
||||
// if (lt.isEmpty) rt else lt
|
||||
(k, buf.toList.sortWith {
|
||||
case ((_, weight1), (_, weight2)) =>
|
||||
weight1 < weight2
|
||||
})
|
||||
})
|
||||
(clusters, edgeMappings, removed, x)
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ import com.typesafe.scalalogging.LazyLogging
|
||||
import scala.collection.immutable.ArraySeq
|
||||
|
||||
object Util extends LazyLogging {
|
||||
type Graph[T] = IndexedSeq[Seq[(Int, T)]]
|
||||
import Ordering.Implicits._
|
||||
private val r = 6471.00 // km
|
||||
|
||||
def toRad(num: Double): Double = {
|
||||
@ -253,6 +255,117 @@ object Util extends LazyLogging {
|
||||
(mst, centroids.toIndexedSeq, removed.toIndexedSeq)
|
||||
}
|
||||
|
||||
// def removeEdges[T](mst: IndexedSeq[Seq[(Int, T)]], epsilon: T)(
|
||||
// implicit num: Numeric[T]
|
||||
// ): (IndexedSeq[Seq[(Int, T)]], IndexedSeq[(Int, Int, T)]) = {
|
||||
// // val mutMST = mst.to(Array)
|
||||
// // val n = mst.length
|
||||
// // val removed: mutable.ListBuffer[(Int, Int, T)] = mutable.ListBuffer.empty
|
||||
// val it = mst.iterator
|
||||
|
||||
// @annotation.tailrec
|
||||
// def loop(
|
||||
// mst: IndexedSeq[Seq[(Int, T)]],
|
||||
// removed: Seq[(Int, Int, T)],
|
||||
// epsilon: T,
|
||||
// iter: Iterator[Seq[(Int, T)]],
|
||||
// index: Int
|
||||
// )(
|
||||
// implicit num: Numeric[T]
|
||||
// ): (IndexedSeq[Seq[(Int, T)]], Seq[(Int, Int, T)]) = {
|
||||
// if (!iter.hasNext) {
|
||||
// return (mst, removed)
|
||||
// }
|
||||
// val lst = iter.next
|
||||
// // val filtered = lst.filter(e => {
|
||||
// // val (node, weight) = e
|
||||
// // num.lt(weight, epsilon)
|
||||
// // })
|
||||
// // val rm = lst
|
||||
// // .filter(e => {
|
||||
// // val (node, weight) = e
|
||||
// // num.gt(weight, epsilon)
|
||||
// // })
|
||||
// // .map(e => {
|
||||
// // val (node, weight) = e
|
||||
// // (index, node, weight)
|
||||
// // })
|
||||
|
||||
// val (filtered, rm) = lst.partition(e => {
|
||||
// val (node, weight) = e
|
||||
// num.lt(weight, epsilon)
|
||||
// })
|
||||
// val rm2 = rm.map(e => {
|
||||
// val (node, weight) = e
|
||||
// (index, node, weight)
|
||||
// })
|
||||
// loop(
|
||||
// mst.updated(index, filtered),
|
||||
// removed ++ rm2,
|
||||
// epsilon,
|
||||
// iter,
|
||||
// index + 1
|
||||
// )
|
||||
// }
|
||||
// // for (i <- 0 until n) {
|
||||
// // // for (j <- 0 until n) {
|
||||
// // // val weight = mutMST(i)(j)._2
|
||||
// // // if (num.gt(weight, epsilon) && weight != 0) {
|
||||
// // // removed += ((i, j, weight))
|
||||
// // // mutMST(i).remove(j)
|
||||
// // // }
|
||||
// // // }
|
||||
|
||||
// // // var j = 0;
|
||||
// // // for ((node, weight) <- mutMST(i)) {
|
||||
// // // if (num.gt(weight, epsilon) && weight != 0) {
|
||||
// // // removed += ((i, j, weight))
|
||||
// // // mutMST(i).remove(j)
|
||||
// // // }
|
||||
// // // j += 1
|
||||
// // // }
|
||||
|
||||
// // mutMST(i) = mutMST(i).filter(e => {
|
||||
// // val (node, weight) = e
|
||||
// // removed += ((i, node, weight))
|
||||
// // num.lt(weight, epsilon)
|
||||
// // })
|
||||
// // }
|
||||
|
||||
// // val updated = ArraySeq.unsafeWrapArray(mutMST.map(e => e.toList))
|
||||
// // val updated = ArraySeq.unsafeWrapArray(mutMST)
|
||||
|
||||
// val (updated, removed) =
|
||||
// loop(mst, Seq[(Int, Int, T)](), epsilon, it, 0)
|
||||
|
||||
// (updated, removed.toIndexedSeq)
|
||||
// }
|
||||
|
||||
def removeEdges[N: Ordering](
|
||||
mst: Graph[N]
|
||||
)(epsilon: N): (Graph[N], List[(Int, Int, N)]) = {
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
val removed = ListBuffer.empty[(Int, Int, N)]
|
||||
|
||||
val result = ArraySeq.tabulate(mst.length) { i =>
|
||||
val (filtered, rm) = mst(i).partitionMap {
|
||||
case (node, weight) =>
|
||||
if (weight <= epsilon)
|
||||
Left((node, weight))
|
||||
else
|
||||
Right((i, node, weight))
|
||||
}
|
||||
|
||||
removed ++= rm
|
||||
|
||||
filtered
|
||||
}
|
||||
|
||||
(result, removed.toList)
|
||||
}
|
||||
|
||||
def DFS[T](
|
||||
start: Int,
|
||||
graph: Array[Array[T]]
|
||||
@ -341,8 +454,7 @@ object Util extends LazyLogging {
|
||||
lst: IndexedSeq[Customer],
|
||||
iter: Iterator[String]
|
||||
): String Either IndexedSeq[Customer] = {
|
||||
if (!iter.hasNext)
|
||||
return Right(lst)
|
||||
if (!iter.hasNext) return Right(lst)
|
||||
val line = iter.next
|
||||
val arr = line.split(",").map(_.trim)
|
||||
arr match {
|
||||
|
Loading…
Reference in New Issue
Block a user