public static Graph LabelCorrecting(Graph g, int vert) { Output.WriteLine("[Label Correcting Output]"); //Not working, I think because of the two loops for in and out edges //Change this to assume g is an undirected graph //Keep a heap of vertices, based on their distance label //Each one is initially infinity, except the intial vertex, which is 0 Graph copy = new Graph(); Graph tree = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List <Vertex> vertices = copy.GetVertices(); List <Edge> edges = copy.GetEdges(); DijkstraData v = new DijkstraData(); v.Predecessor = null; v.InQ = false; v.V = vertices[vert]; v.D = 0; v.InTree = false; v.EdgeLength = float.PositiveInfinity; vertices[vert].Tag = v; Heap <DijkstraData> q = new Heap <DijkstraData>(true); q.Add(vertices[vert].Tag as DijkstraData); (vertices[vert].Tag as DijkstraData).InQ = true; foreach (Vertex u in vertices) { if (!v.V.Equals(u)) { DijkstraData dd = new DijkstraData(); dd.D = float.PositiveInfinity; dd.V = u; dd.InTree = false; dd.InQ = false; u.Tag = dd; } } float maxEdgeWeight = float.NegativeInfinity; foreach (Edge e in edges) { if (Math.Abs(e.Weight) > maxEdgeWeight) { maxEdgeWeight = Math.Abs(e.Weight); } } int n = vertices.Count; float negativeCycleCheck = n * -maxEdgeWeight; while (q.HasNext()) { DijkstraData dd = q.Next(); dd.InQ = false; /*if (dd.Predecessor == null) * { * tree.AddVertex(dd.V); * } * else * { * tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength)); * dd.InTree = true; * }*/ foreach (Edge e in dd.V.GetOutEdges()) { Vertex connectedVertex = e.GetToVertex(); DijkstraData data = connectedVertex.Tag as DijkstraData; if (data.D > dd.D + e.Weight) { data.D = dd.D + e.Weight; if (data.D < negativeCycleCheck) { throw new Exception("Negative cycle detected!"); } data.Predecessor = dd.V; if (!q.Contains(data)) { q.Add(data); data.InQ = true; } } } if (g.Directed) { continue; } foreach (Edge e in dd.V.GetInEdges()) { Vertex connectedVertex = e.GetFromVertex(); DijkstraData data = connectedVertex.Tag as DijkstraData; if (data.D > dd.D + e.Weight) { data.D = dd.D + e.Weight; if (data.D < negativeCycleCheck) { throw new Exception("Negative cycle detected!"); } data.Predecessor = dd.V; if (!q.Contains(data)) { q.Add(data); data.InQ = true; } } } } Output.WriteLine("Distance from selected vertex to:"); foreach (Vertex vertex in vertices) { Output.WriteLine(vertex.ToString() + " = " + (vertex.Tag as DijkstraData).D); } Output.WriteLine("[End Label Correcting Output]"); return(tree); }
public static Graph Dijkstra(Graph g, int vert, bool directed) { Output.WriteLine("[Dijkstra Output]"); //If I get a negative edge weight, tell user to use label correcting instead of dijkstra's //Change this to assume g is an undirected graph //Keep a heap of vertices, based on their distance label //Each one is initially infinity, except the intial vertex, which is 0 Graph copy = new Graph(); Graph tree = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List <Vertex> vertices = copy.GetVertices(); List <Edge> edges = copy.GetEdges(); DijkstraData v = new DijkstraData(); v.Predecessor = null; v.InQ = false; v.V = vertices[vert]; v.D = 0; v.InTree = false; v.EdgeLength = float.PositiveInfinity; vertices[vert].Tag = v; Heap <DijkstraData> q = new Heap <DijkstraData>(true); q.Add(vertices[vert].Tag as DijkstraData); (vertices[vert].Tag as DijkstraData).InQ = true; foreach (Vertex u in vertices) { if (!v.V.Equals(u)) { DijkstraData dd = new DijkstraData(); dd.D = float.PositiveInfinity; dd.V = u; dd.InTree = false; u.Tag = dd; q.Add(dd); dd.InQ = true; } } foreach (Edge e in edges) { if (e.Weight < 0) { Output.WriteLine("Negative edge weight detected. Use Label Correcting instead of Dijkstra"); return(null); } } while (q.HasNext()) { DijkstraData dd = q.Next(); dd.InQ = false; /*if (dd.Predecessor == null) * { * tree.AddVertex(dd.V); * dd.InTree = true; * } * else * { * tree.AddEdge(new Edge(dd.Predecessor, dd.V, dd.EdgeLength)); * dd.InTree = true; * }*/ foreach (Edge e in dd.V.GetOutEdges()) { Vertex connectedVertex = e.GetToVertex(); DijkstraData data = connectedVertex.Tag as DijkstraData; if (data.InQ) { if (dd.D + e.Weight < data.D) { if (dd.D + e.Weight < data.D) { data.D = dd.D + e.Weight; q.Update(data); } } } } //If this is a directed graph, don't consider in edges if (directed) { continue; } foreach (Edge e in dd.V.GetInEdges()) { Vertex connectedVertex = e.GetFromVertex(); DijkstraData data = connectedVertex.Tag as DijkstraData; if (data.InQ) { if (dd.D + e.Weight < data.D) { data.D = dd.D + e.Weight; q.Update(data); } } } } Output.WriteLine("Distance from selected vertex to:"); foreach (Vertex vertex in vertices) { Output.WriteLine(vertex.ToString() + " = " + (vertex.Tag as DijkstraData).D); } Output.WriteLine("[End Dijkstra Output]"); return(tree); }