Created
November 5, 2018 21:55
-
-
Save novakov-alexey-zz/e04b42ed251e0f1e6f11193640745924 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ShortestPath { | |
/** | |
* Function tries to find a shortest path from source vertex | |
* to all other vertices in the graph | |
* | |
* @param g EdgeWeightedDigraph to find a shortest path | |
* @param sourceV source vertex to find a shortest path from | |
* @return return either error as string when input parameters | |
* are invalid or return shortest path result | |
*/ | |
def run(g: EdgeWeightedDigraph, sourceV: Int): Either[String, ShortestPathCalc] = { | |
val size = g.adj.size | |
if (sourceV >= size) Left(s"Source vertex must in range [0, $size)") | |
else { | |
val edgeTo = mutable.ArrayBuffer.fill[Option[DirectedEdge]](size)(None) | |
val distTo = mutable.ArrayBuffer.fill(size)(Double.PositiveInfinity) | |
//init source distance and add to the queue | |
distTo(sourceV) = 0.0 | |
val sourceDist = (sourceV, distTo(sourceV)) | |
val sortByWeight: Ordering[(Int, Double)] = (a, b) => a._2.compareTo(b._2) | |
val queue = mutable.PriorityQueue[(Int, Double)](sourceDist)(sortByWeight) | |
while (queue.nonEmpty) { | |
val (minDestV, _) = queue.dequeue() | |
val edges = g.adj.getOrElse(minDestV, List.empty) | |
edges.foreach { e => | |
if (distTo(e.to) > distTo(e.from) + e.weight) { | |
distTo(e.to) = distTo(e.from) + e.weight | |
edgeTo(e.to) = Some(e) | |
if (!queue.exists(_._1 == e.to)) queue.enqueue((e.to, distTo(e.to))) | |
} | |
} | |
} | |
Right(new ShortestPathCalc(edgeTo, distTo)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment