/// <summary> /// Kruskal's algorithm is an algorithm that finds a minimum spanning tree for a connected weighted graph. /// This means it finds a subset of the edges that forms a tree that includes every vertex, /// where the total weight of all the edges in the tree is minimized. /// If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component). /// </summary> /// <param name="g"></param> /// <returns></returns> public static IGraph KruskalsAlgorithm(IGraph g) { Console.WriteLine("Starting..."); int i1 = g.NumberOfVertices; IGraph graph1 = new GraphAsLists(i1); for (int j1 = 0; j1 < i1; j1++) { graph1.AddVertex(j1); } IPriorityQueue priorityQueue = new BinaryHeap(g.NumberOfEdges); IEnumerator iEnumerator = g.Edges.GetEnumerator(); Console.WriteLine("got the edge enumerator..."); try { while (iEnumerator.MoveNext()) { IEdge edge1 = (IEdge)iEnumerator.Current; int k; //the casting depends on the datatype of the weight, here you are on your own //we'll assume that an int will do as an example if (edge1.Weight == null) { k = 0; } else { try { k = (int)edge1.Weight; } catch { k = 0; } } priorityQueue.Enqueue(new Association(k, edge1)); } } finally { IDisposable iDisposable = iEnumerator as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } Console.WriteLine("after the edge enumerator..."); Console.WriteLine(priorityQueue.ToString()); IPartition partition = new PartitionAsForest(i1); Console.WriteLine("The partition: " + partition.Count); while (!priorityQueue.IsEmpty && (partition.Count > 1)) { IEdge edge2 = (IEdge)((Association)priorityQueue.DequeueMin()).Value; Console.WriteLine(edge2.ToString()); int i2 = edge2.V0.Number; int j2 = edge2.V1.Number; Console.WriteLine("got vertices (" + i2 + "," + j2 + ")"); ISet set1 = partition.Find(i2); ISet set2 = partition.Find(j2); if (set1 != set2) { partition.Join(set1, set2); graph1.AddConnection(i2, j2); } } return(graph1); }
/// <summary> /// Computes a spanning tree /// </summary> /// <param name="g"></param> /// <param name="s"></param> /// <returns></returns> public static IGraph PrimsAlgorithm(IGraph g, int s) { int i1 = g.NumberOfVertices; Entry[] entrys = new Entry[i1]; for (int j1 = 0; j1 < i1; j1++) { entrys[j1] = new Entry(false, int.MaxValue, int.MaxValue); } entrys[s].distance = 0; IPriorityQueue priorityQueue = new BinaryHeap(g.NumberOfEdges); priorityQueue.Enqueue(new Association(0, g.GetVertex(s))); while (!priorityQueue.IsEmpty) { IVertex vertex1 = (IVertex)((Association)priorityQueue.DequeueMin()).Value; if (entrys[vertex1.Number].known) { continue; } entrys[vertex1.Number].known = true; IEnumerator iEnumerator = vertex1.EmanatingEdges.GetEnumerator(); try { while (iEnumerator.MoveNext()) { IEdge edge = (IEdge)iEnumerator.Current; IVertex vertex2 = edge.MateOf(vertex1); int k = (edge.Weight == null? 0 :(int)edge.Weight); if (!entrys[vertex2.Number].known && entrys[vertex2.Number].distance > k) { entrys[vertex2.Number].distance = k; entrys[vertex2.Number].predecessor = vertex1.Number; priorityQueue.Enqueue(new Association(k, vertex2)); } } } finally { IDisposable iDisposable = iEnumerator as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } } IGraph graph1 = new GraphAsLists(i1); for (int i2 = 0; i2 < i1; i2++) { graph1.AddVertex(i2); } for (int j2 = 0; j2 < i1; j2++) { if (j2 != s) { graph1.AddConnection(j2, entrys[j2].predecessor); } } return(graph1); }