Prim算法

news2025/1/16 9:10:38

应用场景

1.如何修路才能保证修路的总路程最短?
在这里插入图片描述
特点:
1.将所有节点全部连通,并且边上的权总和最小——>最小生成树
2.N个顶点,有N-1条边

Prim算法图解分析

简而言之,就是先确定顶点A,然后寻找没有遍历到的点寻找最小权重的点<A,G>
然后从<A,G>开始,寻找相邻没有访问的节点并寻找最小权重<G,B>——>变成了<A,G,B>
然后不断遍历循环,寻找相邻没有访问的节点并为最小权重,最后相加即为最短路径
在这里插入图片描述
会发现n个点,会有n-1条边,把对应的权重相加就是最短路径(有点贪心算法的思维:每次新的路都选择最短的)
在这里插入图片描述

最小生成树

最小生成树实际上就是无向图的最短权值之和

代码实现Prim

简而言之,就是先确定顶点,根据顶点得到边上权值最短的节点,然后根据这两个节点遍历得到周围最短的节点,然后不断遍历不断确定

思路:
1.首先传入的参数是图和顶点,初始化visited[]数组作为节点是否被访问过的状态数组,将顶点状态标记为1
2.初始化边两点h1和h2的下标为-1,以及权重数为10000;
3.进行遍历边,然后两层嵌套——> ** 核心:通过被访问的节点进行扩散访问没有访问过的节点,并比较权重,如果是最小就进行替换minWeight,并记录下标,当一条边的都访问完了,记录一条最短边的权重(此时可能会有其他节点变为以及已经访问的状态) **

package com.demo;

import java.util.Arrays;

public class Prim {
    public static void main(String[] args) {
        //1.存放数据
        char[] data = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int verxs = data.length;
        //2.邻接矩阵的关系用二维数组表示点和点之间的权重(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}

        };

        //3.创建MGraph对象
        MGraph mGraph = new MGraph(verxs);

        //4.创建一个MinTree对象
        MinTree minTree = new MinTree();
        minTree.createGraph(mGraph, verxs, data, weight);

        //5.输出
        minTree.showGraph(mGraph);

        //6.最小生成树
        minTree.prim2(mGraph,0);
    }

}

//生成最小生成树——>村庄的图
class MinTree {

    /**
     * 1.创建图对象
     *
     * @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++) {
            //1.数据赋值
            graph.data[i] = data[i];
            //2.边赋值
            for (j = 0; j < verxs; j++) {
                graph.weight[i][j] = weight[i][j];
            }
        }
    }

    /**
     * 2.显示图的邻接矩阵
     *
     * @param graph
     */
    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) {
        //1.visited[]标记顶点是否被访问过
        int[] visited = new int[graph.verxs];
        //2.顶点的确定
        visited[v] = 1;
        //3.两个点初始下标
        int h1 = -1;
        int h2 = -1;
        int minWeight = 10000; //两点初始化为一个大数

        //4.有graph.verxs个顶点,普利姆算法结束后,有graph.verxs-1条边
        for (int k = 1; k < graph.verxs; k++) {

            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 = graph.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }
            }

            //5.找到从顶点出发的最小边
            System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值:" + minWeight);
            //6.当前节点已经访问
            visited[h2] = 1;
        }

    }

    public void prim2(MGraph gragh, int v) {
        //visited[] 标记节点被访问过
        int visited[] = new int[gragh.verxs];
        //把当前节点标记为
        visited[v] = 1;
        //h1和h2记录两个顶点下标
        int h1 = -1;
        int h2 = -1;
        int minWeight = 10000;//先初始化大数 有比他小的就替换
        for (int k = 1; k < gragh.verxs; k++) {

            //每次生成的子图和哪个节点的距离最近
            for (int i = 0; i < gragh.verxs; i++) { //i节点表示被访问过的节点
                for (int j = 0; j < gragh.verxs; j++) { //j节点表示还没访问过的节点
                    if (visited[i] == 1 && visited[j] == 0 && gragh.weight[i][j] < minWeight) {
                        //替换minWeight
                        minWeight = gragh.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }
            }
            System.out.println("边<" + gragh.data[h1] + "," + gragh.data[h2] + ">权值:" + minWeight);
            //当当前节点标记为已经访问
            visited[h2] = 1;
            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/93907.html

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

相关文章

代码随想录训练营第52天|LeetCode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

参考 代码随想录 题目一&#xff1a;LeetCode 300.最长递增子序列 确定dp数组下标及其含义 dp[i]&#xff1a;在nums数组中&#xff0c;在下标0~i元素&#xff08;包含i&#xff09;的基础上&#xff0c;以nums[i]作为子序列的最后一个元素&#xff0c;组成的最长严格递增子序…

0126 搜索与回溯算法 Day15

剑指 Offer 34. 二叉树中和为某一值的路径 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,…

cuda学习笔记4——cuda 核函数

cuda学习笔记4——cuda 核函数一、CUDA规范二、核函数内部线程的使用2.1 如何启动核函数demo 1&#xff1a;起16个线程来计算&#xff0c;四个线程块&#xff0c;每个块内四个线程例子demo2核函数是指在GPU端运行的代码&#xff0c;核函数内部主要干了什么&#xff1f;简而言之…

一个《跳动的爱心》代码,纯HTML+JS,双击直接运行

HTMLJS实现的一个跳动的爱心。集合了web动画库GSAP JS、OBJ 文件加载器OBJLoader、WebGL第三方库Three.js等。效果非常棒&#xff01; 目录实际效果&#xff1a;目录结构&#xff1a;HTML代码CSS代码js代码&#xff1a;简单的修改完整文件下载实际效果&#xff1a; 由于是纯前端…

学会IDEA这些断点操作,生产问题解决的越来越快了

文章目录IDEA断点高级用法1、断点类型1&#xff09;行断点&#xff08;line breakpoints&#xff09;2&#xff09;字段断点&#xff08;field breakpoints&#xff09;3&#xff09;方法断点&#xff08;method breakpoints&#xff09;1> 加载类名上的断点2> 正常方法断…

xss-labs(WriteUp)

xss-labs 先讲讲什么是跨站脚本攻击XSS(Cross Site Scripting) XSS原理 本质上是针对html的一种注入攻击&#xff0c;没有遵循数据与代码分离的原则&#xff0c;把用户输入的数据当作代码来执行 xss跨站脚本攻击是指恶意攻击者往Web页面里插入恶意脚本代码&#xff08;包括当…

redis之codis和redis cluster对比

写在前面 codis和Redis cluster 都是Redis的集群方案&#xff0c;本文就一起来看下。 1&#xff1a;codis的组件和架构 codis的组件有4个&#xff0c;如下&#xff1a; codis server&#xff1a;基于redis进行了二次开发的组件&#xff0c;负责数据的读写 codis proxy&…

Halcon图像拼接

图像拼接在实际的应用场景很广&#xff0c;比如无人机航拍&#xff0c;遥感图像等等&#xff0c;图像拼接是进一步做图像理解基础步骤&#xff0c;拼接效果的好坏直接影响接下来的工作&#xff0c;所以一个好的图像拼接算法非常重要。 如按下图是将两张楼房图片拼接成一个图像。…

QT 学习笔记(九)

文章目录一、事件的接收和忽略1. 准备工作2. 接收和忽略二、event() 函数1. 简介2. 实例演示3. 总结三、事件过滤器四、总结&#xff08;细看&#xff09;1. 知识点汇总2. QT 的事件处理五、事件、事件的接收和忽略、event() 函数和事件过滤器代码1. 主窗口头文件 mywidget.h2.…

英语文本转语音软件哪个好?分享三个新手也能学会的工具

大家平时都是怎么学习英语的呢&#xff1f;课上老师让我们熟悉单词意思、巩固语法、多练阅读理解&#xff1b;其实通过练习听力来加强语感也很重要。很多小伙伴的阅读理解很好&#xff0c;但是听力却跟不上。这里教大家一个小技巧&#xff0c;就是在做阅读理解的时候&#xff0…

第十章TomCat详解

文章目录Tomcat的部署和启动Tomcat扮演的角色①对外&#xff1a;Web服务器②对内&#xff1a;Servlet容器深入理解为什么需要TomCat从目的开始出发遇到的问题总过程部署前提解压TomCat的目录文件启动Tomcat并访问首页如何部署一个项目访问对应的web资源专业版IDEA创建一个JavaW…

力扣(718.1143)补9.12

718.最长重复子数组 这题真的想不到。 看图的话会好懂很多。 class Solution { public int findLength(int[] nums1, int[] nums2) { int nnums1.length; int n2nums2.length; int[][] dpnew int[n1][n21]; int result0; for(int…

【区块链-智能合约工程师】第二篇:Solidity入门

文章目录Solidity极简入门HelloWorld数值类型三种函数类型函数输出变量作用域引用类型参考文章&#xff1a;一文速览2022十大智能合约开发工具 资料地址&#xff1a;WTF学院 Solidity极简入门 HelloWorld remix&#xff1a;在线智能合约开发IDE&#xff08;Integrated Deve…

DBCO-PEG-Aminooxy, Aminooxy-PEG-DBCO,氨甲基聚乙二醇环辛炔

DBCO-PEG-Aminooxy &#xff0c; Aminooxy-PEG-DBCO&#xff0c;二苯并环辛炔-聚乙二醇-氨甲基&#xff0c;氨甲基聚乙二醇环辛炔 Product specifications&#xff1a; 1.CAS No&#xff1a;N/A 2.Molecular weightMV&#xff1a;1000&#xff0c;2000&#xff0c;34000&#x…

小侃设计模式(十八)-发布订阅模式

1.概述 发布订阅模式又叫观察者模式&#xff08;Observer Pattern&#xff09;&#xff0c;它是指对象之间一对多的依赖关系&#xff0c;每当那个特定对象改变状态时&#xff0c;所有依赖于它的对象都会得到通知并被自动更新&#xff0c;它是行为型模式的一种。观察者模式内部…

被吹爆的JVM笔记,一招教会什么是JVM调优,资深架构师强推!

面试经常被问 JVM 如何调优&#xff1f;这个问题该怎么回答&#xff1f;没有实际调优经验怎么办&#xff1f; 一般面试时问JVM调优&#xff0c;主要是因为&#xff0c;这个技术并不是懂了Java就能自然懂的&#xff0c;需要明白一些底层原理&#xff0c;有一些深度。所以比较适合…

传奇客户端文件介绍注解教程,GM必备知识

传奇客户端文件介绍注解教程&#xff0c;GM必备知识 很多朋友架设微端&#xff0c;或者说修改传奇版本素材方面的内容的时候对于客户端很懵逼&#xff01; 尤其是新手朋友他并不知道传奇客户端里面哪个文件是对应什么内容的&#xff01; 今天我们将这些发出来分享给支持奇速的朋…

高压放大器在IDE压电元件及其在仿生翼中的应用

实验名称&#xff1a;IDE压电元件及其在仿生翼中应用研究 研究方向&#xff1a;仿生学 测试目的&#xff1a; 优化IDE压电元件结构和组分出发&#xff0c;目的是为了获得大驱动位移、综合性能良好的IDE驱动件。着重研究IDE压电元件的力学和电学性能、驱动特性和在仿生翼上的集成…

LVGL学习笔记(一)--- 环境搭建

LVGL全程LittleVGL&#xff0c;是一个轻量化的&#xff0c;开源的&#xff0c;用于嵌入式GUI设计的图形库。并且配合LVGL模拟器&#xff0c;可以在电脑对界面进行编辑显示&#xff0c;测试通过后再移植进嵌入式设备中&#xff0c;可以高效地进行开发。 一.嵌入式设备的移植 L…

企业请体育冠军明星代言,为何要在年前邀请

行业形势好&#xff0c;要把握住消费升级的机会&#xff1b;行业调整时&#xff0c;要抓住结构性增长的机会。实力背书、冠军代言、让品牌成为品类创新&#xff0c;中小型这几个概念与品牌自身的卖点&#xff0c;每一个放在光中小型企业的品牌上都能独当一面&#xff0c;当一款…