Help me please with Boruvka algorithm for creating a minnimum-spanning tree. I wrote code of an algorithm looking on example given by Sedgwick but apparently had done a bunch of nonsense, because the algorithm never goes out of the loop. Tell me please where I have done mistakes and how to fix them, I’ll be very grateful. Code below.
PS. sorry for my english:)
public class Boruvka
{
private Edge[] mst;
/**
* Edges not yet discarded and not yet in the MST
*/
private Edge[] wannabes;
/**
* Each component's nearest neighbor with find component numbers as indices
*/
private Edge[] neighbors;
/**
* Graph representation on which we are searching for MST
*/
private Graph g;
/**
*
*/
private UnionFind uf;
// constructors and methods
/**
* constructor
* @param G Graph
*/
public Boruvka(Graph G) {
this.g = G;
}
/**
* Boruvka's algorithm
*
*
* @return minimal spanning tree - edges that form it
*/
public Edge[] BoruvkaMSTalg()
{
Edge hlpEdge = new Edge(g.getMaxWeight(), 0, 0);
this.uf = new UnionFind(g.getCountVerteces());
this.wannabes = new Edge[this.g.getCountEdges()];
/**
* Get all edges from the graph G to the array edges
*/
for (int i=0; i < g.getCountEdges(); i++)
this.wannabes[i] = g.getEdgeAt(i);
this.neighbors = new Edge[this.g.getCountVerteces()];
this.mst = new Edge[this.g.getCountVerteces()+1];
/**
* index, used to store those edges being saved for the next phase
*/
int nxtPhase;
int k=1;
for (int i=this.g.getCountEdges(); i!=0; i=nxtPhase)
{
int l, m, n;
for (int o=0; o<this.g.getCountVerteces(); o++)
this.neighbors[o] = hlpEdge;
for (n=0, nxtPhase=0; n<i; n++) {
Edge e = this.wannabes[n];
l = this.uf.find(e.getSVIndex()-1);
m = this.uf.find(e.getDVIndex()-1);
if ( l==m )
continue;
if ( e.getWeight() < this.neighbors[l].getWeight() )
this.neighbors[l] = e;
if ( e.getWeight() < this.neighbors[m].getWeight() )
this.neighbors[m] = e;
this.wannabes[nxtPhase++] = e;
}
for (n=0; n<this.g.getCountVerteces(); n++)
if ( this.neighbors[n] != hlpEdge ) {
l = this.neighbors[n].getSVIndex();
m = this.neighbors[n].getDVIndex();
if ( !this.uf.find(l,m) ) {
this.uf.unite(l,m);
this.mst[k++] = this.neighbors[n];
}
}
}
System.out.println("MST by Boruvka successful");
return this.mst;
}
}
I wrote this code looking at code given by Sedgwick in his “Algorithms in java. Part 5 : Graph Algorithm”. And here is his code:
class GraphMST
{ private UF uf;
private Edge[] a, b, mst;
GraphMST(Graph G)
{ Edge z = new Edge(0, 0, maxWT);
uf = new UF(G.V());
a = GraphUtilities.edges(G);
b = new Edge[G.V()]; mst = new Edge[G.V()+1];
int N, k = 1;
for (int E = G.E(); E != 0; E = N)
{ int h, i, j;
for (int t = 0; t < G.V(); t++) b[t] = z;
for (h = 0, N = 0; h < E; h++)
{ Edge e = a[h];
i = uf.find(e.v()); j = uf.find(e.w());
if (i == j) continue;
if (e.wt() < b[i].wt()) b[i] = e;
if (e.wt() < b[j].wt()) b[j] = e;
a[N++] = e;
}
for (h = 0; h < G.V(); h++)
if (b[h] != z)
if (!uf.find(i = b[h].v(), j = b[h].w()))
{ uf.unite(i, j); mst[k++] = b[h]; }
}
}
}
Help me please to find differences between it’s and mine and to fix them.
PS. i’m sorry for my english.
Here’s a start.
Consider the
forloop with this control statement:The only way out of this loop is for
ito be0. The only place thatigets changed is by the loop advancing statementThe only place that
nxtPhasegets changed is hereSo as written, the only way out of the loop is for
nxtPhaseto go through all possibleintvalues (I don’t know the default overflow behaviour of Java so don’t know what will actually happen when it gets to2^32-1). This is probably not what you intend.