Exemplo n.º 1
0
        public void Union_ThrowsOnElementsInTheSameSet2()
        {
            var sets = new DisjointSets <int>(new int[] { 1, 2, 3, 4 });

            sets.Union(4, 3);
            sets.Union(3, 2);
            sets.Union(2, 1);
            Assert.That(() => sets.Union(1, 4), Throws.ArgumentException);
        }
Exemplo n.º 2
0
        public void GetSet_TypicalCase2()
        {
            var sets = new DisjointSets <int>(new int[] { 1, 2, 3, 4, 5, 6 });

            sets.Union(1, 2);
            sets.Union(1, 6);
            sets.Union(3, 4);

            Assert.That(sets.GetSet(1), Is.EquivalentTo(new HashSet <int>(new int[] { 1, 2, 6 })));
            Assert.That(sets.GetSet(2), Is.EquivalentTo(new HashSet <int>(new int[] { 1, 2, 6 })));
            Assert.That(sets.GetSet(6), Is.EquivalentTo(new HashSet <int>(new int[] { 1, 2, 6 })));
            Assert.That(sets.GetSet(3), Is.EquivalentTo(new HashSet <int>(new int[] { 3, 4 })));
            Assert.That(sets.GetSet(4), Is.EquivalentTo(new HashSet <int>(new int[] { 3, 4 })));
            Assert.That(sets.GetSet(5), Is.EquivalentTo(new HashSet <int>(new int[] { 5 })));
        }
Exemplo n.º 3
0
        public List <Edge> GetMST(Graph graph)
        {
            List <Edge> mst = new List <Edge>();

            // Sort the edges in ascending order of their weights
            List <Edge> sortedEdges = graph.AllEdges.OrderBy(e => e.Weight).ToList();

            int totalNumOfVertices = graph.AllVertices.Count();
            DisjointSets <int> ds  = new DisjointSets <int>();


            foreach (Edge e in sortedEdges)
            {
                if (mst.Count() >= totalNumOfVertices)
                {
                    // total number of edges in an mst will be total number of vertices in a graph -1
                    break;
                }
                if (!ds.Find(e.StId, e.EndId))
                {
                    // the stId and endId vertex of the edge are not in the same set
                    // hence adding this edge wont create a cycle
                    ds.Union(e.StId, e.EndId);
                    mst.Add(e);
                }
            }

            return(mst);
        }
Exemplo n.º 4
0
        public static List <Edge> MinimumSpanningTree(IGraph g)
        {
            var result = new List <Edge>();

            var edges       = g.Edges().OrderBy(e => e.weight).ToArray();
            var vertexCount = g.VertexesCount();
            var sets        = new DisjointSets <int>();

            foreach (var edge in edges)
            {
                if (sets.ItemCount == vertexCount)
                {
                    break;
                }

                var setFrom = sets.MakeSet(edge.from);
                var setTo   = sets.MakeSet(edge.to);

                if (setFrom != setTo)
                {
                    sets.Union(setFrom, setTo);
                    result.Add(edge);
                }
            }

            return(result);
        }
Exemplo n.º 5
0
        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);
                }
            }
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
 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
 }
Exemplo n.º 9
0
        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));
            }
        }
Exemplo n.º 10
0
    // Complete the maxRegion function below.
    static int maxRegion(int[][] matrix)
    {
        var xOffset = new[] { -1, 0, 1, -1 };
        var yOffset = new[] { -1, -1, -1, 0 };

        var ds = new DisjointSets();

        var rows = matrix.Length;
        var cols = matrix[0].Length;

        var max = 0;

        Func <int, int, bool> isValid = (int x, int y) =>
        {
            return(x >= 0 && x < cols && y >= 0 && y < rows);
        };

        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < cols; x++)
            {
                if (matrix[y][x] == 0)
                {
                    continue;
                }
                var current = new CellKey(x, y);
                ds.AddNew(current);
                max = Math.Max(max, 1);

                for (int index = 0; index < xOffset.Length; index++)
                {
                    var ox = x + xOffset[index];
                    var oy = y + yOffset[index];

                    if (!isValid(ox, oy))
                    {
                        continue;
                    }

                    if (matrix[oy][ox] == 0)
                    {
                        continue;
                    }

                    var offset = new CellKey(ox, oy);

                    if (ds.Find(current) != ds.Find(offset))
                    {
                        max = Math.Max(max, ds.Union(current, offset));
                    }
                }
            }
        }

        return(max);
    }
Exemplo n.º 11
0
        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");
                }
            }
        }
Exemplo n.º 12
0
        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));
            }
        }
Exemplo n.º 13
0
        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);
        }
Exemplo n.º 14
0
 public void Test01NonGeneric()
 {
     for (var i = 1; i <= ElementsNumber; i += 1 + i / (10 + _random.Next(0, 10)))
     {
         Console.WriteLine($"i = {i}");
         var djs = new DisjointSets(ElementsNumber);
         foreach (var el in RandomShuffle(_seq))
         {
             djs.Union(el, el % i);
         }
         VerifySets(djs, i);
     }
 }
Exemplo n.º 15
0
        /// <summary>
        /// Mark the expressions with the given ids as being in the same comparability set.
        /// </summary>
        /// <param name="idsToMark">the expression ids</param>
        /// <seealso cref="ids"/>
        /// <returns><c>true</c> if any changes to comparability were made</returns>
        private bool Mark(IEnumerable <int> idsToMark)
        {
            bool modified = false;
            int? last     = null;

            foreach (var id in idsToMark)
            {
                if (last != null)
                {
                    modified |= comparability.Union(comparability.FindSet(last.Value), comparability.FindSet(id));
                }
                last = id;
            }
            return(modified);
        }
Exemplo n.º 16
0
 public void Test02Generic()
 {
     for (var i = 1; i <= ElementsNumber; i += 1 + i / (10 + _random.Next(0, 10)))
     {
         Console.WriteLine($"i = {i}");
         var rs  = RandomShuffle(_seq).ToList();
         var djs = new DisjointSets <int>(rs);
         foreach (var el in rs)
         {
             djs.Union(el, el % i);
         }
         VerifySets(djs, i);
         for (var j = 0; j < ElementsNumber; ++j)
         {
             Assert.That(djs[j], Is.EqualTo(rs[j]));
         }
     }
 }
Exemplo n.º 17
0
    // Complete the maxCircle function below.
    static int[] maxCircle(int[][] queries)
    {
        var ds     = new DisjointSets();
        var result = new int[queries.Length];

        var max = 0;

        for (int index = 0; index < queries.Length; index++)
        {
            var left  = ds.FindOrAdd(queries[index][0]);
            var right = ds.FindOrAdd(queries[index][1]);

            max           = Math.Max(max, ds.Union(left, right));
            result[index] = max;
        }

        return(result);
    }
Exemplo n.º 18
0
        public static int[] Solve(int[][] queries)
        {
            DisjointSets userMap = new DisjointSets();

            int[] result = new int[queries.Length];

            for (int i = 0; i < queries.Length; i++)
            {
                int a = queries[i][0];
                int b = queries[i][1];

                userMap.Union(a, b);

                result[i] = userMap.MaxSetSize;
            }

            return(result);
        }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 20
0
        /// <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);
        }
Exemplo n.º 21
0
        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 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);
                }
            }
        }
Exemplo n.º 23
0
    /*
     * Complete the 'kruskals' function below.
     *
     * The function is expected to return an INTEGER.
     * The function accepts WEIGHTED_INTEGER_GRAPH g as parameter.
     */

    /*
     * For the weighted graph, <name>:
     *
     * 1. The number of nodes is <name>Nodes.
     * 2. The number of edges is <name>Edges.
     * 3. An edge exists between <name>From[i] and <name>To[i]. The weight of the edge is <name>Weight[i].
     *
     */

    public static int kruskals(int gNodes, List <int> gFrom, List <int> gTo, List <int> gWeight)
    {
        var ds = new DisjointSets(gNodes);

        var edges = new Edge[gFrom.Count];

        for (var index = 0; index < gFrom.Count; index++)
        {
            edges[index] = new Edge
            {
                From   = gFrom[index],
                To     = gTo[index],
                Weight = gWeight[index]
            };
        }

        Array.Sort(edges);

        var edgesUsed = 0;
        var sum       = 0;

        foreach (var edge in edges)
        {
            if (edgesUsed == gNodes - 1)
            {
                break;
            }

            if (ds.Find(edge.From) == ds.Find(edge.To))
            {
                continue;
            }

            edgesUsed++;
            sum += edge.Weight;

            ds.Union(edge.From, edge.To);
        }

        return(sum);
    }
Exemplo n.º 24
0
        public MST <V> Execute()
        {
            var mst = new MST <V>();

            var orderedEdges = _g.AllEdges().OrderBy(e => e.Weight);

            var ds = new DisjointSets <Node <V> >();

            foreach (var edge in orderedEdges)
            {
                var head = ds.Find(edge.Head);
                var tail = ds.Find(edge.Tail);

                if (!head.Equals(tail))
                {
                    mst.Edges.Add(edge);
                    ds.Union(head, tail);
                }
            }

            return(mst);
        }
Exemplo n.º 25
0
        public void Union_ThrowsOnSecondElementNonExistent()
        {
            var sets = new DisjointSets <int>(new int[] { 1, 2 });

            Assert.That(() => sets.Union(1, 3), Throws.ArgumentException);
        }
Exemplo n.º 26
0
 /// <summary>
 /// Unifies two set elements.
 /// </summary>
 /// <param name="e1">a set element</param>
 /// <param name="e2">another set element</param>
 public void Union(T e1, T e2)
 {
     _impl.Union(_impl.FindSet(_index[e1]), _impl.FindSet(_index[e2]));
     _repShuffle[_impl.FindSet(_index[e2])] = _index[e2];
 }
Exemplo n.º 27
0
        /// <summary>
        /// Procedurally generates the 2-dimensional data for a maze with the dimensions set by the
        /// <see cref="MazeGenerator(int, int)"/> constructor.<para />
        /// Calling this method consecutively will always generate an entirely new maze but of same Rows by Cols
        /// dimensions of the given object instance. To change the dimensions, a new object must be instantiated.
        /// </summary>
        public void GenerateMaze()
        {
            int  visitedCells = 1;
            int  currCell     = rand.Next(CellNum);
            int  adjCell;
            bool adjacentFound;

            // Index - 0: above, 1: below, 2: left, 3: right
            // If adjacentCells[Index] = -1 then that adjacent cell does not exist.
            int[] adjCells = new int[Max_Adjacency];

            Stack <int> cellStack = new Stack <int>();

            while (visitedCells < CellNum)
            {
                adjCell       = -1;
                adjacentFound = false;

                if (currCell < Cols)
                {
                    adjCells[0] = -1;
                }
                else
                {
                    adjCells[0] = currCell - Cols;
                }

                if (currCell >= (CellNum - Cols))
                {
                    adjCells[1] = -1;
                }
                else
                {
                    adjCells[1] = currCell + Cols;
                }

                if (currCell % Cols == 0)
                {
                    adjCells[2] = -1;
                }
                else
                {
                    adjCells[2] = currCell - 1;
                }

                if ((currCell + 1) % Cols == 0)
                {
                    adjCells[3] = -1;
                }
                else
                {
                    adjCells[3] = currCell + 1;
                }

                for (int i = 0; i < adjCells.Length; ++i)
                {
                    if (adjCells[i] >= 0 &&
                        (sets.Find(currCell) != sets.Find(adjCells[i])))
                    {
                        adjacentFound = true;
                    }
                    else
                    {
                        adjCells[i] = -1;
                    }
                }

                if (adjacentFound)
                {
                    int wallIndex;
                    do
                    {
                        wallIndex = rand.Next(Max_Adjacency);
                        adjCell   = adjCells[wallIndex];
                    }while (adjCell < 0);

                    sets.Union(currCell, adjCell);

                    // Adjacent cell is - 0: above, 1: below, 2: left, 3: right
                    switch (wallIndex)
                    {
                    case 0:     // Connect currentCell with adjacentCell above.
                        grid[currCell] = new Cell(false, grid[currCell].belowWall, grid[currCell].leftWall, grid[currCell].rightWall);
                        grid[adjCell]  = new Cell(grid[adjCell].aboveWall, false, grid[adjCell].leftWall, grid[adjCell].rightWall);
                        break;

                    case 1:     // Connect currentCell with adjacentCell below.
                        grid[currCell] = new Cell(grid[currCell].aboveWall, false, grid[currCell].leftWall, grid[currCell].rightWall);
                        grid[adjCell]  = new Cell(false, grid[adjCell].belowWall, grid[adjCell].leftWall, grid[adjCell].rightWall);
                        break;

                    case 2:     // Connect currentCell with adjacentCell on left.
                        grid[currCell] = new Cell(grid[currCell].aboveWall, grid[currCell].belowWall, false, grid[currCell].rightWall);
                        grid[adjCell]  = new Cell(grid[adjCell].aboveWall, grid[adjCell].belowWall, grid[adjCell].leftWall, false);
                        break;

                    case 3:     // Connect currentCell with adjacentCell on right.
                        grid[currCell] = new Cell(grid[currCell].aboveWall, grid[currCell].belowWall, grid[currCell].leftWall, false);
                        grid[adjCell]  = new Cell(grid[adjCell].aboveWall, grid[adjCell].belowWall, false, grid[adjCell].rightWall);
                        break;

                    default:
                        Debug.LogError
                            ("GenerateMaze() error: invalid wallIndex value.");
                        break;
                    }

                    cellStack.Push(currCell);
                    currCell = adjCell;
                    ++visitedCells;
                }
                else
                {
                    if (cellStack.Count > 0)
                    {
                        currCell = cellStack.Pop();
                    }
                }
            }
        }
Exemplo n.º 28
0
        /// <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);
        }