1
+ import scala .collection .mutable
2
+
3
+ object Main extends App {
4
+
5
+ val graphs = new SimpleGraph [String ](
6
+ Map (
7
+ " A" -> Map (" B" -> 7 , " C" -> 8 ),
8
+ " B" -> Map (" A" -> 7 , " F" -> 2 ),
9
+ " C" -> Map (" A" -> 8 , " G" -> 4 , " F" -> 6 ),
10
+ " D" -> Map (" F" -> 8 ),
11
+ " E" -> Map (" H" -> 1 ),
12
+ " F" -> Map (" B" -> 2 , " C" -> 6 , " D" -> 8 , " G" -> 9 , " H" -> 1 ),
13
+ " G" -> Map (" C" -> 4 , " F" -> 9 ),
14
+ " H" -> Map (" E" -> 1 , " F" -> 3 )
15
+ )
16
+ )
17
+ graphs.getShortestPath(" A" ," E" )
18
+
19
+ }
20
+
21
+ case class SimpleGraph [N ](succs : Map [N , Map [N , Int ]]) {
22
+
23
+ def apply (n : N ) = succs.getOrElse(n, Map .empty)
24
+
25
+ def initDistance (point: N ) = {
26
+ this .succs.foldLeft(Map .empty: Map [N , (Int , Seq [N ])]) {
27
+ (result, vertex) =>
28
+ if (vertex._1 == point) {
29
+ result ++ Map (point -> (0 ,Seq (point)))
30
+ } else {
31
+ result ++ Map (vertex._1 -> (Int .MaxValue , Seq (point)))
32
+ }
33
+ }
34
+ }
35
+
36
+ def shortestPath (n: N )(selected: Set [N ])(currentDistance: Map [N , (Int , Seq [N ])]) = {
37
+ currentDistance.keys.filterNot(selected.contains(_)).foldLeft(n: N ) {
38
+ (result, point) =>
39
+ currentDistance(point)._1 match {
40
+ case x if result == n => point
41
+ case y if (currentDistance(result)._1 > y) => point
42
+ case _ => result
43
+ }
44
+ }
45
+ }
46
+
47
+ def updateGraph (n: N )(f: N )(distance: Map [N , (Int , Seq [N ])]): Map [N , (Int , Seq [N ])] = {
48
+ val hereDistance = distance(f)
49
+ this .succs(f).foldLeft(distance: Map [N , (Int , Seq [N ])]) {
50
+ (result, vertex) =>
51
+ val nodeDistance = hereDistance._1 match {
52
+ case Int .MaxValue => vertex._2
53
+ case _ => hereDistance._1 + vertex._2
54
+ }
55
+ if (distance(vertex._1)._1 > nodeDistance) {
56
+ result ++ Map (vertex._1 -> (nodeDistance, hereDistance._2 :+ vertex._1))
57
+ } else {
58
+ result
59
+ }
60
+ }
61
+ }
62
+
63
+ def getShortestPath (start : N , finish : N ) = {
64
+ var nextNode : N = start;
65
+ var currentDistance : Map [N , (Int , Seq [N ])] = initDistance(start);
66
+ var unreachedVertexSet : Set [N ] = succs.keySet.filterNot(_ == start)
67
+ while (! unreachedVertexSet.isEmpty) {
68
+ currentDistance = updateGraph(start)(nextNode)(currentDistance)
69
+ nextNode = shortestPath(start)(succs.keySet.filterNot(unreachedVertexSet.contains(_)))(currentDistance)
70
+ unreachedVertexSet = unreachedVertexSet.- (nextNode)
71
+ }
72
+ println(currentDistance(finish)._2.reverse.toSeq)
73
+ }
74
+
75
+ }
0 commit comments