Skip to content

Instantly share code, notes, and snippets.

@novakov-alexey-zz
Created November 5, 2018 21:55
Show Gist options
  • Save novakov-alexey-zz/e04b42ed251e0f1e6f11193640745924 to your computer and use it in GitHub Desktop.
Save novakov-alexey-zz/e04b42ed251e0f1e6f11193640745924 to your computer and use it in GitHub Desktop.
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