├── LICENSE ├── PrimsAlgorithm ├── EMST.pde ├── PrimsAlgorithm.pde ├── animation_01.gif └── animation_02.gif └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nikolai Janakiev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PrimsAlgorithm/EMST.pde: -------------------------------------------------------------------------------- 1 | class EMST { 2 | // Input points 3 | ArrayList points; 4 | // Number of input points 5 | int n; 6 | // Resulting edges 7 | ArrayList edges; 8 | // Adjacency matrix 9 | float [][] graph; 10 | // Cost for each node 11 | float distances[]; 12 | // Store edges with shortest distances 13 | int p[]; 14 | // Store if node has been visited 15 | boolean visited[]; 16 | // Index of current node 17 | int current; 18 | // Index of total iterations 19 | int total; 20 | 21 | EMST(ArrayList points) { 22 | this.points = points; 23 | n = points.size(); 24 | graph = new float[n][n]; 25 | edges = new ArrayList(); 26 | 27 | // Distances from node 28 | distances = new float[n]; 29 | p = new int[n]; 30 | visited = new boolean[n]; 31 | 32 | // Fill adjacency matrix 33 | for (int i = 0; i < n; i++) { 34 | graph[i][i] = -1; 35 | for (int j = (i + 1); j < n; j++) { 36 | float distance = points.get(i).dist(points.get(j)); 37 | graph[i][j] = distance; 38 | graph[j][i] = distance; 39 | } 40 | } 41 | 42 | // Initialize 43 | for (int i = 0; i < n; i++) { 44 | visited[i] = false; 45 | p[i] = -1; 46 | distances[i] = MAX_FLOAT; 47 | } 48 | 49 | current = 0; 50 | total = 0; 51 | distances[current] = 0; 52 | visited[current] = true; 53 | } 54 | 55 | boolean update() { 56 | if (total >= n) { 57 | return false; 58 | } 59 | for (int i = 0; i < n; i++) { 60 | if (graph[current][i] >= 0 && !visited[i]) { 61 | if (distances[i] > graph[current][i]) { 62 | distances[i] = graph[current][i]; 63 | p[i] = current; 64 | } 65 | } 66 | } 67 | float minDistance = MAX_FLOAT; 68 | for (int i = 0; i < n; i++) { 69 | if (!visited[i] && distances[i] < minDistance) { 70 | minDistance = distances[i]; 71 | current = i; 72 | } 73 | } 74 | 75 | // Add new edge to spanning tree 76 | PVector p0 = points.get(current); 77 | PVector p1 = points.get(p[current]); 78 | edges.add(new Edge(p0, p1)); 79 | 80 | visited[current] = true; 81 | total++; 82 | 83 | return true; 84 | } 85 | 86 | void draw(float r) { 87 | strokeWeight(r*0.9); 88 | for (PVector p : points) { 89 | ellipse(p.x, p.y, r, r); 90 | } 91 | for (Edge e : edges) { 92 | line(e.p0.x, e.p0.y, e.p1.x, e.p1.y); 93 | } 94 | } 95 | } 96 | 97 | class Edge { 98 | PVector p0, p1; 99 | Edge(PVector p0, PVector p1) { 100 | this.p0 = p0; 101 | this.p1 = p1; 102 | } 103 | } -------------------------------------------------------------------------------- /PrimsAlgorithm/PrimsAlgorithm.pde: -------------------------------------------------------------------------------- 1 | ArrayList generateGrid(int n, float rOffset){ 2 | ArrayList points = new ArrayList(); 3 | float factor = 0.05; // border in percentage 4 | for(int i=0; i generateRandomPoints(int n){ 21 | ArrayList points = new ArrayList(); 22 | float factor = 0.05; // border in percentage 23 | for(int i=0; i points = generateRandomPoints(1000); 37 | //ArrayList points = generateGrid(10, 10); 38 | tree = new EMST(points); //<>// 39 | 40 | size(600, 600); 41 | stroke(0); 42 | fill(0); 43 | } 44 | 45 | void draw(){ 46 | background(255); 47 | tree.draw(2); 48 | 49 | if(!tree.update()){ 50 | lastFrameCount--; 51 | } 52 | 53 | if(saveFrames && lastFrameCount > 0){ 54 | saveFrame("frames/#####.png"); 55 | } 56 | } -------------------------------------------------------------------------------- /PrimsAlgorithm/animation_01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njanakiev/prims-algorithm/ae925e5384dd9574e5633d14e79293572555de04/PrimsAlgorithm/animation_01.gif -------------------------------------------------------------------------------- /PrimsAlgorithm/animation_02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/njanakiev/prims-algorithm/ae925e5384dd9574e5633d14e79293572555de04/PrimsAlgorithm/animation_02.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # prims-algorithm 2 | 3 | This is an implementation of [Prim's algorithm](https://en.wikipedia.org/wiki/Prim%27s_algorithm) in [Processing](https://processing.org/). The algorithm is used to calculate the [minimum spanning tree](https://en.wikipedia.org/wiki/Minimum_spanning_tree) of a given undirected connected graph where each edge has a given weight. The minimum spanning tree is a [spanning tree](https://en.wikipedia.org/wiki/Spanning_tree) where the sum of the edge weights is as small as possible and where the graph has no cycles (edges forming closed loops). Another algorithm for calculating the minimum spanning tree is [Kruskal's algorithm](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm). 4 | 5 | The following animations show the process of generating the [Euclidean minimum spanning tree](https://en.wikipedia.org/wiki/Euclidean_minimum_spanning_tree) (EMST) of a set of input points. The EMST is a minimum spanning tree, where the nodes are points in the plane and the weights of the edges are the distances between the points. An efficient algorithm for EMST is Kruskal's algorithm combined with the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) which reduces the number of edges to the edges in the delaunay triangulation of the given input points. 6 | 7 | ![Animation_01](PrimsAlgorithm/animation_01.gif) 8 | 9 | ![Animation_02](PrimsAlgorithm/animation_02.gif) 10 | --------------------------------------------------------------------------------