当前位置: 首页 > news >正文

【算法】普里姆算法解决修路问题

 应用场景——修路问题

1.某地有 7 个村庄(A,B,C,D,E,F,G),现在需要修路把 7 个村庄连通

2.各个村庄的距离用边线表示(权),比如 A - B 距离 5 公里

3.问:如何修路保证各个村庄都能连通,并且修建公路的总里程最少?

思路

尽可能选择少的路线,并且每条路线最小,保证里程数最少

最小生成树问题

修路问题的本质就是最小生成树问题,先介绍一下最小生成树(MST)

1.给定一个带权的无向连通图,如何选取一颗生成树,使树上所有边上权的总和为最小,这叫最小生成树

2.N 个顶点,一定有 N-1 条边

3.包含全部顶点

4.N-1 条边都在图中

普里姆算法介绍

一、普里姆算法求最小生成树,也就是在包含 n 个顶点的连通图中,找出只有 n-1 条边包含所有 n 个顶点的连通子图,也就是所谓的极小连通子图

二、普里姆的算法如下

  1. 设 G=(V,E) 是连通网,T=(U,D) 是最小生成树,V,U 是顶点集合,E,D是边的集合
  2. 若从顶点 u 开始构造最小生成树,则从集合 V 中取出顶点 u 放入到集合 U 中,标记顶点 v 的 visited[u]=1
  3. 若集合 U 中顶点 ui 与集合 V - U 中的顶点 vj 之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点 vj 加入集合 U 中,将边(ui,vj) 加入集合 D 中,标记 visited[vj]=1
  4. 重复步骤2,直到 U 与 V 相等,即所有顶点都被标记为访问过,此时 D 中有 n-1 条边
普里姆算法的分析

1.从 <A> 顶点开始处理 => <A,G> => 权值 2

2.从 <A,G> 开始,将 A 和 G 顶点和他们相邻的还没有访问的顶点进行处理 => <A,G,B>

3.从 <A,G,B> 开始,将 A,G,B 顶点和他们相邻的还没有访问的顶点进行处理 => <A,G,B,E>

......

6.从 <A,G,B,E,F,D> 开始,将 A,G,B,E,F,D 顶点和他们相邻的还没有访问的顶点进行处理 => <A,G,B,E,F,D,C>

public class PrimAlgorithm {public static void main(String[] args) {//测试图是否创建成功char[] data = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int verxs = data.length;//邻接矩阵的关系使用二维数组表示,用 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 = new MGraph(verxs);//创建一个 MinTree 对象MinTree minTree = new MinTree();minTree.createGraph(graph, verxs, data, weight);//输出minTree.showGraph(graph);//测试普里姆算法minTree.prim(graph, 0);}
}//创建最小生成树 -> 村庄的图
class MinTree {//创建图的邻接矩阵/*** @param graph  图对象* @param verxs  图对应的顶点个数* @param data   图的各个顶点的值* @param weight 图的邻接矩阵*/public void createGraph(MGraph graph, int verxs, char[] data, int[][] weight) {for (int i = 0; i < verxs; i++) {graph.data[i] = data[i];for (int j = 0; j < verxs; j++) {graph.weight[i][j] = weight[i][j];}}}//显示图的邻接矩阵public void showGraph(MGraph graph) {for (int[] link : graph.weight) {System.out.println(Arrays.toString(link));}}//编写 prim 算法得到最小生成树/*** @param graph 图* @param v     v 表示从第几个顶点开始生成*/public void prim(MGraph graph, int v) {//visited[] 标记节点是否被访问过int visited[] = new int[graph.verxs];//把当前节点标记为已访问visited[v] = 1;//h1 和 h2 记录两个顶点的下标int h1 = -1;int h2 = -1;int minWeight = 10000;  //将 minWeight 初始成一个大数在后面的遍历过程中会被替换for (int k = 1; k < graph.verxs; k++) {  //因为有 graph.verxs 顶点,普利姆算法结束后,有graph.verxs-1条边//确定每一次生成的子图和哪个节点最近for (int i = 0; i < graph.verxs; i++) {  //i 节点表示被访问过的节点for (int j = 0; j < graph.verxs; j++) {  //j 节点表示没有被访问过的节点if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {//替换 minWeight (寻找已经访问过的节点间的权值最小的边)minWeight = graph.weight[i][j];h1 = i;h2 = j;}}}//找到一条边是最小System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值:" + minWeight);//将当前这个节点标记为已经访问visited[h2] = 1;//minWeight 重新设置为最大值 10000minWeight = 10000;}}
}class MGraph {int verxs;  //表示图的节点个数char[] data;  //存放节点数据int[][] weight;  //存放边,就是我们的邻接矩阵public MGraph(int verxs) {this.verxs = verxs;data = new char[verxs];weight = new int[verxs][verxs];}
}
http://www.lryc.cn/news/417636.html

相关文章:

  • Python 之Scikit-learn(二) -- Scikit-learn标准化数据
  • 机械学习—零基础学习日志(python编程)
  • WEB应用(十三)---RCE
  • 【云原生】Service服务暴露详细
  • 实名认证次数限制
  • 【如何在Python中使用pathlib模块】
  • sqli-labs第一关详细解答
  • 分布式事务一站式解决方案-Seata
  • openwrt 使用ftace工具追踪协议栈转发流程
  • ElasticSearch优化实战:打造高性能搜索引擎的秘籍
  • 【STL】| C++ 栈和队列(详解、容器适配器的初步引入)
  • xss漏洞(二,xss靶场搭建以及简单利用)
  • 深度学习--------------Kaggle房价预测
  • cpio 命令
  • TreeMap自定义排序
  • 我的CSDN 512天创作纪念日-20240807
  • 微服务-实现nacos的集群和Gateway网关的实现、认证校验、解决跨域
  • 数据库中的约束,聚合函数以及联合查询
  • 【AI大模型】Ollama+OpenWebUI+llama3本地大模型
  • 习题20240807
  • src挖掘-记一次有趣的逻辑漏洞分享
  • 【C++】STL | list (链表)详解及重要函数的实现
  • 警惕智能手机的“隐形眼”:如何保护我们的数字隐私堡垒
  • 人工智能算法工程师(高级)课程12-自然语言处理之NLP的语言模型-ELMo,transformer,BERT与代码详解
  • PicGo + gitee 免费搭建个人图床
  • 组合数的低复杂度运算
  • 小型并网式光伏气象站:光伏电站的智能守护者
  • JavaScript 中的回调函数(callback)
  • 计算机毕业设计hadoop+spark+hive漫画推荐系统 动漫视频推荐系统 漫画分析可视化大屏 漫画爬虫 漫画推荐系统 漫画爬虫 知识图谱 大数据
  • 解决pycharm日志总是弹出“无法运行Git,未安装Git”的问题