【数据结构与算法】普里姆算法

news2024/9/29 9:32:51

普里姆算法

最小生成树

最小生成树,简称MST。

  1. 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这就叫最小生成树。
  2. N 个顶点,一定有 N - 1 条边
  3. 半酣全部顶点
  4. N - 1 条边都在图中
  5. 举例说明:

在这里插入图片描述

求最小生成树的算法主要是普里姆算法和克鲁斯卡尔算法

介绍

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

普里姆算法最佳实践 - 修路问题

在这里插入图片描述

  1. 有胜利乡有 7 个村庄{A,B,C,D,E,F,G},现在需要修路把 7 个村庄连通
  2. 各个村庄的距离用边线表示(权),比如 A - B 距离 5 公里
  3. 问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短?

代码实现

public class PrimAlgorithm {
    public static void main(String[] args) {
        // 测试
        char[] data = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int verxs = data.length;
        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 graph = new MGraph(verxs);
        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) {
        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];
            }
        }
    }

    /**
     * 显示图的邻接矩阵
     *
     * @param graph 图对象
     */
    public void showGraph(MGraph graph) {
        for (int[] link : graph.weight) {
            System.out.println(Arrays.toString(link));
        }
    }

    /**
     * 编写 prim 算法,得到最小生成树
     *
     * @param graph 图对象
     * @param 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 设置为最大值
            minWeight = 10000;
        }
    }
}

class MGraph {
    int verxs; // 表示图的节点的个数
    char[] data; // 存放节点数据
    int[][] weight; // 存放边,就是我们的邻接矩阵

    public MGraph(int verxs) {
        this.verxs = verxs;
        this.data = new char[verxs];
        this.weight = new int[verxs][verxs];
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫逆向实战(五)--猿人学第三题

一、数据接口分析 主页地址&#xff1a;猿人学第三题 1、抓包 通过抓包可以发现数据接口是api/match/3 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无cookie是否加密&#xff1f; 无 二、发送请求 …

【Java】智慧工地SaaS平台源码:AI/云计算/物联网/智慧监管

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

Redis对象和五种常用数据类型

Redisobject 对象 对象分为键对象和值对象 键对象一般是string类型 值对象可以是string&#xff0c;list&#xff0c;set,zset,hash q&#xff1a;redisobj的结构 typedef struct redisObject { //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层实现…

ArcGIS Pro如何制作不规则形状图例

在默认的情况下&#xff0c;ArcGIS Pro生成的图例是标准的点、直线和矩形的&#xff0c;对于湖泊等要素而言&#xff0c;这样的表示方式不够直观&#xff0c;我们可以将其优化一下&#xff0c;制作不规则的线和面来代替原有图例&#xff0c;这里为大家介绍一下制作方法&#xf…

广东灯具3D扫描抄数建模服务3D测绘出图纸三维逆向设计-CASAIM

灯具三维逆向建模是一种将实际物体转换为数字模型的过程。通过逆向工程技术&#xff0c;可以将现有的灯具进行3D扫描&#xff0c;然后利用专业的逆向设计软件将其转换为准确的三维模型。 以下是CASAIM实施灯具三维逆向建模的一般步骤图&#xff1a; 1. 扫描&#xff1a;三维扫…

基于Prometheus监控Kubernetes集群

目录 一、环境准备 1.1、主机初始化配置 1.2、部署docker环境 二、部署kubernetes集群 2.1、组件介绍 2.2、配置阿里云yum源 2.3、安装kubelet kubeadm kubectl 2.4、配置init-config.yaml 2.5、安装master节点 2.6、安装node节点 2.7、安装flannel、cni 2.8、部署测…

读高性能MySQL(第4版)笔记03_监控

1. 服务级别帮助你定义客户满意的程度和标准&#xff0c;以便你在解决性能、可扩展性挑战等事情与开发内部工具之间做出时间权衡 2. 服务水平指标&#xff08;SLI&#xff09; 2.1. 如何衡量客户是否满意 3. 服务水平目标&#xff08;SLO&#xff09; 3.1. 为了确保客户满意…

三维模型OSGB格式轻量化顶点压缩主要技术方法分析

三维模型OSGB格式轻量化顶点压缩主要技术方法分析 在三维模型应用中&#xff0c;轻量化处理是提高数据传输效率、减少渲染时间和优化用户体验的重要手段。而OSGB格式是一种常见的三维模型格式&#xff0c;在进行轻量化处理时&#xff0c;顶点压缩是一种常用的技术方法。本文将…

Redis 十大数据类型

Redis数据类型都有哪些&#xff1f; Redis支持丰富的数据类型&#xff0c;那么具体在Redis7中都有哪些数据类型呢&#xff1f;请看下图&#xff1a; 官网介绍&#xff1a;https://redis.io/docs/data-types/。 其中&#xff0c;String、Hash、List、Set、Sorted Set等类型是大…

爬虫逆向实战(十五)--阿某某营登录

一、数据接口分析 主页地址&#xff1a;阿某某营 1、抓包 通过抓包可以发现登录接口是Users/Login 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现有一个s加密参数 请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无cookie是…

2022年电赛C题——小车跟随行驶系统——做题记录以及经验分享

前言 自己打算将做过的电赛真题&#xff0c;主要包含控制组的&#xff0c;近几年出现的小车控制题目&#xff0c;自己做过的真题以及在准备电赛期间刷真题出现的问题以及经验分享给大家 这次带来的是22年电赛C题——小车跟随行驶系统&#xff0c;这道题目指定使用的是TI的单片…

uniapp微信小程序区分正式版,开发版,体验版

小程序代码区分是正式版&#xff0c;开发版&#xff0c;还是体验版 通常正式和开发环境需要调用不同域名接口&#xff0c;发布时需要手动更换 或者有些东西不想在正式版显示&#xff0c;只在开发版体验版中显示&#xff0c;也需要去手动隐藏 官方没有明确给出判断环境的方法&a…

web实现酷炫的canvas粒子动画背景

文章目录 前言一、particle-bg1. git地址&#xff1a;2. 安装3. 使用4. 完整demo 二、tsParticles1. 源码地址&#xff1a;2. 安装3. 引入4. 使用5. 几个例子5.1 ts粒子五彩纸屑烟花5.2 多粒子产卵器-用tsParticles制作5.3 ts粒子鼠标吸引力5.4 粒子烟花 源码地址完结 前言 粒…

C++--深入类和对象(上)

引言&#xff1a; 本篇博客将深入探究C中的类和对象。我们将从普通高校教学点开始&#xff0c;逐步介绍类的定义、对象的创建和使用&#xff0c;以及类与对象之间的关系。通过详细讲解访问控制和成员函数&#xff0c;我们将揭示封装的重要性以及如何实现数据的隐藏和安全性。 目…

Docker容器:docker基础概述、安装、网络及资源控制

文章目录 一.docker容器概述1.什么是容器2. docker与虚拟机的区别2.1 docker虚拟化产品有哪些及其对比2.2 Docker与虚拟机的区别 3.Docker容器的使用场景4.Docker容器的优点5.Docker 的底层运行原理6.namespace的六项隔离7.Docker核心概念 二.Docker安装 及管理1.安装 Docker1.…

图数据库_Neo4j基于docker服务版安装_Neo4j Desktop桌面版安装---Neo4j图数据库工作笔记0004

然后我们来看看如何用docker来安装Neo4j community server 首先去执行docker pull neo4j:3.5.22-community 去拉取镜像 然后执行命令就可以安装了 可以用docker ps查看一下 看看暴露了哪些端口 然后再看一下访问一下这个时候,要用IP地址了注意 然后再来看一下安装Desktop 去下…

如何在前端实现WebSocket发送和接收UDP消息(多线程模式)

目录 简介&#xff1a;步骤1&#xff1a;创建WebSocket连接步骤2&#xff1a;创建Web Workers步骤3&#xff1a;发送和接收UDP消息&#xff08;多线程模式&#xff09;结束语&#xff1a; 简介&#xff1a; 本文将继续介绍如何在前端应用中利用WebSocket技术发送和接收UDP消息…

数学建模的概念和学习方法(什么是数学建模)

一、初步认识数学建模 数学建模是将数学方法和技巧应用于实际问题的过程。它涉及使用数学模型来描述和分析现实世界中的现象、系统或过程&#xff0c;并通过数学分析和计算来预测、优化或解决问题。数学建模可以应用于各种领域&#xff0c;包括自然科学、工程、经济学、环境科学…

Effective C++学习笔记(8)

目录 条款49&#xff1a;了解new-handler的行为条款50&#xff1a;了解new和delete的合理替换时机条款51&#xff1a;编写new和delete时需固守常规条款52&#xff1a;写了placement new也要写placement delete条款53&#xff1a;不要轻忽编译器的警告条款54&#xff1a;让自己熟…

XenDesktop5.6如何连接数据库

Citrix在数据库的连接方式上一直不统一&#xff0c;但是也还是有迹可循的。 经过了好长时间的下载以后&#xff0c;今天终于有时间来测试一下最新版本的XenDesktop 5 SP1&#xff0c;由于结合了其他组件和环境的需要&#xff0c;所以&#xff0c;选择了独立部署数据库&#xf…