普利姆算法解决最短修路问题
普利姆算法
1、应用场景-修路问题
2、最小生成树
3、普利姆算法介绍
4、普利姆算法的最为简单的理解(重点):
理论上7个点要6条路就可以连通,随便从一个结点(村庄)出发(假设为A),先找该结点和邻居结点(村庄)距离最小的结点(村庄),假设为B,最小路径为A–>B ,这样子A和B连通了。
把B加入已访问的集合中,则为(A,B)找A的其他邻居和B的其他邻居,然后找到距离A或者B最小的那个邻居结点,假设为C点,且路径为B–>C最小,则A–>B B–>C 这样A通过B可以走到C,即ABC连通了。把C加入已访问的集合中,则为(A,B,C)
依次往后找,上一段为(A–>B B–>C),比较A,B,C的其他邻居和A,B,C之间的距离,然后找到距离A或者B或者C最小的那个邻居结点(村庄),假设为D点,且路径为B–>D最小,则A–>B B–>C B–>D 这样A通过B可以走到C,也可以走到D,即ABCD连通了。把D加入已访问的集合中,则为(A,B,C,D)
…
依次循环,n节点需走n-1个次(eg:【点–点--点–点(4个结点(村庄)3条最小路径便能连通)】),就能构建出一条理论上最短的连通路径(有点贪心算法的味道了,每次都取相邻距离最小的点,并且把该点入集合,然后下次再把集合中那几个点的相邻的最小的点放入集合,把所有n个点放完也就n-1次,就构建了n-1条短路,n个村庄就能连起来互通了)
5、普利姆算法最佳实践(修路问题)
代码实现:
package com.czl.prim;import java.lang.reflect.Array;
import java.util.Arrays;public class PrimAlgorithm {public static void main(String[] args) {MinTree minTree = new MinTree();//测试看看图是否创建成功char[] data = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G'};//邻接矩阵的关系使用二维数组表示,10000这个大数,表示两个点不连通int[][] weight = {{10000, 5, 7, 10000, 10000, 10000, 2},{5, 10000, 10000, 9, 10000, 10000, 3},{7, 10000, 10000, 10000, 8, 10000, 10000},{10000, 9, 10000, 10000, 10000, 4, 10000},{10000, 10000, 8, 10000, 10000, 5, 4},{10000, 10000, 10000, 4, 5, 10000, 6},{2, 3, 10000, 10000, 4, 6, 10000}};//得到MGraph对象MGraph graph = minTree.createGraph(data, weight);for (int[] link : graph.weight) {System.out.println(Arrays.toString(link));}//测试普利姆算法minTree.prim(graph, 1);}
}//创建最小生成树->村庄的图
class MinTree {/**** @param data 图的各个顶点的值* @param weight 图的邻接矩阵* @return*/public MGraph createGraph(char[] data, int[][] weight) {MGraph graph = new MGraph(data.length);graph.data = data;for (int i = 0; i < data.length; i++) {for (int j = 0; j < data.length; j++) {graph.weight[i][j] = weight[i][j];}}return graph;}//普利姆算法得到最小生成树/**** @param mGraph 图* @param v 表示从图的第几个顶点开始生成 'A'->0 'B'->1 ...*/public void prim(MGraph mGraph, int v) {//visited[] 标记结点(顶点)是否被访问过。1为被访问,0为没访问int[] visited = new int[mGraph.verxs];int minWeight = 10000;//初始化一个大数,后面在遍历过程中,会被替换//把当前这个结点标记为已访问visited[v] = 1;//h1和h2记录两个顶点的下标int h1 = -1;int h2 = -1;//有graph.verxs个顶点,普利姆算法结束后,有graph.verxs-1条边,因此这里做graph,verxs-1次循环/*第一次循环,假设当前顶点为A,则寻找A相邻顶点距离最小的顶点(村庄),假设为B ,且路径为A --> B此时子图为A,B A-->B第二次循环,比较A到其他相邻顶点和B到其他相邻顶点(村庄)的距离,找到最小距离的那个顶点(村庄), 假设为C 且路径为B-->C最小 ,此时子图为 A,B ,C A-->B B-->C(即A可以通过B到达C)第三次循环,比较A,B,C其他相邻顶点的距离,找到最小距离的那个顶点,假设为D,且路径为 B-->D此时子图为A,B,C,D A-->B B-->C B-->D(即A可以通过B到达D)第四次循环,比较A,B,C,D其他相邻顶点的距离,找到最小距离的那个顶点,假设为E,路径为 D-->E此时子图为A,B,C,D,E A-->B B -->C B-->D D -->E (即A通过B到达D,再通过D到达E)依次循环...直到n个顶点遍历n-1次后找到n个顶点(村庄)连接的最小路径*/for (int k = 1; k < mGraph.verxs; k++) {//确定每一次生成的子图,与那个结点最近//一次双层for循环,可以找到子图中已访问的所有的点和其他相邻顶点距离最小的顶点for (int i = 0; i < mGraph.verxs; i++) {//i结点表示被访问过的节点for (int j = 0; j < mGraph.verxs; j++) {//j结点表示还没访问过的结点//被访问过的结点(visited[i] == 1 )和未访问过的结点( visited[j] == 0 )之间的距离(权)<设定的minWeight(10000)if (visited[i] == 1 && visited[j] == 0 && mGraph.weight[i][j] < minWeight) {//替换minWeight(x寻找已经访问过的结点和未访问过的结点间的权值最小的边)minWeight = mGraph.weight[i][j];h1 = i;h2 = j;}}}//找到一条边最小System.out.println("边<"+mGraph.data[h1]+","+mGraph.data[h2]+">权为:"+minWeight);//将当前这个结点标记为已经访问visited[h2]=1;//重新设置为最大值10000minWeight = 10000;}}}//邻接矩阵
class MGraph {int verxs;//表示图的结点个数int weight[][];//存放边,就是我们的邻接矩阵char[] data;//存放结点数据public MGraph(int verx) {verxs = verx;weight = new int[verxs][verxs];data = new char[verxs];}}
普利姆算法解决最短修路问题相关推荐
- 普里姆算法解决修路问题
一 问题提出 1 胜利乡有7个村庄(A, B, C, D, E, F, G),现在需要修路把7个村庄连通. 2 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里. 问:如何修路保证各个 ...
- 普利姆算法和修路问题
修路问题 看一个应用场景和问题: 有胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里 问:如何 ...
- 普利姆算法和克鲁斯卡尔算法解决最小生成树问题
什么是最小生成树? 最小生成树(Minimum Cost Spanning Tree),简称MST. 最小生成树要求图是连通图.连通图指图中任意两个顶点都有路径相通,通常指无向图.理论上如果图是有向. ...
- Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)
1.Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal) 普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)求**最小生成树(极小连通子图)**的算法 1.1普利姆算法(Prim) ...
- Prim Algorithm(普利姆算法)
Prim算法介绍 普里姆算法(Prim's algorithm),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权 ...
- 普利姆算法(prim)---(韩顺平数据结构)笔记
普利姆算法 本质:求出从某一结点开始到达其他结点距离花费最少的组合 从图中指定顶点出发,寻找它相连的所有结点,比较这些结点的权值大小,然后连接权值最小的那个结点. 然后将寻找这两个结点相连的所有结点, ...
- 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)
最小生成树 什么是最小生成树 是一棵树 - 无回路 - |V|个顶点一定有|V|-1条边 是生成树 - 包含全部顶点 - |V|-1条边全在图里 贪心算法 什么是"贪":每一步都要 ...
- 普利姆算法和克鲁斯卡尔算法求解最小生成树
Q:最小生成树有什么用? A:譬如我要去五个城市旅游,每两个城市之间可能有路也可能没有,路的距离可能一样也可能不一样,随机从一个城市出发,我想要把每个城市走一遍,怎么样走过的路距离最短,比如我想从上海 ...
- 数据结构第十二天——普利姆算法和迪杰斯特拉算法
普利姆(Prim)算法求最小生成树,也就是在包含 n个顶点的连通图中,找出只有(n-1)条边包含所有 n个顶点的连通子图,也就是所谓的极小连通子图 最小生成树:给定一个带权的无向连通图,如何选取一棵生 ...
最新文章
- 什么是Hystrix
- 蓝桥分酒java_[蓝桥杯][java]海盗分酒
- hadoop学习5 搭建storm集群
- 【转】2007高校BBS上20个睿智的冷笑话
- 【APIO2018】Duathlon 铁人两项 【圆方树】
- 7 操作系统第二章 进程管理 进程同步与互斥
- JS当中的无限分类递归树
- [C++][基础]8_容器
- 数字通信的调制方式 ASK FSK PSK QAM
- java论文范文模板_Java专业论文开题报告 论文的开题报告模板
- 深度 ghost xp3 装IIS 方法
- 汤国安 ARCGIS地理信息系统空间分析实验教程
- 小米笔记本用鸿蒙系统,小米笔记本Pro15.6GTX版评测 如果你主力用它来玩游戏显然不是明智之选...
- linux udp 端口 抓包,Linux系统-tcpdump常用抓包命令
- 科学计数法符号e 自然常数e
- python读取文本某一行内容
- 公司邮件服务器端口mail2000,简单邮件传输协议SMTP—邮件服务器DBMail
- 游戏地图与场景设计常用名词
- 2022-07-31 零基础吉他入门知识
- 决策树(一)——构建决策树
热门文章
- TeamViewer远程工具使用安装方法图解
- SAP SD VL31N BBP_INB_DELIVERY_CREATE 根据采购订单创建内向交货单
- 蓝桥杯第八届真题 :拉马车
- “加密上海·喜玛拉雅Web3.0数字艺术大展”落幕,AIGC和数字艺术衍生品是最大赢家?...
- 学渣小论文投稿期刊记录总结
- 计算机教学运用培训,教师计算机培训教学教程.doc
- PostgreSQL - null和''的区别与判断以及COALESCE函数
- 假如生活欺骗了你……
- UTC时间与北京时间
- 何鸿略加入华为消费者业务 任大中华区副总裁