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 PrimMST(Graph g) { if (g.Directed) { Output.WriteLine("Can't run Prim's algorithm on a directed graph"); return null; } Graph copy = new Graph(); Graph mst = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List<Vertex> vertices = copy.GetVertices(); foreach (Vertex vert in vertices) { mst.AddVertex(vert); } PrimData v = new PrimData(); v.Predecessor = null; v.Seen = true; v.V = vertices[0]; v.D = 0; v.InMST = true; v.EdgeLength = float.PositiveInfinity; vertices[0].Tag = v; foreach (Vertex u in vertices) { if (!v.V.Equals(u)) { PrimData pd = new PrimData(); pd.D = float.PositiveInfinity; pd.V = u; pd.InMST = false; pd.Seen = false; u.Tag = pd; } } Heap<PrimData> q = new Heap<PrimData>(true); q.Add(vertices[0].Tag as PrimData); while (q.HasNext()) { PrimData pd = q.Next(); if (pd.Predecessor == null) { //mst.AddVertex(pd.V); } else { string label = pd.V.Label; mst.AddEdge(new Edge(pd.Predecessor, pd.V, pd.EdgeLength)); pd.V.Label = label; pd.InMST = true; } foreach (Edge e in pd.V.GetOutEdges()) { Vertex connectedVertex = e.GetToVertex(); PrimData data = connectedVertex.Tag as PrimData; if (!data.Seen) { q.Add(data); data.Predecessor = pd.V; data.EdgeLength = e.Weight; data.Seen = true; } if (data.D > e.Weight && !data.InMST) { data.D = e.Weight; data.Predecessor = pd.V; data.EdgeLength = e.Weight; q.Update(data); } } /*foreach (Edge e in pd.V.GetInEdges()) { Vertex connectedVertex = e.GetFromVertex(); PrimData data = connectedVertex.Tag as PrimData; if (!data.Seen) { q.Add(data); data.Predecessor = pd.V; data.EdgeLength = e.Weight; data.Seen = true; } if (data.D > e.Weight && !data.InMST) { data.D = e.Weight; data.Predecessor = pd.V; data.EdgeLength = e.Weight; q.Update(data); } }*/ } return mst; }
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; }
public static Graph KruskalMST(Graph g) { Graph copy = new Graph(); Graph mst = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List<Edge> edges = copy.GetEdges(); List<Vertex> vertices = copy.GetVertices(); for (int i = 0; i < vertices.Count; i++) { //Associate each vertex with a set of vertices //Initially, each vertex belongs to its own set List<Vertex> vertexSet = new List<Vertex>(); vertexSet.Add(vertices[i]); vertices[i].Tag = vertexSet; mst.AddVertex(vertices[i]); } //We don't want to consider edges going in the opposite direction List<Edge> filteredEdges = new List<Edge>(); for (int i = 0; i < edges.Count; i += 2) { filteredEdges.Add(edges[i]); } filteredEdges.Sort(delegate(Edge e1, Edge e2) { return e1.Weight.CompareTo(e2.Weight); }); //Have counter that counts number of edges used. //If it equals the total number of edges then the original graph was disconnected int edgeIndex = 0; //Loop through all the edges while (edgeIndex < filteredEdges.Count/* && mst.GetEdges().Count < g.GetVertices().Count - 1*/) { //Walk up the array instead of removing the vertex Edge minEdge = filteredEdges[edgeIndex]; //Get the sets associated with the vertices on the minEdge List<Vertex> fromSet = minEdge.GetFromVertex().Tag as List<Vertex>; List<Vertex> toSet = minEdge.GetToVertex().Tag as List<Vertex>; //If these two sets are not the same set... if (!fromSet.Equals(toSet)) { //...then add the edge to the MST string fromLabel = minEdge.GetFromVertex().Label; string toLabel = minEdge.GetToVertex().Label; mst.AddEdge(minEdge); minEdge.GetFromVertex().Label = fromLabel; minEdge.GetToVertex().Label = toLabel; //Merge the two vertices' sets together List<Vertex> newList = fromSet.Union(toSet).ToList<Vertex>(); foreach (Vertex v in newList) { v.Tag = newList; } minEdge.GetFromVertex().Tag = newList; minEdge.GetToVertex().Tag = newList; } //Offset by 2 because we're ignoring edges that go in the opposite direction edgeIndex++; } return mst; }
private static void TestMatrixStuff() { Graph g = new Graph(); g.Directed = true; Vertex v1 = new Vertex(); Vertex v2 = new Vertex(); Vertex v3 = new Vertex(); Vertex v4 = new Vertex(); g.AddVertex(v1); g.AddVertex(v2); g.AddVertex(v3); g.AddVertex(v4); g.AddEdge(new Edge(v2, v1, 25f)); g.AddEdge(new Edge(v1, v3, 10f)); g.RemoveEdge(g.GetEdges()[1]); g.AddEdge(new Edge(v4, v2, 7f)); g.RemoveVertex(v1); g.RemoveVertex(v2); g.AddEdge(new Edge(v3, v4, 30f)); g.AddEdge(new Edge(v4, v3, 27f)); Console.WriteLine("Testing graph insertion and deletion"); g.PrintMatrix(); Console.WriteLine(); Graph g2 = new Graph(); g.CopyTo(g2); g2.PrintMatrix(); }
public static Graph PrimMST(Graph g) { if (g.Directed) { Output.WriteLine("Can't run Prim's algorithm on a directed graph"); return(null); } Graph copy = new Graph(); Graph mst = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List <Vertex> vertices = copy.GetVertices(); foreach (Vertex vert in vertices) { mst.AddVertex(vert); } PrimData v = new PrimData(); v.Predecessor = null; v.Seen = true; v.V = vertices[0]; v.D = 0; v.InMST = true; v.EdgeLength = float.PositiveInfinity; vertices[0].Tag = v; foreach (Vertex u in vertices) { if (!v.V.Equals(u)) { PrimData pd = new PrimData(); pd.D = float.PositiveInfinity; pd.V = u; pd.InMST = false; pd.Seen = false; u.Tag = pd; } } Heap <PrimData> q = new Heap <PrimData>(true); q.Add(vertices[0].Tag as PrimData); while (q.HasNext()) { PrimData pd = q.Next(); if (pd.Predecessor == null) { //mst.AddVertex(pd.V); } else { string label = pd.V.Label; mst.AddEdge(new Edge(pd.Predecessor, pd.V, pd.EdgeLength)); pd.V.Label = label; pd.InMST = true; } foreach (Edge e in pd.V.GetOutEdges()) { Vertex connectedVertex = e.GetToVertex(); PrimData data = connectedVertex.Tag as PrimData; if (!data.Seen) { q.Add(data); data.Predecessor = pd.V; data.EdgeLength = e.Weight; data.Seen = true; } if (data.D > e.Weight && !data.InMST) { data.D = e.Weight; data.Predecessor = pd.V; data.EdgeLength = e.Weight; q.Update(data); } } /*foreach (Edge e in pd.V.GetInEdges()) * { * Vertex connectedVertex = e.GetFromVertex(); * PrimData data = connectedVertex.Tag as PrimData; * if (!data.Seen) * { * q.Add(data); * data.Predecessor = pd.V; * data.EdgeLength = e.Weight; * data.Seen = true; * } * * if (data.D > e.Weight && !data.InMST) * { * data.D = e.Weight; * data.Predecessor = pd.V; * data.EdgeLength = e.Weight; * q.Update(data); * } * }*/ } return(mst); }
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); }
public static Graph KruskalMST(Graph g) { Graph copy = new Graph(); Graph mst = new Graph(); //Create a copy to preserve g's state g.CopyTo(copy); List <Edge> edges = copy.GetEdges(); List <Vertex> vertices = copy.GetVertices(); for (int i = 0; i < vertices.Count; i++) { //Associate each vertex with a set of vertices //Initially, each vertex belongs to its own set List <Vertex> vertexSet = new List <Vertex>(); vertexSet.Add(vertices[i]); vertices[i].Tag = vertexSet; mst.AddVertex(vertices[i]); } //We don't want to consider edges going in the opposite direction List <Edge> filteredEdges = new List <Edge>(); for (int i = 0; i < edges.Count; i += 2) { filteredEdges.Add(edges[i]); } filteredEdges.Sort(delegate(Edge e1, Edge e2) { return(e1.Weight.CompareTo(e2.Weight)); }); //Have counter that counts number of edges used. //If it equals the total number of edges then the original graph was disconnected int edgeIndex = 0; //Loop through all the edges while (edgeIndex < filteredEdges.Count /* && mst.GetEdges().Count < g.GetVertices().Count - 1*/) { //Walk up the array instead of removing the vertex Edge minEdge = filteredEdges[edgeIndex]; //Get the sets associated with the vertices on the minEdge List <Vertex> fromSet = minEdge.GetFromVertex().Tag as List <Vertex>; List <Vertex> toSet = minEdge.GetToVertex().Tag as List <Vertex>; //If these two sets are not the same set... if (!fromSet.Equals(toSet)) { //...then add the edge to the MST string fromLabel = minEdge.GetFromVertex().Label; string toLabel = minEdge.GetToVertex().Label; mst.AddEdge(minEdge); minEdge.GetFromVertex().Label = fromLabel; minEdge.GetToVertex().Label = toLabel; //Merge the two vertices' sets together List <Vertex> newList = fromSet.Union(toSet).ToList <Vertex>(); foreach (Vertex v in newList) { v.Tag = newList; } minEdge.GetFromVertex().Tag = newList; minEdge.GetToVertex().Tag = newList; } //Offset by 2 because we're ignoring edges that go in the opposite direction edgeIndex++; } return(mst); }