java 图论三 带权图的最小生成树 Prim算法

带权图是实际情况中经常使用的,如城市道路,etl优化等等。

 

在带权图中经常遇到的问题就是生成最小生成树,就是加权总值最小的路径,这里用prime算法实现

 

prim算法的总思路

 

/**
	 * 生成最小生成树
	 * 将顶点放到树集合中,重复一下操作
	 * 1.找到最新的vertex到其他vertex的所有edge,其他vertex不能在树集合中,把这些edge放到优先队列中
	 * 2.找到权值最小的边,把edge和edge所到达的vertex放到树集合中
	 */

 

 

prim算法的过程示意图:这里贴一个邮电大学的

http://resource.jingpinke.com/details?uuid=ff808081-29263667-0129-2636a17d-39cb&objectId=oid:ff808081-29263667-0129-2636a17d-39cc

 

prim算法代码,java实现:

 

 

package com.Construction.DiscrectGraph;

import java.io.ObjectOutputStream.PutField;

public class Graph {
	/**
	 * max vertx number
	 */
	private final int MAX_VERTX = 20;
	/**
	 * max distance value
	 */
	private final int INFINITY  = 1000000;
	/**
	 * node list
	 */
	private Vertex vertexList[];
	/**
	 * adjacency matrix
	 */
	private int adjMat[][];
	/**
	 * graph node number
	 */
	private int nVerts;
	/**
	 * prime tree number
	 */
	private int nTree;
	/**
	 * current tree node
	 */
	private int currentVert;
	
	private PriorityQ priorityQueue;
	
	public Graph(){
		vertexList = new Vertex[MAX_VERTX];
		adjMat = new int[MAX_VERTX][MAX_VERTX];
		nVerts = 0;
		for (int i = 0; i < MAX_VERTX; i++) {
			for (int j = 0; j < MAX_VERTX; j++) {
				adjMat[i][j] = INFINITY;
			}
		}
		priorityQueue = new PriorityQ();
	}
	
	/**
	 * 添加元素
	 * @param label
	 */
	public void addVertex(char label){
		//添加元素,并将计数器加一
		vertexList[nVerts++] = new Vertex(label);
	}
	
	/**
	 * 添加边
	 * @param sv
	 * @param dv
	 * @param dis
	 */
	public void addEdge(int sv,int dv,int dis){
		adjMat[sv][dv] = dis;
		adjMat[dv][sv] = dis;
	}
	
	
	/**
	 * 生成最小生成树
	 * 将顶点放到树集合中,重复一下操作
	 * 1.找到最新的vertex到其他vertex的所有edge,其他vertex不能在树集合中,把这些edge放到优先队列中
	 * 2.找到权值最小的边,把edge和edge所到达的vertex放到树集合中
	 */
	public void mstw(){
		currentVert = 0;
		while (nTree < nVerts -1) {
			vertexList[currentVert].isInTree = true;//步骤2,放到树中
			nTree ++;
			for (int i = 0; i < nVerts; i++) {
				if(i == currentVert) continue; // visit other graph node
				if(vertexList[i].isInTree) continue;//visit other graph don't contain in tree -- to avoid connect unneccessary node
				int dis = adjMat[currentVert][i];
				if (dis == INFINITY) continue;
				putInPQ(i, dis);
			}
			if (priorityQueue.getSize() == 0) {
				return;
			}
			
			Edge currentMinEdge  = priorityQueue.removeMin();
			int sVert = currentMinEdge.srcVert;
			currentVert = currentMinEdge.destVert;
			System.out.println(vertexList[sVert].label);
			System.out.println(vertexList[currentVert].label);
			System.out.println(" ");
		}
		for (int i = 0; i < nVerts; i++) {
			vertexList[i].isInTree = false;
		}
	}
	
	/**
	 * 将循环操作1中的edge,放入优先队列中
	 * 优先队列中,到一个目的的边是唯一滴,所有当已经有老边了,需要比较替代
	 * @param vertex
	 * @param dis
	 */
	public void putInPQ(int vertex,int dis){
		int index = priorityQueue.find(vertex);
		if(index != -1){
			Edge tempEdge = priorityQueue.peek(index);
			int oldDis = tempEdge.distance;
			if(oldDis > dis){
				priorityQueue.remove(index);
				Edge theEdge = new Edge(currentVert, vertex, dis);
				priorityQueue.insert(theEdge);
			}
		}else{
			Edge theEdge = new Edge(currentVert, vertex, dis);
			priorityQueue.insert(theEdge);
		}
	}
	
	    public static void main(String[] args){  
	        Graph g = new Graph();  
	        g.addVertex('A');  
	        g.addVertex('B');  
	        g.addVertex('C');  
	        g.addVertex('D');  
	        g.addVertex('E');  
	        g.addVertex('F');  
	          
	        g.addEdge(0, 1, 6);  
	        g.addEdge(0, 3, 4);  
	        g.addEdge(1, 2, 10);  
	        g.addEdge(1, 3, 7);  
	        g.addEdge(1, 4, 7);  
	        g.addEdge(2, 3, 8);  
	        g.addEdge(2, 4, 5);  
	        g.addEdge(2, 5, 6);  
	        g.addEdge(3, 4, 12);  
	        g.addEdge(4, 5, 7);  
	        g.mstw();  
	    }  

}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值