用于最小生成树的Prim算法实现
来源:互联网 发布:36o隐私保险箱数据恢复 编辑:程序博客网 时间:2024/06/04 18:53
Prim算法,同Kruskal算法一样,也是解决最小生成树的算法。在讲这个算法前,我们先来看看其他的一些概念。
什么是割?在无向图中,割指的是对图的一种划分。当一条边(u,v)的一个顶点属于S,另一个顶点属于V-S,则我们称(u,v)边通过割(S,V-S)。如果一个边的集合A中没有任何一条边通过割,则我们称该割不妨害边集A。如果某条边的权值在通过某个割的所有边中是最小的,则称该边是通过该割的一条轻边。
Prim算法的基本思想就是不断的寻找通过一条割的轻边,这个割是指当前最小生成树所组成的点集S和图中不在最小生成树中的点集(V-S)所形成的一种图的划分,然后将所找到的轻边添加到最小生成树中。我们使用最小优先队列来快速的寻找通过某个割的轻边。当然,我们在寻找轻边的时候要检查该边的两个顶点是否已经在最小生成树中,如果在的话,我们就不需要再将这条边添加到最小生成树的边集了,因为这两个端点已经是连通着的了。
代码实现如下所示:
package com.chapter4;
//用于解决最小生成树问题的Prim算法(延时版本)
import java.util.Queue;
import java.util.LinkedList;
public class LazyPrimMST {
privateQueue<Edge> mst;
private boolean[]marked;
private doubletotalweight;
privateMinPriorityQueue<Edge> mpq;
publicLazyPrimMST(EdgeWeightedGraph G)
{
int V=G.V();
mst=newLinkedList<Edge>();
marked=newboolean[V];
mpq=newMinPriorityQueue<Edge>();
for(inti=0;i<V;i++)
{
if(!marked[i])
prim(G,i);
}
}
private voidprim(EdgeWeightedGraph G,int s)
{
scan(G,s);
while(!mpq.isEmpty())
{
Edgee=mpq.deleteMin();
System.out.println("从优先队列中移除"+e);
intv=e.either(),w=e.other(v);
assertmarked[v]||marked[w];
if(marked[v]&&marked[w])continue;
mst.add(e);
System.out.println("向最小生成树的边集合中加入"+e);
totalweight+=e.weight();
if(!marked[v])scan(G,v);
if(!marked[w])scan(G,w);
}
}
private voidscan(EdgeWeightedGraph G,int v)
{
assert!marked[v];
marked[v]=true;
for(Edgee:G.adj(v))
{
if(!marked[e.other(v)])
{
mpq.insert(e);
System.out.println("向优先队列中加入"+e);
}
}
}
public doubletotalWeight(){return totalweight;}
public StringtoString()
{
StringBuildersb=new StringBuilder();
sb.append("最小生成树的边信息:\n");
for(Edgee:mst)
{
sb.append(e.toString()+"\n");
}
sb.append(String.format("权值和为:%.5f",totalweight));
returnsb.toString();
}
public static voidmain(String[] args) {
// TODOAuto-generated method stub
In in=newIn("tinyEWG.txt");
EdgeWeightedGraphgraph=new EdgeWeightedGraph(in);
LazyPrimMSTsample=new LazyPrimMST(graph);
System.out.println(sample);
}
}
运行结果如下所示:
向优先队列中加入0--7[0.16000]
向优先队列中加入0--4[0.38000]
向优先队列中加入0--2[0.26000]
向优先队列中加入6--0[0.58000]
从优先队列中移除0--7[0.16000]
向最小生成树的边集合中加入0--7[0.16000]
向优先队列中加入4--7[0.37000]
向优先队列中加入5--7[0.28000]
向优先队列中加入1--7[0.19000]
向优先队列中加入2--7[0.34000]
从优先队列中移除1--7[0.19000]
向最小生成树的边集合中加入1--7[0.19000]
向优先队列中加入1--5[0.32000]
向优先队列中加入1--2[0.36000]
向优先队列中加入1--3[0.29000]
从优先队列中移除0--2[0.26000]
向最小生成树的边集合中加入0--2[0.26000]
向优先队列中加入2--3[0.17000]
向优先队列中加入6--2[0.40000]
从优先队列中移除2--3[0.17000]
向最小生成树的边集合中加入2--3[0.17000]
向优先队列中加入3--6[0.52000]
从优先队列中移除5--7[0.28000]
向最小生成树的边集合中加入5--7[0.28000]
向优先队列中加入4--5[0.35000]
从优先队列中移除1--3[0.29000]
从优先队列中移除1--5[0.32000]
从优先队列中移除2--7[0.34000]
从优先队列中移除4--5[0.35000]
向最小生成树的边集合中加入4--5[0.35000]
向优先队列中加入6--4[0.93000]
从优先队列中移除1--2[0.36000]
从优先队列中移除4--7[0.37000]
从优先队列中移除0--4[0.38000]
从优先队列中移除6--2[0.40000]
向最小生成树的边集合中加入6--2[0.40000]
从优先队列中移除3--6[0.52000]
从优先队列中移除6--0[0.58000]
从优先队列中移除6--4[0.93000]
最小生成树的边信息:
0--7[0.16000]
1--7[0.19000]
0--2[0.26000]
2--3[0.17000]
5--7[0.28000]
4--5[0.35000]
6--2[0.40000]
权值和为:1.81000
(说明:程序中需要的其他一些类可以在“用于最小生成树的Kruskal算法实现”一文中查到,在这篇文章中不在重复!)
文章链接: http://blog.csdn.net/andamajing/article/details/8702179点击打开链接
- 用于最小生成树的Prim算法实现
- 最小生成树的prim算法实现
- 最小生成树的prim算法实现
- 最小生成树的Prim算法实现
- 我对Prim算法用于求无向图的最小生成树的理解 (C++实现)
- Prim 算法生成的最小生成树
- 最小生成树Prim算法实现
- 最小生成树prim算法实现
- prim 最小生成树算法 java实现
- Prim算法实现最小生成树MST
- python实现prim 最小生成树算法
- poj1258--最小生成树prim算法实现
- 最小生成树prim算法实现
- 最小生成树prim算法实现
- 最小生成树prim算法实现
- 最小生成树Prim算法实现
- 最小生成树prim算法实现
- 简单实现最小生成树-Prim算法
- Linux下ffmpeg安装与开发配置
- 关于android游戏的汉化
- 编辑器中js跨二级域问题 document.designMode与domain冲突
- ora01019错误一览表
- iOS的基本的设计模式
- 用于最小生成树的Prim算法实现
- 接口隔离原则(Interface Segregation Principle)
- 只用4行代码编写出一个从字符串到长整形的函数
- 图文解释XCode常用快捷键的使用
- osgi环境下 quartz集群方案
- 软件生存期模型
- Linux软连接 删除/查看
- UIBezierPath
- AndEngine安全移除精灵的方式