37.普利姆(Prim)算法

从一个问题开始

“要想富,先修路”,郝乡长最近为了德胜乡修路的事情愁白了头。
得胜乡有A、B、C、D、E、F、G七个村子,现在需要修路把7个村庄连通,但是又想要耗费的公路建材最少(修建公路的总里程最短),聪明的你是否有什么好办法呢?
注:各个村庄的距离用边线(权值)来表示。

在这里插入图片描述

我们可以帮助郝乡长想想这个问题的解。思路上,尽可能选择少的路线,并且每条路线最小,是不是就能保证总里程数最小呢?

关于最小生成树

修路问题其实本质上是最小生成树问题。这里先介绍下最小生成树(Minimum Cost Spanning Tree),简称MST。

  1. 给定一个带权的无向连通图,如何选取一棵树,使得树上所有边上权的总和为最小,这个树就叫最小生成树
  2. 包含全部顶点
  3. N个顶点则必有N-1条边
  4. N-1条边必都在图中
    在这里插入图片描述

普利姆算法

普利姆算法解决的就是最小生成树的问题。
普利姆(Prim)算法求最小生成树,也就是在包含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条边

代码实现

public class PrimAlgorithm {public static void main(String[] args) {//创建测试char [] data = new char[]{'A','B','C','D','E','F','G'};int verxs = data.length;//邻接矩阵的关系使用二维数组表示,10000表示两点不连通int [][]weight=new int[][]{{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);//测试普利姆(Prim)算法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){int i,j;for (i = 0; i < verxs; i++) {//顶点graph.data[i] = data[i];for (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 表示从图的第几个顶点开始生成,比如从A开始生成 则传0;从B开始生成则传1*/public void prim(MGraph graph,int v){//标记顶点是否被访问过,默认全0,即均未访问过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){//(前两个条件假想落实)拿访问过的节点到未访问过节点的最近距离//替换为较小的minWeightminWeight = graph.weight[i][j];h1=i;h2=j;}}}//找到了一条边System.out.println("边<"+graph.data[h1]+","+graph.data[h2]+">权值:"+minWeight);//将当前这个节点标记为已访问visited[h2] = 1;//重置minWeightminWeight = 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];}
}

关注我,共同进步,每周至少一更。——Wayne

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/128301.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】TCP的服务端(守护进程) + 客户端

文章目录 &#x1f4d6; 前言1. 服务端基本结构1.1 类成员变量&#xff1a;1.2 头文件1.3 初始化&#xff1a;1.3 - 1 全双工与半双工1.3 - 2 inet_aton1.3 - 3 listen 2. 服务端运行接口2.1 accept&#xff1a;2.2 服务接口&#xff1a; 3. 客户端3.1 connect&#xff1a;3.2 …

条件查询和数据查询

一、后端 1.controller层 package com.like.controller;import com.like.common.CommonDto; import com.like.entity.User; import com.like.service.UserService; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.GetMapping; import …

文心一言 VS 讯飞星火 VS chatgpt (108)-- 算法导论10.1 6题

六、用go语言&#xff0c;说明如何用两个栈实现一个队列&#xff0c;并分析相关队列操作的运行时间。 文心一言&#xff1a; 使用两个栈实现队列的基本思想是利用一个栈&#xff08;stack1&#xff09;来处理入队操作&#xff0c;另一个栈&#xff08;stack2&#xff09;来处…

ELK集群 日志中心集群

ES&#xff1a;用来日志存储 Logstash:用来日志的搜集&#xff0c;进行日志格式转换并且传送给别人&#xff08;转发&#xff09; Kibana:主要用于日志的展示和分析 kafka Filebeat:搜集文件数据 es-1 本地解析 vi /etc/hosts scp /etc/hosts es-2:/etc/hosts scp /etc…

手机切换ip地址的几种方法详解

在某些情况下&#xff0c;我们可能需要切换手机的IP地址来实现一些特定的需求&#xff0c;如解决某些应用程序的限制、绕过IP封禁等。本文将为大家分享几种切换手机IP地址的方法&#xff0c;让您能够轻松应对各种需求。 一、使用动态服务器 使用动态服务器是一种常见的切换手机…

【Leetcode】 51. N 皇后

按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一种…

分布式文件系统HDFS(林子雨慕课课程)

文章目录 3. 分布式文件系统HDFS3.1 分布式文件系统HDFS简介3.2 HDFS相关概念3.3 HDFS的体系结构3.4 HDFS的存储原理3.5 HDFS数据读写3.5.1 HDFS的读数据过程3.5.2 HDFS的写数据过程 3.6 HDFS编程实战 3. 分布式文件系统HDFS 3.1 分布式文件系统HDFS简介 HDFS就是解决海量数据…

基于springboot实现人职匹配推荐管理系统演示【项目源码+论文说明】分享

基于springboot实现人职匹配推荐管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于人职匹配推荐系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了…

合宙Air780e+luatos+腾讯云物联网平台完成设备通信与控制(属性上报+4G远程点灯)

1.腾讯云物联网平台 首先需要在腾讯云物联网平台创建产品、创建设备、定义设备属性和行为&#xff0c;例如&#xff1a; &#xff08;1&#xff09;创建产品 &#xff08;2&#xff09;定义设备属性和行为 &#xff08;3&#xff09;创建设备 &#xff08;4&#xff09;准备参…

【Zookeeper专题】Zookeeper经典应用场景实战(一)

目录 前置知识课程内容一、Zookeeper Java客户端实战1.1 Zookeeper 原生Java客户端使用1.2 Curator开源客户端使用快速开始使用示例 二、Zookeeper在分布式命名服务中的实战2.1 分布式API目录2.2 分布式节点的命名2.3 分布式的ID生成器 三、zookeeper实现分布式队列3.1 设计思路…

MySQL命令行中文乱码问题

MySQL命令行中文乱码问题&#xff1a; 命令行界面默认字符集是gbk&#xff0c;若字符集不匹配会中文乱码或无法插入中文。 解决办法&#xff1a;执行set names gbk; 验证&#xff1a; 执行命令show variables like ‘char%’;查看默认字符集。 创建数据库设置字符集utf8&…

行车记录仪检测不到内存卡的原因

最近修了两个行车记录仪&#xff0c;相同的问题&#xff0c;都是提示插入内存卡&#xff08;TF卡&#xff09;。网上搜索资料&#xff0c;并没有明确的指出问题原因&#xff0c;有的是直接更换卡槽。 于是自己分析&#xff0c;首先内存卡电路属于小电流&#xff0c;而且电压并不…