public void DisjoinSetsPerformanceTest() { #region Arrange var numElements = 1000000; var djs = new DisjointSets(numElements); #endregion #region Act var firstRoot = 0; var secondRoot = numElements / 2; djs.CreateSet(firstRoot); djs.CreateSet(secondRoot); for (int i = 0; i < numElements; i++) { if (i != firstRoot && i != secondRoot) { if (i < secondRoot) { djs.AddToSet(firstRoot, i); } else { djs.AddToSet(secondRoot, i); } } } djs.Union(firstRoot, secondRoot); #endregion #region Assert Assert.AreEqual(1, djs.SetsCount); for (int i = 0; i < numElements; i++) { Assert.AreEqual(0, djs.GetIncludingSetId(i)); } #endregion }
public void DisjoinSetsBaseScenarioTest() { var djs = new DisjointSets(4); Assert.AreEqual(0, djs.SetsCount); var setId = djs.CreateSet(0); Assert.AreEqual(0, setId); Assert.AreEqual(1, djs.SetsCount); djs.AddToSet(setId, 1); Assert.AreEqual(setId, djs.GetIncludingSetId(1)); var setId1 = djs.CreateSet(2); Assert.AreEqual(2, djs.SetsCount); djs.Union(setId, setId1); Assert.AreEqual(1, djs.SetsCount); Assert.AreEqual(setId, djs.GetIncludingSetId(2)); }
/// <summary> /// Calculates minimal spanning tree using Kruskal algo. /// Edges are required to be sorted by weigth. /// </summary> /// <param name="numNodes">Count of nodes</param> /// <param name="edges">Edges data</param> /// <returns>Array of indicies of edges in minimal spanning tree</returns> public static int[] CalcKruskal(int numNodes, GraphEdge[] edges) { int[] result = new int[numNodes - 1]; var ds = new DisjointSets(numNodes); var connectedNodesCount = 0; var currResultEdge = 0; // for each edge try to include it in minimal spanning tree for (int i = 0; i < edges.Length; i++) { var set1 = ds.GetIncludingSetId(edges[i].Node1); var set2 = ds.GetIncludingSetId(edges[i].Node2); if (set1 == set2 && set1 != -1) { // this edge will introduce cycle, skip it // it already connects two nodes which are // already in the same region continue; } else { // edge connects two edges which are not in the same region // so this edge can be included into MST result[currResultEdge] = i; currResultEdge++; if (set1 != -1 && set2 != -1) { // edge connects two distinct regions - union them ds.Union(set1, set2); } else if (set1 != -1 && set2 == -1) { // node 2 is single, add to gerion of node 1 ds.AddToSet(set1, edges[i].Node2); connectedNodesCount += 1; } else if (set2 != -1 && set1 == -1) { // node 1 is single, add to gerion of node 2 ds.AddToSet(set2, edges[i].Node1); connectedNodesCount += 1; } else { // both nodes are singe // create region and add them into it var newSet = ds.CreateSet(edges[i].Node1); ds.AddToSet(newSet, edges[i].Node2); connectedNodesCount += 2; } // if all nodes are connected and in the single region // then MST is built if (connectedNodesCount == numNodes && ds.SetsCount == 1) { return(result); } } } return(result); }