public List <Path> Dijkstra(IVertex source) { var paths = new Dictionary <IVertex, PathBuilder>(); var flags = new Dictionary <IVertex, bool>(); var vertices = new List <IVertex>(Vertices); foreach (var v in vertices) { paths[v] = new PathBuilder(v, null, v == source ? 0 : int.MaxValue); flags[v] = false; } var unreachable = new Vertex(-1); while (true) { var least = new PathBuilder(unreachable, null, int.MaxValue); foreach (var v in vertices) { if (!flags[v] && paths[v].Weight < least.Weight) { least = paths[v]; } } if (least.Source == unreachable) { break; } var src = least.Source; flags[src] = true; foreach (var dst in src.Neighbors.Select(Vertex)) { var weight = EdgeWeight(src, dst); if (weight <= 0 || flags[dst]) { continue; } var oldPath = paths[dst]; var newWeight = weight + least.Weight; if (newWeight < oldPath.Weight) { paths[oldPath.Source] = new PathBuilder(oldPath.Source, least, newWeight); } } } var pathsFound = new List <PathBuilder>(paths.Values); var result = pathsFound.Select(p => p.Build(this).Reverse()).OrderBy(p => p.First.Id).ToList(); return(result); }
public PathBuilder Reverse() { var currentNode = new PathBuilder(Source, null, 0); var currentWeight = Weight; var iterator = Next; while (iterator != null) { currentNode = new PathBuilder(iterator.Source, currentNode, currentWeight - iterator.Weight); iterator = iterator.Next; } return(currentNode); }
public PathBuilder(IVertex source, PathBuilder next, int weight) { Source = source; Next = next; Weight = weight; }