Ejemplo n.º 1
0
        public List <LineSegment> SpanningTree(KruskalType type = KruskalType.MINIMUM /*, BitmapData keepOutMask = null*/)
        {
            List <Edge>        edges    = DelaunayHelpers.SelectNonIntersectingEdges(/*keepOutMask,*/ _edges);
            List <LineSegment> segments = DelaunayHelpers.DelaunayLinesForEdges(edges);

            return(DelaunayHelpers.Kruskal(segments, type));
        }
Ejemplo n.º 2
0
        public static List<LineSegment> KruskalTree(List<LineSegment> segments, KruskalType type= KruskalType.Minimum) {
            var nodes = new Dictionary<Point, Node>();
            var mst = new List<LineSegment>();
            switch (type) {
                // note that the compare functions are the reverse of what you'd expect
                // because (see below) we traverse the lineSegments in reverse order for speed
                case KruskalType.Maximum:
                    segments.Sort(LineSegment.CompareLengths);
                    break;
                default:
                    segments.Sort(LineSegment.CompareLengthsMax);
                    break;
            }
            for (int i = segments.Count; --i > -1; ) {
                var segment = segments[i];
                Node rootOfSet0 = null;
                Node node0;
                if (!nodes.ContainsKey(segment.P0)) {
                    node0 = new Node();
                    // intialize the node:
                    rootOfSet0 = node0.Parent = node0;
                    node0.TreeSize = 1;

                    nodes[segment.P0] = node0;
                } else {
                    node0 = nodes[segment.P0];
                    rootOfSet0 = Node.Find(node0);
                }
                Node node1;
                Node rootOfSet1;
                if (!nodes.ContainsKey(segment.P1)) {
                    node1 = new Node();
                    // intialize the node:
                    rootOfSet1 = node1.Parent = node1;
                    node1.TreeSize = 1;
                    nodes[segment.P1] = node1;
                } else {
                    node1 = nodes[segment.P1];
                    rootOfSet1 = Node.Find(node1);
                }

                if (rootOfSet0 != rootOfSet1) { // nodes not in same set
                    mst.Add(segment);

                    // merge the two sets:
                    var treeSize0 = rootOfSet0.TreeSize;
                    var treeSize1 = rootOfSet1.TreeSize;
                    if (treeSize0 >= treeSize1) {
                        // set0 absorbs set1:
                        rootOfSet1.Parent = rootOfSet0;
                        rootOfSet0.TreeSize += treeSize1;
                    } else {
                        // set1 absorbs set0:
                        rootOfSet0.Parent = rootOfSet1;
                        rootOfSet1.TreeSize += treeSize0;
                    }
                }
            }
            return mst;
        }
Ejemplo n.º 3
0
        public List <LineSegment> SpanningTree(KruskalType type = KruskalType.MINIMUM)
        {
            List <Edge>        edges        = DelaunayHelpers.SelectNonIntersectingEdges(_edges);
            List <LineSegment> lineSegments = DelaunayHelpers.DelaunayLinesForEdges(edges);

            return(DelaunayHelpers.Kruskal(lineSegments, type));
        }
Ejemplo n.º 4
0
		public List<LineSegment> SpanningTree (KruskalType type = KruskalType.MINIMUM/*, BitmapData keepOutMask = null*/)
		{
			List<Edge> edges = DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges);
			List<LineSegment> segments = DelaunayHelpers.DelaunayLinesForEdges (edges);
			return DelaunayHelpers.Kruskal (segments, type);
		}
Ejemplo n.º 5
0
        /**
        *  Kruskal's spanning tree algorithm with union-find
         * Skiena: The Algorithm Design Manual, p. 196ff
         * Note: the sites are implied: they consist of the end points of the line segments
        */
        public static List<LineSegment> Kruskal(List<LineSegment> lineSegments, KruskalType type = KruskalType.Minimum)
        {
            var nodes = new Dictionary<Vector2?, Node>();
            var mst = new List<LineSegment>();
            var nodePool = Node.Pool;

            switch (type)
            {
                // note that the compare functions are the reverse of what you'd expect
                // because (see below) we traverse the lineSegments in reverse order for speed
                case KruskalType.Maximum:
                    lineSegments.Sort(LineSegment.CompareLengths);
                    break;
                default:
                    lineSegments.Sort(LineSegment.CompareLengths_MAX);
                    break;
            }

            for (var i = lineSegments.Count; --i > -1; )
            {
                var lineSegment = lineSegments[i];

                Node node0;
                Node rootOfSet0;
                if (!nodes.ContainsKey(lineSegment.P0))
                {
                    node0 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet0 = node0.Parent = node0;
                    node0.TreeSize = 1;

                    nodes[lineSegment.P0] = node0;
                }
                else
                {
                    node0 = nodes[lineSegment.P0];
                    rootOfSet0 = Find(node0);
                }

                Node node1;
                Node rootOfSet1;
                if (!nodes.ContainsKey(lineSegment.P1))
                {
                    node1 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet1 = node1.Parent = node1;
                    node1.TreeSize = 1;

                    nodes[lineSegment.P1] = node1;
                }
                else
                {
                    node1 = nodes[lineSegment.P1];
                    rootOfSet1 = Find(node1);
                }

                if (rootOfSet0 == rootOfSet1) continue; // nodes not in same set

                mst.Add(lineSegment);

                // merge the two sets:
                var treeSize0 = rootOfSet0.TreeSize;
                var treeSize1 = rootOfSet1.TreeSize;

                if (treeSize0 >= treeSize1)
                {
                    // set0 absorbs set1:
                    rootOfSet1.Parent = rootOfSet0;
                    rootOfSet0.TreeSize += treeSize1;
                }

                else
                {
                    // set1 absorbs set0:
                    rootOfSet0.Parent = rootOfSet1;
                    rootOfSet1.TreeSize += treeSize0;
                }
            }

            foreach (var node in nodes.Values)
            {
                nodePool.Push(node);
            }

            return mst;
        }
        /**
        *  Kruskal's spanning tree algorithm with union-find
         * Skiena: The Algorithm Design Manual, p. 196ff
         * Note: the sites are implied: they consist of the end points of the line segments
        */
        public static List<LineSegment> Kruskal(List<LineSegment> lineSegments, KruskalType type = KruskalType.MINIMUM)
        {
            Dictionary<Nullable<Vector2>,Node> nodes = new Dictionary<Nullable<Vector2>,Node> ();
            List<LineSegment> mst = new List<LineSegment> ();
            Stack<Node> nodePool = Node.pool;

            switch (type) {
            // note that the compare functions are the reverse of what you'd expect
            // because (see below) we traverse the lineSegments in reverse order for speed
            case KruskalType.MAXIMUM:
                lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {
                    return LineSegment.CompareLengths (l1, l2);
                });
                break;
            default:
                lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {
                    return LineSegment.CompareLengths_MAX (l1, l2);
                });
                break;
            }

            for (int i = lineSegments.Count; --i > -1;) {
                LineSegment lineSegment = lineSegments [i];

                Node node0 = null;
                Node rootOfSet0;
                if (!nodes.ContainsKey (lineSegment.p0)) {
                    node0 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();
                    // intialize the node:
                    rootOfSet0 = node0.parent = node0;
                    node0.treeSize = 1;

                    nodes [lineSegment.p0] = node0;
                } else {
                    node0 = nodes [lineSegment.p0];
                    rootOfSet0 = Find (node0);
                }

                Node node1 = null;
                Node rootOfSet1;
                if (!nodes.ContainsKey (lineSegment.p1)) {
                    node1 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();
                    // intialize the node:
                    rootOfSet1 = node1.parent = node1;
                    node1.treeSize = 1;

                    nodes [lineSegment.p1] = node1;
                } else {
                    node1 = nodes [lineSegment.p1];
                    rootOfSet1 = Find (node1);
                }

                if (rootOfSet0 != rootOfSet1) {	// nodes not in same set
                    mst.Add (lineSegment);

                    // merge the two sets:
                    int treeSize0 = rootOfSet0.treeSize;
                    int treeSize1 = rootOfSet1.treeSize;
                    if (treeSize0 >= treeSize1) {
                        // set0 absorbs set1:
                        rootOfSet1.parent = rootOfSet0;
                        rootOfSet0.treeSize += treeSize1;
                    } else {
                        // set1 absorbs set0:
                        rootOfSet0.parent = rootOfSet1;
                        rootOfSet1.treeSize += treeSize0;
                    }
                }
            }
            foreach (Node node in nodes.Values) {
                nodePool.Push (node);
            }

            return mst;
        }
Ejemplo n.º 7
0
 public List<LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum)
 {
     return DelaunayHelpers.Kruskal(DelaunayHelpers.DelaunayLinesForEdges(Edges), type);
 }
Ejemplo n.º 8
0
        /**
         *  Kruskal's spanning tree algorithm with union-find
         * Skiena: The Algorithm Design Manual, p. 196ff
         * Note: the sites are implied: they consist of the end points of the line segments
         */
        public static List <LineSegment> Kruskal(List <LineSegment> lineSegments, KruskalType type = KruskalType.MINIMUM)
        {
            Dictionary <Nullable <Vector2>, Node> nodes = new Dictionary <Nullable <Vector2>, Node>();
            List <LineSegment> mst      = new List <LineSegment>();
            Stack <Node>       nodePool = Node.pool;

            switch (type)
            {
            // note that the compare functions are the reverse of what you'd expect
            // because (see below) we traverse the lineSegments in reverse order for speed
            case KruskalType.MAXIMUM:
                lineSegments.Sort(delegate(LineSegment l1, LineSegment l2)
                {
                    return(LineSegment.CompareLengths(l1, l2));
                });
                break;

            default:
                lineSegments.Sort(delegate(LineSegment l1, LineSegment l2)
                {
                    return(LineSegment.CompareLengths_MAX(l1, l2));
                });
                break;
            }

            for (int i = lineSegments.Count; --i > -1;)
            {
                LineSegment lineSegment = lineSegments[i];

                Node node0 = null;
                Node rootOfSet0;
                if (!nodes.ContainsKey(lineSegment.p0))
                {
                    node0 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet0     = node0.parent = node0;
                    node0.treeSize = 1;

                    nodes[lineSegment.p0] = node0;
                }
                else
                {
                    node0      = nodes[lineSegment.p0];
                    rootOfSet0 = Find(node0);
                }

                Node node1 = null;
                Node rootOfSet1;
                if (!nodes.ContainsKey(lineSegment.p1))
                {
                    node1 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet1     = node1.parent = node1;
                    node1.treeSize = 1;

                    nodes[lineSegment.p1] = node1;
                }
                else
                {
                    node1      = nodes[lineSegment.p1];
                    rootOfSet1 = Find(node1);
                }

                if (rootOfSet0 != rootOfSet1)
                {   // nodes not in same set
                    mst.Add(lineSegment);

                    // merge the two sets:
                    int treeSize0 = rootOfSet0.treeSize;
                    int treeSize1 = rootOfSet1.treeSize;
                    if (treeSize0 >= treeSize1)
                    {
                        // set0 absorbs set1:
                        rootOfSet1.parent    = rootOfSet0;
                        rootOfSet0.treeSize += treeSize1;
                    }
                    else
                    {
                        // set1 absorbs set0:
                        rootOfSet0.parent    = rootOfSet1;
                        rootOfSet1.treeSize += treeSize0;
                    }
                }
            }
            foreach (Node node in nodes.Values)
            {
                nodePool.Push(node);
            }

            return(mst);
        }
Ejemplo n.º 9
0
        /**
         *  Kruskal's spanning tree algorithm with union-find
         * Skiena: The Algorithm Design Manual, p. 196ff
         * Note: the sites are implied: they consist of the end points of the line segments
         */
        public static List <LineSegment> Kruskal(List <LineSegment> lineSegments, KruskalType type = KruskalType.Minimum)
        {
            var nodes    = new Dictionary <Vector2?, Node>();
            var mst      = new List <LineSegment>();
            var nodePool = Node.Pool;

            switch (type)
            {
            // note that the compare functions are the reverse of what you'd expect
            // because (see below) we traverse the lineSegments in reverse order for speed
            case KruskalType.Maximum:
                lineSegments.Sort(LineSegment.CompareLengths);
                break;

            default:
                lineSegments.Sort(LineSegment.CompareLengths_MAX);
                break;
            }

            for (var i = lineSegments.Count; --i > -1;)
            {
                var lineSegment = lineSegments[i];

                Node node0;
                Node rootOfSet0;
                if (!nodes.ContainsKey(lineSegment.P0))
                {
                    node0 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet0     = node0.Parent = node0;
                    node0.TreeSize = 1;

                    nodes[lineSegment.P0] = node0;
                }
                else
                {
                    node0      = nodes[lineSegment.P0];
                    rootOfSet0 = Find(node0);
                }

                Node node1;
                Node rootOfSet1;
                if (!nodes.ContainsKey(lineSegment.P1))
                {
                    node1 = nodePool.Count > 0 ? nodePool.Pop() : new Node();
                    // intialize the node:
                    rootOfSet1     = node1.Parent = node1;
                    node1.TreeSize = 1;

                    nodes[lineSegment.P1] = node1;
                }
                else
                {
                    node1      = nodes[lineSegment.P1];
                    rootOfSet1 = Find(node1);
                }

                if (rootOfSet0 == rootOfSet1)
                {
                    continue;                           // nodes not in same set
                }
                mst.Add(lineSegment);

                // merge the two sets:
                var treeSize0 = rootOfSet0.TreeSize;
                var treeSize1 = rootOfSet1.TreeSize;

                if (treeSize0 >= treeSize1)
                {
                    // set0 absorbs set1:
                    rootOfSet1.Parent    = rootOfSet0;
                    rootOfSet0.TreeSize += treeSize1;
                }

                else
                {
                    // set1 absorbs set0:
                    rootOfSet0.Parent    = rootOfSet1;
                    rootOfSet1.TreeSize += treeSize0;
                }
            }

            foreach (var node in nodes.Values)
            {
                nodePool.Push(node);
            }

            return(mst);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Algoritmo de Kruskal com diversas implementações.
        /// </summary>
        /// <param name="implementationType">Tipo de implemantação que será usada para executar o algoritmo</param>
        /// <returns></returns>
        public int Kruskal(KruskalType implementationType)
        {
            //Declaração de variáveis auxiliares
            int minimumSpaningTreeCost = 0;

            //IUnionFind é uma interface, sua implementação será escolhida no swich abaixo
            IUnionFind unionFind = null;

            //Verifica qual é o tipo de implementação do kruskal foi escolhida e executa as ações condizentes
            switch (implementationType)
            {
            case KruskalType.LinkedListUFHeapSort:

                //Union Find implementado com listas encadeadas
                unionFind = new UnionFindLL(this.numberOfVertices);

                //Faz o sorting com o HeapSort (in place)
                Sorting.Heap <Edge> .HeapSort(ref graphEdges);

                break;

            case KruskalType.TreeUFHeapSort:

                //Union Find implementado com arvores
                unionFind = new UnionFindT(this.numberOfVertices);

                //Faz o sorting com o HeapSort (in place)
                Sorting.Heap <Edge> .HeapSort(ref graphEdges);

                break;

            case KruskalType.LinkedListUFCountingSort:

                //Union Find implementado com listas encadeadas
                unionFind = new UnionFindLL(this.numberOfVertices);

                //Faz o sorting com o CountingSort
                graphEdges = Sorting.Sorting <Edge> .CountingSort(graphEdges, this.maxWeight);

                break;

            case KruskalType.TreeUFCountingSort:

                //Union Find implementado com arvores
                unionFind = new UnionFindT(this.numberOfVertices);

                //Faz o sorting com o CountingSort
                graphEdges = Sorting.Sorting <Edge> .CountingSort(graphEdges, this.maxWeight);

                break;

            default:

                throw new ArgumentException("Tipo de Kruskal não especificado.");
            }

            //Percorre a lista ordenada de Arestas.
            //Termina o looping quando todos os vértices já tiverem sido colocados na arvore geradora mínima.
            int i = 1;
            int j = 0;

            while (i < this.numberOfVertices)
            {
                //Decobre os conjuntos aos quais os vértices pertencem
                int set1 = unionFind.Find(graphEdges[j].Item2.vertexTo);
                int set2 = unionFind.Find(graphEdges[j].Item2.vertexFrom);

                //Verifica se os vértices pertencem ao mesmo grupo (forma ciclo)
                if (set1 != set2)
                {
                    //Soma o risco da aresta ao risco total da arvore geradora mínima
                    minimumSpaningTreeCost += graphEdges[j].Item1;
                    //Une os conjuntos nos quais estão os vértices da aresta que foi adicionada na árvore geradora mínima
                    unionFind.Union(set1, set2);
                    i++;
                }

                j++;
            }

            return(minimumSpaningTreeCost);
        }
Ejemplo n.º 11
0
 public List<LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum) {
     var edges = SelectNonIntersectingEdges(Edges);
     var segments = DelauneyLinesForEdges(edges);
     return Kruskal.KruskalTree(segments, type);
 }
Ejemplo n.º 12
0
 public List <LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum)
 {
     return(DelaunayHelpers.Kruskal(DelaunayHelpers.DelaunayLinesForEdges(Edges), type));
 }
Ejemplo n.º 13
0
        public static List <LineSegment> Kruskal(List <LineSegment> lineSegments, KruskalType type = KruskalType.MINIMUM)
        {
            Dictionary <Vector2?, Node> dictionary = new Dictionary <Vector2?, Node>();
            List <LineSegment>          list       = new List <LineSegment>();
            Stack <Node> pool = Node.pool;

            if (type == KruskalType.MAXIMUM)
            {
                lineSegments.Sort((LineSegment l1, LineSegment l2) => LineSegment.CompareLengths(l1, l2));
            }
            else
            {
                lineSegments.Sort((LineSegment l1, LineSegment l2) => LineSegment.CompareLengths_MAX(l1, l2));
            }
            int num = lineSegments.Count;

            while (--num > -1)
            {
                LineSegment lineSegment = lineSegments[num];
                Node        node        = null;
                Node        node2;
                if (!dictionary.ContainsKey(lineSegment.p0))
                {
                    node          = ((pool.Count <= 0) ? new Node() : pool.Pop());
                    node2         = (node.parent = node);
                    node.treeSize = 1;
                    dictionary[lineSegment.p0] = node;
                }
                else
                {
                    node  = dictionary[lineSegment.p0];
                    node2 = Find(node);
                }
                Node node3 = null;
                Node node4;
                if (!dictionary.ContainsKey(lineSegment.p1))
                {
                    node3                      = ((pool.Count <= 0) ? new Node() : pool.Pop());
                    node4                      = (node3.parent = node3);
                    node3.treeSize             = 1;
                    dictionary[lineSegment.p1] = node3;
                }
                else
                {
                    node3 = dictionary[lineSegment.p1];
                    node4 = Find(node3);
                }
                if (node2 != node4)
                {
                    list.Add(lineSegment);
                    int treeSize  = node2.treeSize;
                    int treeSize2 = node4.treeSize;
                    if (treeSize >= treeSize2)
                    {
                        node4.parent    = node2;
                        node2.treeSize += treeSize2;
                    }
                    else
                    {
                        node2.parent    = node4;
                        node4.treeSize += treeSize;
                    }
                }
            }
            foreach (Node value in dictionary.Values)
            {
                pool.Push(value);
            }
            return(list);
        }