public static bool DetectCycleinUndirectedGraphUsingDisjointSets <T>(this Graph <T> g, out long v1, out long v2) { DisjointSets ds = new DisjointSets(); v1 = Int32.MaxValue; v2 = Int32.MaxValue; //Step 1: Make a set for all nodes in graph foreach (var v in g.AllVertex.Values) { ds.MakeSet(v.Id); } //For all edges, findset each vertex. // If the findset does not match, do union else you have found a cycle foreach (var edge in g.AllEdges) { var n1 = ds.FindSet(edge.V1.Id); var n2 = ds.FindSet(edge.V2.Id); if (n1 == n2) { v1 = edge.V1.Id; v2 = edge.V2.Id; return(true); } ds.Union(edge.V1.Id, edge.V2.Id); } return(false); }
/// <summary> /// Compute comparability for a method's parameters based on the types of the parameters. Two parameters /// are considered comparable if one can be assigned to the other. /// </summary> /// <param name="parameters">the parameters</param> /// <seealso cref="TypeHelper.TypesAreAssignmentCompatible"/> /// <returns>comparability sets for the parameters</returns> public static HashSet <HashSet <string> > ParameterTypeComparability(IEnumerable <IParameterDefinition> parameters) { Contract.Requires(parameters != null); Contract.Ensures(Contract.Result <HashSet <HashSet <string> > >() != null); Dictionary <IParameterDefinition, int> ids = new Dictionary <IParameterDefinition, int>(); DisjointSets cmp = new DisjointSets(); foreach (var p in parameters) { ids.Add(p, cmp.AddElement()); } foreach (var lhs in parameters) { Contract.Assume(ids.ContainsKey(lhs), "Error tracking parameter " + lhs.Name); foreach (var rhs in parameters) { Contract.Assume(ids.ContainsKey(rhs), "Error tracking parameter " + rhs.Name); if (TypeHelper.TypesAreAssignmentCompatible(lhs.Type.ResolvedType, rhs.Type.ResolvedType, true)) { cmp.Union(cmp.FindSet(ids[lhs]), cmp.FindSet(ids[rhs])); } } } var result = new HashSet <HashSet <string> >(ids.Keys.GroupBy(p => cmp.FindSet(ids[p])).Select(g => new HashSet <string>(g.Select(p => p.Name.Value)))); return(result); }
public KruskalMST(Graph g) { BinaryHeapPQ <Edge> pq = new BinaryHeapPQ <Edge>(); for (int v = 0; v < g.V; v++) { for (int i = 0; i < g.Deg(v); i++) { pq.Insert(new Edge() { U = v, V = g.AdjV(v, i), W = g.AdjW(v, i) }); } } DisjointSets ds = new DisjointSets(g.V); while (pq.Count > 0 && mst.Count < g.V - 1) { Edge e = pq.ExtractMin(); int v = e.U; int w = e.V; if (ds.FindSet(v) != ds.FindSet(w)) { ds.Union(v, w); mst.Add(e); } } }
public void RunTest() { DisjointSets ds = new DisjointSets(_numElements); int[] e2set = new int[_numElements]; HashSet <int>[] sets = new HashSet <int> [_numSets]; for (int i = 0; i < _numSets; i++) { sets[i] = new HashSet <int>(); } Random rnd = new Random(); for (int i = 0; i < _numElements; i++) { int nset = rnd.Next(_numSets); e2set[i] = nset; sets[nset].Add(i); } foreach (HashSet <int> set in sets) { Queue <int> q = new Queue <int>(set); if (q.Count == 0) { continue; } int last = q.Dequeue(); while (q.Count > 0) { int cur = q.Dequeue(); ds.Union(ds.FindSet(last), ds.FindSet(cur)); last = cur; } } int[] reps = new int[_numSets]; for (int i = 0; i < _numSets; i++) { reps[i] = -1; } for (int i = 0; i < _numElements; i++) { int rep = ds.FindSet(i); int nset = e2set[i]; if (reps[nset] == -1) { reps[nset] = rep; } else if (reps[nset] != rep) { throw new TestFailedException("Test with " + _numElements + " elements and " + _numSets + " sets: wrong representant"); } } }
public void Union() { var sets = new DisjointSets <int>(new int[] { 1, 2, 3, 4, 5, 6 }); sets.Union(1, 2); Assert.That(sets.FindSet(1), Is.EqualTo(1).Or.EqualTo(2)); Assert.That(sets.FindSet(2), Is.EqualTo(1).Or.EqualTo(2)); foreach (int i in new int[] { 3, 4, 5, 6 }) { Assert.That(sets.FindSet(i), Is.EqualTo(i)); } }
public int GetComparability(string name) { Contract.Requires(!string.IsNullOrWhiteSpace(name)); Contract.Ensures(Contract.Result <int>() >= 0); return(comparability.FindSet(GetId(name))); }
/// <summary> /// Returns the names in the same comparability set as <code>name</code>. This set includes <code>name</code>. /// </summary> /// <param name="name"></param> /// <returns></returns> public HashSet <string> ComparabilitySet(string name) { Contract.Requires(!string.IsNullOrWhiteSpace(name)); Contract.Ensures(Contract.Result <HashSet <string> >() != null); Contract.Ensures(Contract.Result <HashSet <string> >().Contains(name)); if (ids.ContainsKey(name)) { var groupId = comparability.FindSet(ids[name]); return(new HashSet <string>(Comparability.Where(x => x.Value == groupId).Select(x => x.Key))); } else { return(new HashSet <string>(new[] { name })); } }
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 FindSet_WithoutPreExistingElements() { var sets = new DisjointSets <int>(); foreach (int i in Enumerable.Range(1, 10)) { sets.MakeSet(i); foreach (int j in Enumerable.Range(1, i)) { Assert.That(sets.FindSet(j), Is.EqualTo(j)); } } foreach (int i in Enumerable.Range(1, 10)) { Assert.That(sets.FindSet(i), Is.EqualTo(i)); } }
public void Union_TypicalCase() { var sets = new DisjointSets <int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); sets.Union(1, 2); sets.Union(2, 3); sets.Union(3, 4); sets.Union(5, 6); sets.Union(3, 7); foreach (int i in new int[] { 1, 2, 3, 4, 5, 6, 7 }) { Assert.That(new int[] { sets.FindSet(i) }, Is.SubsetOf(new int[] { 1, 2, 3, 4, 5, 6, 7 })); // Sort of hacky; Is.MemberOf would be better } foreach (int i in new int[] { 8, 9, 10 }) { 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 void RunTest() { DisjointSets ds = new DisjointSets(_numElements); int[] e2set = new int[_numElements]; HashSet<int>[] sets = new HashSet<int>[_numSets]; for (int i = 0; i < _numSets; i++) { sets[i] = new HashSet<int>(); } Random rnd = new Random(); for (int i = 0; i < _numElements; i++) { int nset = rnd.Next(_numSets); e2set[i] = nset; sets[nset].Add(i); } foreach (HashSet<int> set in sets) { Queue<int> q = new Queue<int>(set); if (q.Count == 0) continue; int last = q.Dequeue(); while (q.Count > 0) { int cur = q.Dequeue(); ds.Union(ds.FindSet(last), ds.FindSet(cur)); last = cur; } } int[] reps = new int[_numSets]; for (int i = 0; i < _numSets; i++) reps[i] = -1; for (int i = 0; i < _numElements; i++) { int rep = ds.FindSet(i); int nset = e2set[i]; if (reps[nset] == -1) reps[nset] = rep; else if (reps[nset] != rep) throw new TestFailedException("Test with " + _numElements + " elements and " + _numSets + " sets: wrong representant"); } }
public void FindSet_WithPreExistingElements() { var elements = new int[] { 1, 2, 3, 4 }; var sets = new DisjointSets <int>(elements); foreach (var element in elements) { Assert.That(sets.FindSet(element), Is.EqualTo(element)); } }
public void Constructor_TypicalCase() { var elements = new int[] { 1, 2, 3, 4, 5 }; var sets = new DisjointSets <int>(elements); foreach (var element in elements) { Assert.That(sets.FindSet(element), Is.EqualTo(element)); } }
public TypeSummary(string assemblyQualifiedName, NameBuilder names, IEnumerable <MethodVisitor> methods) { Contract.Requires(!string.IsNullOrEmpty(assemblyQualifiedName)); Contract.Requires(names != null); Contract.Requires(methods != null); Contract.Ensures(ids.Keys.SetEquals(names.ThisNames())); this.AssemblyQualifiedName = assemblyQualifiedName; // give a union-find id to each instance expression name foreach (var name in names.ThisNames()) { ids.Add(name, comparability.AddElement()); } // union the sets, according to each method's opinion foreach (var name in names.ThisNames()) { HashSet <string> indexOpinion = new HashSet <string>(); foreach (var method in methods) { var opinion = method.ComparabilitySet(name).Intersect(ids.Keys); string last = null; foreach (var other in opinion) { if (last != null) { comparability.Union(comparability.FindSet(ids[last]), comparability.FindSet(ids[name])); } last = other; } indexOpinion.UnionWith(method.IndexComparabilityOpinion(name).Intersect(names.ThisNames())); } if (indexOpinion.Count > 0) { arrayIndexes.Add(name, indexOpinion); } } }
public void FindSet_ThrowsOnNonExistentElement() { var sets = new DisjointSets <int>(new int[] { 1, 2, 3 }); Assert.That(() => sets.FindSet(4), Throws.ArgumentException); }
/// <summary> /// Finds the representant of a set element. /// </summary> /// <param name="elem">set element</param> /// <returns>representant</returns> public T Find(T elem) { int fidx = _impl.FindSet(_index[elem]); return(_elems[_repShuffle[fidx]]); }