/// <summary> /// Dijkstra algorithm (shortest path) based on graph g for start vertice s. Positive cycles are allowed in shortest path algorithm /// </summary> /// <param name="g">Graph for search</param> /// <param name="s">Start vertice</param> public static PathStats ShortestPath(GraphBase g, int s) { var ps = new PathStats(g.V); for (var i = 0; i < ps.Dist.Length; i++) { ps.Dist[i] = int.MaxValue; ps.Prev[i] = -1; } ps.Dist[s] = 0;//start vertice var pq = new IndexMinPQ<Distance>(ps.Dist.Length); for (int i = 0; i < ps.Dist.Length; i++) { pq.Insert(i, new Distance { V = i, Dist = ps.Dist[i] }); } while (!pq.IsEmpty()) { var v = pq.DelRoot(); foreach (var e in g.Adjacent(v)) { if (ps.Dist[e.V2] > ps.Dist[v] + e.Weight) { ps.Dist[e.V2] = ps.Dist[v] + e.Weight; ps.Prev[e.V2] = v; pq.ChangeKey(e.V2, new Distance { V = e.V2, Dist = ps.Dist[e.V2] }); } } } return ps; }
public static void Explore(GraphBase g, int v, DfsStats dfsStats) { PreVisitVertice(v, dfsStats); foreach (var e in g.Adjacent(v)) { if (!dfsStats.Visited[e.V2]) { Explore(g, e.V2, dfsStats); } //else if (e < v) //only directed graph has 'back edge' else if (g is DirectedGraph && e.V2 < v)//e < v is not right { dfsStats.BackEdges.Add(new Edge { V1 = v, V2 = e.V2 }); } } PostVisitVertice(v, dfsStats); }
private static PathStats GetPathStats(GraphBase g, int s, bool isShortest) { var ps = new PathStats(g.V); for (var i = 0; i < ps.Dist.Length; i++) { ps.Dist[i] = isShortest ? int.MaxValue : int.MinValue; ps.Prev[i] = -1; } ps.Dist[s] = 0;//start vertice var pq = isShortest ? new MinPQ<Distance>(ps.Dist.Length) : new MaxPQ<Distance>(ps.Dist.Length); pq.Insert(new Distance { Dist = 0, V = s }); while (!pq.IsEmpty()) { var v = pq.DelRoot(); foreach (var e in g.Adjacent(v.V)) { if ((isShortest && ps.Dist[e.V2] > ps.Dist[v.V] + e.Weight) || //shortest path (!isShortest && ps.Dist[e.V2] < ps.Dist[v.V] + e.Weight)) //longest path { ps.Dist[e.V2] = ps.Dist[v.V] + e.Weight; ps.Prev[e.V2] = v.V; pq.Insert(new Distance { V = e.V2, Dist = ps.Dist[e.V2] }); } } } return ps; }