static void Main(string[] args) { DisjointSets ds = new DisjointSets(); ds.MakeSet(1); ds.MakeSet(2); ds.MakeSet(3); ds.MakeSet(4); ds.MakeSet(5); ds.MakeSet(6); ds.MakeSet(7); ds.Union(1, 2); ds.Union(2, 3); ds.Union(4, 5); ds.Union(6, 7); ds.Union(5, 6); ds.Union(3, 7); Console.WriteLine(ds.FindSet(1).Data); Console.WriteLine(ds.FindSet(2).Data); Console.WriteLine(ds.FindSet(3).Data); Console.WriteLine(ds.FindSet(4).Data); Console.WriteLine(ds.FindSet(5).Data); Console.WriteLine(ds.FindSet(6).Data); Console.WriteLine(ds.FindSet(7).Data); }
public void MakeSet_WithPreExistingElements() { var sets = new DisjointSets <int>(Enumerable.Range(1, 10)); foreach (int i in Enumerable.Range(11, 10)) { sets.MakeSet(i); } foreach (int i in Enumerable.Range(1, 20)) { Assert.That(sets.FindSet(i), Is.EqualTo(i)); } }
/// <summary> /// /**https://en.wikipedia.org/wiki/Kruskal%27s_algorithm * KRUSKAL(G): * 1 A = ∅ * 2 foreach v ∈ G.V: * 3 MAKE-SET(v) * 4 foreach (u, v) in G.E ordered by weight(u, v), increasing: * 5 if FIND-SET(u) ≠ FIND-SET(v): * 6 A = A ∪ {(u, v)} * 7 UNION(u, v) * 8 return A * **/ /// </summary> /// <typeparam name="T"></typeparam> /// <param name="g"></param> /// <returns></returns> public static List <Edge <T> > GetMSTUsingKruskal <T>(this Graph <T> g) { EdgeComparer <T> comparer = new EdgeComparer <T>(); List <Edge <T> > result = new List <Edge <T> >(); //First sort the edges g.AllEdges.Sort(comparer); Console.WriteLine("Edes in Sorted Order"); foreach (var e in g.AllEdges) { Console.WriteLine(e.ToString()); } DisjointSets disjointSet = new DisjointSets(); //Create Set for each vertex foreach (var v in g.AllVertex.Values) { disjointSet.MakeSet(v.Id); } //For each edge, check if vertex is already in SET. //1. If yes, ignore //2. If not, Union and add it to result of edge foreach (var e in g.AllEdges) { var n1 = disjointSet.FindSet(e.V1.Id); var n2 = disjointSet.FindSet(e.V2.Id); if (n1 == n2) { continue; } else { result.Add(e); disjointSet.Union(e.V1.Id, e.V2.Id); } } return(result); }
public override void Run() { Result = new ConnectedComponentImage(InputImage.Width, InputImage.Height, -1); var cursor = new ImageCursor(InputImage, 1); // per semplicità ignora i bordi (1 pixel) int[] neighborLabels = new int[Metric == MetricType.CityBlock ? 2 : 4]; int nextLabel = 0; var equivalences = new DisjointSets(InputImage.PixelCount); do { // prima scansione if (InputImage[cursor] == Foreground) { int labelCount = 0; if (Result[cursor.West] >= 0) { neighborLabels[labelCount++] = Result[cursor.West]; } if (Result[cursor.North] >= 0) { neighborLabels[labelCount++] = Result[cursor.North]; } if (Metric == MetricType.Chessboard) { // anche le diagonali if (Result[cursor.Northwest] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northwest]; } if (Result[cursor.Northeast] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northeast]; } } if (labelCount == 0) { equivalences.MakeSet(nextLabel); // crea un nuovo set Result[cursor] = nextLabel++; // le etichette iniziano da 0 } else { int l = Result[cursor] = neighborLabels[0]; // seleziona la prima for (int i = 1; i < labelCount; i++) // equivalenze { if (neighborLabels[i] != l) { equivalences.MakeUnion(neighborLabels[i], l); // le rende equivalenti } } } } } while (cursor.MoveNext()); //rende le etichette numeri consecutivi int totalLabels; int[] corresp = equivalences.Renumber(nextLabel, out totalLabels); //seconda e ultima scansione cursor.Restart(); do { int l = Result[cursor]; if (l >= 0) { Result[cursor] = corresp[l]; } }while(cursor.MoveNext()); Result.ComponentCount = totalLabels; }