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)); }
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; }
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)); }
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); }
/** * 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; }
public List<LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum) { return DelaunayHelpers.Kruskal(DelaunayHelpers.DelaunayLinesForEdges(Edges), type); }
/** * 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); }
/** * 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); }
/// <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); }
public List<LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum) { var edges = SelectNonIntersectingEdges(Edges); var segments = DelauneyLinesForEdges(edges); return Kruskal.KruskalTree(segments, type); }
public List <LineSegment> SpanningTree(KruskalType type = KruskalType.Minimum) { return(DelaunayHelpers.Kruskal(DelaunayHelpers.DelaunayLinesForEdges(Edges), type)); }
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); }