public void DisjointSetForestConstructorTest() { // no parameters DisjointSetForest <Int32> disjointSet = new DisjointSetForest <Int32>(); Assert.AreEqual(0, disjointSet.Count); Assert.AreEqual(0, disjointSet.SetCount); // capacity parameter disjointSet = new DisjointSetForest <Int32>(100); Assert.AreEqual(0, disjointSet.Count); Assert.AreEqual(0, disjointSet.SetCount); // source parameter disjointSet = new DisjointSetForest <Int32>(_values); Assert.AreEqual(_values.Length, disjointSet.Count); Assert.AreEqual(_values.Length, disjointSet.SetCount); // exceptions Assert.Throws <ArgumentOutOfRangeException>(() => disjointSet = new DisjointSetForest <Int32>(-1)); Assert.Throws <ArgumentNullException>(() => disjointSet = new DisjointSetForest <Int32>((IEnumerable <Int32>)null)); }
public void DisjointSetForestConstructorTest() { // no parameters DisjointSetForest <Int32> disjointSet = new DisjointSetForest <Int32>(); disjointSet.Count.ShouldBe(0); disjointSet.SetCount.ShouldBe(0); // capacity parameter disjointSet = new DisjointSetForest <Int32>(100); disjointSet.Count.ShouldBe(0); disjointSet.SetCount.ShouldBe(0); // source parameter disjointSet = new DisjointSetForest <Int32>(this.values); disjointSet.Count.ShouldBe(this.values.Length); disjointSet.SetCount.ShouldBe(this.values.Length); // exceptions Should.Throw <ArgumentOutOfRangeException>(() => disjointSet = new DisjointSetForest <Int32>(-1)); Should.Throw <ArgumentNullException>(() => disjointSet = new DisjointSetForest <Int32>(null)); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _forest = new DisjointSetForest <IGraphVertex>(Source.Vertices); foreach (IGraphEdge edge in Source.Edges.OrderBy(x => _weightMetric(x))) { if (_forest.Find(edge.Source) != _forest.Find(edge.Target)) { _spanningEdges.Add(edge); _forest.Union(edge.Source, edge.Target); } } }
public void DisjointSetForestEnumeratorTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(this.values); IEnumerator enumerator = this.values.GetEnumerator(); IEnumerator <Int32> disjointSetEnumerator = disjointSetInt.GetEnumerator(); while (enumerator.MoveNext()) { disjointSetEnumerator.MoveNext().ShouldBeTrue(); disjointSetEnumerator.Current.ShouldBe(enumerator.Current); } }
public void DisjointSetForestEnumeratorTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(_values); IEnumerator enumerator = _values.GetEnumerator(); IEnumerator <Int32> disjointSetEnumerator = disjointSetInt.GetEnumerator(); while (enumerator.MoveNext()) { Assert.IsTrue(disjointSetEnumerator.MoveNext()); Assert.AreEqual(enumerator.Current, disjointSetEnumerator.Current); } }
public void DisjointSetForestJoinSetsTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in this.values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } for (Int32 i = 0; i < this.values.Length; i = i + 2) { disjointSetInt.JoinSets(this.values[i], this.values[i + 1]); disjointSetString.JoinSets(this.values[i].ToString(), this.values[i + 1].ToString()); } // testing representatives for (Int32 i = 0; i < this.values.Length; i = i + 2) { disjointSetInt.FindSet(this.values[i + 1]).ShouldBe(disjointSetInt.FindSet(this.values[i])); disjointSetString.FindSet(this.values[i + 1].ToString()).ShouldBe(disjointSetString.FindSet(this.values[i].ToString())); } // testing setCounts disjointSetInt.SetCount.ShouldBe(this.values.Length / 2); disjointSetString.SetCount.ShouldBe(this.values.Length / 2); disjointSetInt.Count.ShouldBe(this.values.Length); disjointSetString.Count.ShouldBe(this.values.Length); // exceptions Should.Throw <ArgumentException>(() => disjointSetInt.JoinSets(this.values[0], 1000)); Should.Throw <ArgumentException>(() => disjointSetInt.JoinSets(1000, this.values[0])); Should.Throw <ArgumentException>(() => disjointSetInt.JoinSets(1000, 101)); Should.Throw <ArgumentException>(() => disjointSetString.JoinSets(this.values[0].ToString(), 1000.ToString())); Should.Throw <ArgumentException>(() => disjointSetString.JoinSets(1000.ToString(), this.values[0].ToString())); Should.Throw <ArgumentException>(() => disjointSetString.JoinSets(1000.ToString(), 101.ToString())); Should.Throw <ArgumentNullException>(() => disjointSetString.JoinSets(this.values[0].ToString(), null)); Should.Throw <ArgumentNullException>(() => disjointSetString.JoinSets(null, this.values[0].ToString())); Should.Throw <ArgumentNullException>(() => disjointSetString.JoinSets(null, null)); }
public void DisjointSetForestUnionTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in _values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } for (Int32 i = 0; i < _values.Length; i = i + 2) { disjointSetInt.Union(_values[i], _values[i + 1]); disjointSetString.Union(_values[i].ToString(), _values[i + 1].ToString()); } // testing representatives for (Int32 i = 0; i < _values.Length; i = i + 2) { Assert.AreEqual(disjointSetInt.Find(_values[i]), disjointSetInt.Find(_values[i + 1])); Assert.AreEqual(disjointSetString.Find(_values[i].ToString()), disjointSetString.Find(_values[i + 1].ToString())); } // testing setCounts Assert.AreEqual(disjointSetInt.SetCount, _values.Length / 2); Assert.AreEqual(disjointSetString.SetCount, _values.Length / 2); Assert.AreEqual(disjointSetInt.Count, _values.Length); Assert.AreEqual(disjointSetString.Count, _values.Length); // exceptions Assert.Throws <ArgumentException>(() => disjointSetInt.Union(_values[0], 100)); Assert.Throws <ArgumentException>(() => disjointSetInt.Union(100, _values[0])); Assert.Throws <ArgumentException>(() => disjointSetInt.Union(100, 101)); Assert.Throws <ArgumentException>(() => disjointSetString.Union(_values[0].ToString(), 100.ToString())); Assert.Throws <ArgumentException>(() => disjointSetString.Union(100.ToString(), _values[0].ToString())); Assert.Throws <ArgumentException>(() => disjointSetString.Union(100.ToString(), 101.ToString())); Assert.Throws <ArgumentNullException>(() => disjointSetString.Union(_values[0].ToString(), null)); Assert.Throws <ArgumentNullException>(() => disjointSetString.Union(null, _values[0].ToString())); Assert.Throws <ArgumentNullException>(() => disjointSetString.Union(null, null)); }
/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { _edgeSet = new HashSet <IGraphEdge>(); _forest = new DisjointSetForest <IGraphVertex>(Source.Vertices); while (_forest.SetCount > 1) { IGraphVertex currentRep = null; foreach (IGraphVertex vertex in _forest.OrderedEnumerator) { if (currentRep != _forest.Find(vertex)) { //new component currentRep = _forest.Find(vertex); if (_edgeSet.Count > 0) { _spanningEdges.Add(_edgeSet.MinBy(x => _weightMetric(x)).First()); } _edgeSet.Clear(); } if (Source.OutEdges(vertex).Any(x => _forest.Find(x.Target) != currentRep)) { _edgeSet.Add( Source.OutEdges(vertex) .Where(x => _forest.Find(x.Target) != currentRep) .MinBy(y => _weightMetric(y)) .First()); } } if (_edgeSet.Count > 0) { //on the last element there is no component change _spanningEdges.Add(_edgeSet.MinBy(x => _weightMetric(x)).First()); } _edgeSet.Clear(); foreach (IGraphEdge spanningEdge in _spanningEdges) { _forest.Union(spanningEdge.Source, spanningEdge.Target); } } }
public void DisjointSetForestClearTest() { // empty DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); disjointSetInt.Clear(); disjointSetInt.Count.ShouldBe(0); disjointSetInt.SetCount.ShouldBe(0); // filled disjointSetInt = new DisjointSetForest <Int32>(this.values); disjointSetInt.Clear(); disjointSetInt.Count.ShouldBe(0); disjointSetInt.SetCount.ShouldBe(0); }
public void DisjointSetForestMakeSetTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in this.values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } // testing if added correctly disjointSetInt.Count.ShouldBe(this.values.Length); disjointSetInt.SetCount.ShouldBe(this.values.Length); disjointSetString.Count.ShouldBe(this.values.Length); disjointSetString.SetCount.ShouldBe(this.values.Length); foreach (Int32 value in this.values) { value.ShouldBe(disjointSetInt.FindSet(value)); disjointSetString.FindSet(value.ToString()).ShouldBe(value.ToString()); } // testing element uniqueness for (Int32 i = 0; i < 20; i++) { disjointSetInt.MakeSet(this.values[0]); disjointSetString.MakeSet(this.values[0].ToString()); } disjointSetInt.Count.ShouldBe(this.values.Length); disjointSetInt.SetCount.ShouldBe(this.values.Length); disjointSetString.Count.ShouldBe(this.values.Length); disjointSetString.SetCount.ShouldBe(this.values.Length); // exceptions Should.Throw <ArgumentNullException>(() => new DisjointSetForest <String>().MakeSet(null)); }
public void DisjointSetForestMakeSetTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in _values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } // testing if added correctly Assert.AreEqual(_values.Length, disjointSetInt.Count); Assert.AreEqual(_values.Length, disjointSetInt.SetCount); Assert.AreEqual(_values.Length, disjointSetString.Count); Assert.AreEqual(_values.Length, disjointSetString.SetCount); foreach (Int32 value in _values) { Assert.AreEqual(disjointSetInt.Find(value), value); Assert.AreEqual(disjointSetString.Find(value.ToString()), value.ToString()); } // testing element uniqueness for (Int32 i = 0; i < 20; i++) { disjointSetInt.MakeSet(_values[0]); disjointSetString.MakeSet(_values[0].ToString()); } Assert.AreEqual(_values.Length, disjointSetInt.Count); Assert.AreEqual(_values.Length, disjointSetInt.SetCount); Assert.AreEqual(_values.Length, disjointSetString.Count); Assert.AreEqual(_values.Length, disjointSetString.SetCount); // exceptions Assert.Throws <ArgumentNullException>(() => new DisjointSetForest <String>().MakeSet(null)); }
public void DisjointSetForestClearTest() { // empty DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); disjointSetInt.Clear(); Assert.AreEqual(0, disjointSetInt.Count); Assert.AreEqual(0, disjointSetInt.SetCount); // filled disjointSetInt = new DisjointSetForest <Int32>(_values); disjointSetInt.Clear(); Assert.AreEqual(0, disjointSetInt.Count); Assert.AreEqual(0, disjointSetInt.SetCount); }
public void DisjointSetForestFindTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in this.values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } foreach (Int32 value in this.values) { value.ShouldBe(disjointSetInt.FindSet(value)); disjointSetString.FindSet(value.ToString()).ShouldBe(value.ToString()); } // exceptions Should.Throw <ArgumentNullException>(() => disjointSetString.FindSet(null)); Should.Throw <ArgumentException>(() => disjointSetInt.FindSet(10000)); Should.Throw <ArgumentException>(() => disjointSetString.FindSet(10000.ToString())); }
/// <summary> /// Internal constructor. /// </summary> /// <param name="graph">adjacency list graph representation</param> /// <param name="matching">the matching of the graph</param> /// <param name="subset">subset a subset of vertices</param> private EdmondsMaximumMatching(int[][] graph, Matching matching, BitArray subset) { this.graph = graph; this.matching = matching; this.subset = subset; this.even = new int[graph.Length]; this.odd = new int[graph.Length]; this.queue = new List <int>(); // LinkedList this.dsf = new DisjointSetForest(graph.Length); // tmp storage of paths in the algorithm path = new int[graph.Length]; vAncestors = new BitArray(graph.Length); wAncestors = new BitArray(graph.Length); // continuously augment while we find new paths while (ExistAugmentingPath()) { ; } }
public void DisjointSetForestFindTest() { DisjointSetForest <Int32> disjointSetInt = new DisjointSetForest <Int32>(); DisjointSetForest <String> disjointSetString = new DisjointSetForest <String>(); foreach (Int32 value in _values) { disjointSetInt.MakeSet(value); disjointSetString.MakeSet(value.ToString()); } foreach (Int32 value in _values) { Assert.AreEqual(disjointSetInt.Find(value), value); Assert.AreEqual(disjointSetString.Find(value.ToString()), value.ToString()); } // exceptions Assert.Throws <ArgumentNullException>(() => disjointSetString.Find(null)); Assert.Throws <ArgumentException>(() => disjointSetInt.Find(100)); Assert.Throws <ArgumentException>(() => disjointSetString.Find(100.ToString())); }
/// <summary> /// Find an augmenting path an alternate it's matching. If an augmenting path /// was found then the search must be restarted. If a blossom was detected /// the blossom is contracted and the search continues. /// </summary> /// <returns>an augmenting path was found</returns> private bool ExistAugmentingPath() { // reset data structures Arrays.Fill(even, NIL); Arrays.Fill(odd, NIL); dsf = new DisjointSetForest(graph.Length); bridges.Clear(); queue.Clear(); // enqueue every unmatched vertex and place in the // even level (level = 0) for (int v = 0; v < graph.Length; v++) { if (subset[v] && matching.Unmatched(v)) { even[v] = v; queue.Add(v); } } // for each 'free' vertex, start a bfs search while (queue.Count != 0) { var v = queue[0]; queue.RemoveAt(0); foreach (var w in graph[v]) { if (!subset[w]) { continue; } // the endpoints of the edge are both at even levels in the // forest - this means it is either an augmenting path or // a blossom if (even[dsf.GetRoot(w)] != NIL) { if (Check(v, w)) { return(true); } } // add the edge to the forest if is not already and extend // the tree with this matched edge else if (odd[w] == NIL) { odd[w] = v; var u = matching.Other(w); // add the matched edge (potential though a blossom) if it // isn't in the forest already if (even[dsf.GetRoot(u)] == NIL) { even[u] = w; queue.Add(u); } } } } // no augmenting paths, matching is maximum return(false); }