public static (bool connected, Graph tree) Prim(this Graph g, int startingVertex = 0) { if (g.Directed) { throw new WrongGraphException("Graph must be an undirected graph"); } if (startingVertex < 0 || startingVertex >= g.VerticesCount) { throw new ArgumentOutOfRangeException("startingVertex"); } Graph tree = g.IsolatedGraph(g.Directed); PairingHeap <Edge> queue = new PairingHeap <Edge>((x, y) => x.Weight > y.Weight); UnionFind unionFind = new UnionFind(g.VerticesCount); foreach (var e in g.GetEdgesFrom(startingVertex)) { queue.Insert(e); } int c = 0; while (true) { if (queue.IsEmpty() || c == g.VerticesCount - 1) { return(c == g.VerticesCount - 1 ? true : false, tree); } var e = queue.ExtractMinimum(); if (unionFind.FindParent(e.value.From) != unionFind.FindParent(e.value.To)) { tree.AddEdge(e.value); unionFind.Union(e.value.From, e.value.To); foreach (var f in g.GetEdgesFrom(e.value.To)) { queue.Insert(f); } c++; } } }
// Test program public static void Main(string[] args) { PairingHeap <int> h = new PairingHeap <int>( ); int numItems = 10000; int i = 37; int j; Console.WriteLine("Checking; no bad output is good"); for (i = 37; i != 0; i = (i + 37) % numItems) { h.Insert(i); } for (i = 1; i < numItems; i++) { if (h.DeleteMin( ) != i) { Console.WriteLine("Oops! " + i); } } List <IPriorityQueuePosition <int> > p = new List <IPriorityQueuePosition <int> >( ); for (i = 0; i < numItems; i++) { p.Add(null); } for (i = 0, j = numItems / 2; i < numItems; i++, j = (j + 71) % numItems) { p[j] = h.Insert(j + numItems); } for (i = 0, j = numItems / 2; i < numItems; i++, j = (j + 53) % numItems) { h.DecreaseKey(p[j], p[j].GetValue( ) - numItems); } i = -1; while (!h.IsEmpty( )) { if (h.DeleteMin( ) != ++i) { Console.WriteLine("Oops! " + i + " "); } } Console.WriteLine("Check completed"); }
// Single-source weighted shortest-path algorithm using pairing heaps. public void Dijkstra2(string startName) { IPriorityQueue <Path> pq = new PairingHeap <Path>(); Vertex start = vertexMap[startName]; // throws an exception if not found ClearAll(); start.pos = pq.Insert(new Path(start, 0)); start.dist = 0; while (!pq.IsEmpty()) { Path vrec = pq.DeleteMin(); Vertex v = vrec.dest; foreach (Edge e in v.adj) { Vertex w = e.dest; double cvw = e.cost; if (cvw < 0) { throw new GraphException("Graph has negative edges"); } if (w.dist > v.dist + cvw) { w.dist = v.dist + cvw; w.prev = v; Path newVal = new Path(w, w.dist); if (w.pos == null) { w.pos = pq.Insert(newVal); } else { pq.DecreaseKey(w.pos, newVal); } } } } }
public static (bool connected, Graph tree) Kruskal(this Graph g) { if (g.Directed) { throw new WrongGraphException("Graph must be an undirected graph"); } Graph tree = g.IsolatedGraph(g.Directed); PairingHeap <Edge> queue = new PairingHeap <Edge>((x, y) => x.Weight > y.Weight); UnionFind unionFind = new UnionFind(g.VerticesCount); for (int i = 0; i < g.VerticesCount; i++) { foreach (var e in g.GetEdgesFrom(i)) { queue.Insert(e); } } int c = 0; while (true) { if (queue.IsEmpty() || c == g.VerticesCount - 1) { return(c == g.VerticesCount - 1 ? true : false, tree); } var e = queue.ExtractMinimum(); if (unionFind.FindParent(e.value.From) != unionFind.FindParent(e.value.To)) { tree.AddEdge(e.value); unionFind.Union(e.value.From, e.value.To); c++; } } }