`

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();  
	    }  

}
 

 

分享到:
评论

相关推荐

    cpp-图论算法最小生成树Prim算法和Kruskal算法C实现

    图论算法:最小生成树——Prim算法和Kruskal算法C 实现

    最小生成树Prim算法的C语言程序

    Prim算法是最小生成树一般算法的特例, Prim算法的特点是集合A的边总是只形成单棵树.

    用c++实现的图论中的prim最小生成树算法

    本程序是使用c++编写的prim最小生成树算法,需要输入的是graph的阶数以及边赋权图矩阵

    Prim算法最小生成树

    Prim 算法求最小生成树 语法:prim(Graph G,int vcount,int father[]); 参数: G:图,用邻接矩阵表示 vcount:表示图的顶点个数 father[]:用来记录每个节点的父节点 返回值:null 注意: 常数max_vertexes 为图...

    论文研究-基于GPU的并行最小生成树算法的设计与实现.pdf

    针对目前并行Prim最小生成树算法效率不高的问题,在分析现有并行Prim算法的基础上,提出了适于GPU架构的压缩邻接表图表示形式,开发了基于GPU的min-reduction数据并行原语,在NVIDIA GPU上设计并实现了基于Prim算法...

    c/c++最小生成树 prim算法

    洛谷原模板题p3366 题目网址: https://www.luogu.com.cn/problem/P3366

    Prim算法 最小生成树

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为...

    最小生成树算法之Prim算法

    主要讲解了普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树,需要的朋友可以参考下

    c++最小生成树算法

    这是用prim算法实现的最小生成树算法,实质上是一个贪心算法的应用,看一下,会对你有帮助

    最小生成树的算法实现

    该程序用C实现了最小生成树的prim和kruscal算法,并且也实现了,图的广度遍历和深度遍历,采用了临界矩阵或者是临界表的存储结构。

    matlab最小生成树算法

    matlab算法,可以解决最小生成树算法以及类似问题关于最小生成树,学过图论的都懂,这里就不做介绍。 下面是一个例题,附有Kruskal算法和Prim算法。

    图论算法(matlab).rar

    图论算法(matlab),包含迪克斯特拉算法、图论弗洛伊德算法、最小生成树prim算法。亲自验证无误,可直接使用.

    算法Prim.zip

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为...

    prim算法.cpp

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为...

    Frim算法求最小生成树问题_matlab_K._

    图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由...

    山东大学2018算法导论图论考试复习总结

    2.2 Kruskal算法和Prim算法 3 单源最短路径 3.1 Bellman-Ford算法 3.2 有向无环图(DAG图)中单源最短路径问题 3.3 Dijkstra算法 3.4 差分约束和最短路径 3.5 最短路径的性质证明(三上无路收钱) 4 所有结点对的...

    图论算法库 C++ 语言实现 代码内容 图论算法库,包括以下算法: 单源最短路径 Dijkstra 算法 单源最短路径 Bell

    图论算法库 C++ 语言实现 代码内容 图论算法库,包括以下算法: 单源最短路径 Dijkstra 算法 单源最短路径 Bellman-Ford 算法 最小生成树 Prim 算法 每对节点间最短路径 Flod-Warshall 算法

    图论(最短路径,最小生成树)

    Prim,Floyd,Dijkstra算法

    浙大算法包,几何 结构\数论\数值计算\图论_NP搜索\图论_连通性\图论_匹配\组合\

    最小生成树(prim+mapped_heap邻接表形式) 最小生成树(prim+mapped_heap正向表形式) 最小树形图(邻接阵形式) 应用\ joseph模拟 N皇后构造解 布尔母函数 第k元素 幻方构造 模式匹配(kmp) 逆序对数 字符串...

Global site tag (gtag.js) - Google Analytics