Skip to content

Commit 126305a

Browse files
committed
Polish Boruvkas algorithm
1 parent 0d62201 commit 126305a

File tree

1 file changed

+32
-55
lines changed
  • src/main/java/com/williamfiset/algorithms/graphtheory

1 file changed

+32
-55
lines changed

src/main/java/com/williamfiset/algorithms/graphtheory/Boruvkas.java

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
/** WIP */
21
package com.williamfiset.algorithms.graphtheory;
32

43
import java.util.*;
54

65
public class Boruvkas {
76

8-
static class Edge {
7+
static class Edge implements Comparable<Edge> {
98
int u, v, cost;
109

1110
public Edge(int u, int v, int cost) {
@@ -14,11 +13,12 @@ public Edge(int u, int v, int cost) {
1413
this.cost = cost;
1514
}
1615

16+
@Override
1717
public String toString() {
1818
return String.format("%d %d, cost: %d", u, v, cost);
1919
}
2020

21-
// @Override
21+
@Override
2222
public int compareTo(Edge other) {
2323
int cmp = cost - other.cost;
2424
// Break ties by picking lexicographically smallest edge pair.
@@ -32,7 +32,7 @@ public int compareTo(Edge other) {
3232
}
3333

3434
// Inputs
35-
private final int n, m; // Num nodes, num edges
35+
private final int n; // Number of nodes
3636
private final Edge[] graph; // Edge list
3737

3838
// Internal
@@ -43,11 +43,10 @@ public int compareTo(Edge other) {
4343
private long minCostSum;
4444
private List<Edge> mst;
4545

46-
public Boruvkas(int n, int m, Edge[] graph) {
46+
public Boruvkas(int n, Edge[] graph) {
4747
if (graph == null) throw new IllegalArgumentException();
4848
this.graph = graph;
4949
this.n = n;
50-
this.m = m;
5150
}
5251

5352
// Returns the edges used in finding the minimum spanning tree, or returns
@@ -69,62 +68,43 @@ private void solve() {
6968
if (solved) return;
7069

7170
mst = new ArrayList<>();
72-
7371
UnionFind uf = new UnionFind(n);
7472

75-
int[] cheapest = new int[n];
76-
Arrays.fill(cheapest, -1);
77-
78-
// Repeat at most log(n) times or until we have a complete spanning tree.
79-
// for(int t = 1; t < N && index < n - 1; t = t + t) {
80-
// for(long t = 1; t <= n && mst.size() != n-1; t = t << 1) {
81-
for (; mst.size() != n - 1; ) {
82-
83-
// TODO: Remove
84-
Arrays.fill(cheapest, -1);
85-
boolean stop = true;
86-
87-
for (int i = 0; i < graph.length; i++) {
88-
Edge e = graph[i];
89-
if (e.u == e.v) continue;
90-
int uc = uf.id[e.u], vc = uf.id[e.v];
91-
if (uc == vc) continue;
92-
// if (cheapest[vc] == -1 || e.compareTo(graph[cheapest[vc]]) < 0) { stop = false;
93-
// cheapest[vc] = i; }
94-
// if (cheapest[uc] == -1 || e.compareTo(graph[cheapest[uc]]) < 0) { stop = false;
95-
// cheapest[uc] = i; }
96-
if (cheapest[vc] == -1 || e.cost < graph[cheapest[vc]].cost) {
97-
stop = false;
98-
cheapest[vc] = i;
73+
while (uf.components > 1) {
74+
Edge[] cheapest = new Edge[n];
75+
76+
// Find the cheapest edge for each component
77+
for (Edge e : graph) {
78+
int root1 = uf.find(e.u);
79+
int root2 = uf.find(e.v);
80+
if (root1 == root2) continue;
81+
82+
if (cheapest[root1] == null || e.cost < cheapest[root1].cost) {
83+
cheapest[root1] = e;
9984
}
100-
if (cheapest[uc] == -1 || e.cost < graph[cheapest[uc]].cost) {
101-
stop = false;
102-
cheapest[uc] = i;
85+
if (cheapest[root2] == null || e.cost < cheapest[root2].cost) {
86+
cheapest[root2] = e;
10387
}
10488
}
10589

106-
if (stop) break;
107-
90+
// Add the cheapest edges to the MST
10891
for (int i = 0; i < n; i++) {
109-
if (cheapest[i] == -1) continue;
110-
Edge e = graph[cheapest[i]];
111-
// cheapest[i] = -1;
112-
if (uf.connected(e.u, e.v)) continue;
113-
114-
mst.add(e);
115-
minCostSum += e.cost;
116-
uf.union(e.u, e.v);
117-
118-
// TODO(williamfiset): Optimization is to remove e from graph.
92+
Edge e = cheapest[i];
93+
if (e == null) {
94+
continue;
95+
}
96+
int root1 = uf.find(e.u);
97+
int root2 = uf.find(e.v);
98+
if (root1 != root2) {
99+
uf.union(root1, root2);
100+
mst.add(e);
101+
minCostSum += e.cost;
102+
}
119103
}
120104
}
121105

122-
// if ( (index==n-1) != (uf.size(0) == n) ) throw new NullPointerException();
123-
124-
mstExists = (mst.size() == n - 1); // (uf.size(0) == n);
106+
mstExists = (mst.size() == n - 1);
125107
solved = true;
126-
127-
// if (!check()) throw new IllegalStateException();
128108
}
129109

130110
private boolean check() {
@@ -200,7 +180,7 @@ public static void main(String[] args) {
200180
g[i++] = new Edge(7, 8, 6);
201181
g[i++] = new Edge(9, 8, 0);
202182

203-
Boruvkas solver = new Boruvkas(n, m, g);
183+
Boruvkas solver = new Boruvkas(n, g);
204184

205185
Long ans = solver.getMstCost();
206186
if (ans != null) {
@@ -211,9 +191,6 @@ public static void main(String[] args) {
211191
} else {
212192
System.out.println("No MST exists");
213193
}
214-
215-
// System.out.println(solver.solve(g, n));
216-
217194
}
218195

219196
// Union find data structure

0 commit comments

Comments
 (0)