最小生成ツリーアルゴリズム——KruskyalアルゴリズムJavaを実装します.
3959 ワード
暇があっても大丈夫です.アルゴリズムを書いて、ツリーを最小に生成するKruskyalアルゴリズムは、Primアルゴリズムより少し面倒です.
package trees;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
/**
* Kruskal ,
* For a connected weighted graph G, a spanning tree T of G is constructed as follows:
* For the first edge e1 of T, we select any edge of G of minimum weight and for the second
* edge e2 of T, we select any remaining edge of G of minimum weight. For the third edge e3
* of T,we choose any remaining edge of G of minimum weight that dose not produce a cycle with
* the previousely selected edges. We continue in this manner until a spanning tree is produced.
* @author xhw
*
*/
public class KruskalMinimumSpanningTree {
/**
* @param args
*/
public static void main(String[] args) {
double graph[][]={{0,1,4,4,5},
{1,0,3,7,5},
{4,3,0,6,Double.MAX_VALUE},
{4,7,6,0,2},
{5,5,Double.MAX_VALUE,2,0}};
double tree[][]=minimumSpanningTree(graph);
if(tree==null)
{
System.out.println("no spanning tree");
System.exit(0);
}
PriorityQueue<Edge> edgeList=generateEdgeList(tree);
for(Edge e:edgeList)
{
System.out.println(e);
}
}
/**
* ( i=j, 0, i j Double.max), ,
* @param graph
* @return
*/
public static double[][] minimumSpanningTree(double[][] graph) {
int rlength=graph.length;
int clength=graph[0].length;
PriorityQueue<Edge> edgeList;
edgeList=generateEdgeList(graph);
double tree[][]=new double[rlength][clength];
/**
* tree
*/
for(int i=0;i<rlength;i++)
{
for(int j=0;j<clength;j++)
{
if(i==j)
tree[i][j]=0;
else
tree[i][j]=Double.MAX_VALUE;
}
}
/**
* map , , , , ,
*/
Map<Integer,Set<Integer>> map=new HashMap<Integer,Set<Integer>>();
int edgeCount=0;
while(edgeCount<rlength-1&&!edgeList.isEmpty())
{
Edge e=edgeList.poll();
Set<Integer> setU=map.get(e.u);
Set<Integer> setV=map.get(e.v);
//System.out.println(e);
//
if(setU==null&&setV==null)
{
Set<Integer> set=new HashSet<Integer>();
set.add(e.u);
set.add(e.v);
map.put(e.u, set);
map.put(e.v, set);
}// , ,
else if(setU==null&&setV!=null)
{
map.put(e.u, setV);
setV.add(e.u);
}
else if(setU!=null&&setV==null)
{
map.put(e.v, setU);
setU.add(e.v);
}// ,
else if(setU!=setV)
{
for(int v:setV)
{
map.put(v, setU);
}
setU.addAll(setV);
}// , ,
else
{
continue;
}
tree[e.u][e.v]=e.weight;
tree[e.v][e.u]=e.weight;
edgeCount++;
}
if(edgeCount==rlength-1)
return tree;
else
return null;
}
/**
*
* @param graph
* @return
*/
private static PriorityQueue<Edge> generateEdgeList(double[][] graph) {
PriorityQueue<Edge> edgeList=new PriorityQueue<Edge>();
int rlength=graph.length;
int clength=graph[0].length;
for(int i=0;i<rlength;i++)
{
for(int j=i+1;j<clength;j++ )
{
if(graph[i][j]>0&graph[i][j]<Double.MAX_VALUE)
{
Edge e=new Edge(i,j,graph[i][j]);
edgeList.add(e);
}
}
}
return edgeList;
}
}
class Edge implements Comparable<Edge>
{
int u;
int v;
double weight;
public Edge(int u, int v, double weight) {
super();
this.u = u;
this.v = v;
this.weight = weight;
}
@Override
public int compareTo(Edge e) {
if(e.weight==weight)
return 0;
else if(weight<e.weight)
return -1;
else
return 1;
}
public String toString()
{
return u+"--"+v+":"+weight;
}
}