简介

最小生成树介绍

Prim 算法本质就是就是求最小生成树问题, 最小生成树(Minimum Cost Spanning Tree),简称MST。

  • 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树
  • N个顶点,一定有N-1条边
  • 包含全部顶点
  • 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条边

普里姆算法最佳实践(解决修路问题)

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

思路: 将10条边,连接即可,但是总的里程数不是最小.
正确的思路,就是尽可能的选择少的路线,并且每条路线最小,保证总里程数最少

解决过程图示

(1) 连接所有村庄

(2) 以A 点为起点开始处理

  • A—C
  • A—G (最短)
  • A—B

(3) 自 A, G 开始 和 他们相邻的还没有访问的顶点进行处理

  • A—C
  • A—B
  • G—B (最短)
  • G—E
  • G—F

(4) 自 A,G, B 开始和他们相邻的还没有访问的节点进行处理

  • A—C
  • A—B
  • G—E (最短)
  • G—F
  • B—D

(5) 自 A,G, B,E 开始和他们相邻的还没有访问的节点进行处理

  • A—C
  • A—B
  • G—F
  • B—D
  • E—F (最短)
  • E—C

(6) 自 A,G, B,E,F 开始和他们相邻的还没有访问的节点进行处理

  • A—C
  • A—B
  • G—F
  • B—D
  • E—C
  • F—D (最短)

(7) 自 A,G, B,E,F 开始和他们相邻的还没有访问的节点进行处理

  • A—C(最短)
  • A—B
  • G—F
  • B—D
  • E—C

到现在为止, 所有节点均已被访问 即生成最小路径完成

代码

核心代码

package com.learn.bigdata.java.core.arithmetic;import java.util.Arrays;/*** 普利姆算法*/
public class Prim {public static volatile int MAX = Integer.MAX_VALUE; // 表示到不了的边public void createGraph(MGraph graph, int vertex, char[] data, int[][] matrix) {for (int k = 0; k < vertex; k++) {graph.data[k] = data[k];for (int j = 0; j < vertex; j++) {graph.matrix[k][j] = matrix[k][j];}}}public void showGraph(MGraph graph) {for (int i = 0; i < graph.vertex; i++) {int link[] = graph.matrix[i];System.out.println(Arrays.toString(link).replaceAll(Prim.MAX + "","∞"));}}/*** 普利姆核心算法* @param graph* @param v*/public void primCore(MGraph graph, int v) {int visited[] = new int[graph.vertex];visited[v] = 1;int vertex = graph.vertex;int minWeight = Prim.MAX;for (int k = 1; k < vertex; k++) {int t1 = -1;int t2 = -1;for (int i =0; i < vertex; i++) {for (int j = 0; j < vertex; j++) {boolean flag = visited[i] == 1 && visited[j] == 0 && graph.matrix[i][j] < minWeight;if (flag) {minWeight = graph.matrix[i][j];t1 = i;t2 = j;}}}//找到一条边是最小System.out.println("边 <" + graph.data[t1] + "," + graph.data[t2] + "> 权值:" + minWeight);visited[t2] = 1;minWeight = Prim.MAX;}}}class MGraph{int vertex; //节点个数char [] data; // 存放节点数据int [][] matrix; // 存放边, 邻接矩阵public MGraph(int vertex){this.vertex = vertex;data = new char[vertex];matrix = new int[vertex][vertex];}
}

测试代码

package com.learn.bigdata.java.core.arithmetic;import org.junit.Test;public class PrimTest {@Testpublic void prim() {char[] data = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int MAX = Prim.MAX;//邻接矩阵的关系使用二维数组表示,M 这个 表示无穷大的大数,表示两个点不联通//     *  | A  |  B  |  C  |  D  |  E  |  F |  G  |//     A  | M  |  5  |  7  |  M  |  M  |  M |  2  |//     B  | 5  |  M  |  M  |  9  |  M  |  M |  3  |//     C  | 7  |  M  |  M  |  M  |  8  |  M |  M  |//     D  | M  |  9  |  M  |  M  |  M  |  4 |  M  |//     E  | M  |  M  |  8  |  M  |  M  |  5 |  4  |//     F  | M  |  M  |  M  |  4  |  5  |  M |  6  |//     G  | 2  |  3  |  M  |  M  |  4  |  6 |  M  |int[][] weight = new int[][]{{MAX, 5, 7, MAX, MAX, MAX, 2},{5, MAX, MAX, 9, MAX, MAX, 3},{7, MAX, MAX, MAX, 8, MAX, MAX},{MAX, 9, MAX, MAX, MAX, 4, MAX},{MAX, MAX, 8, MAX, MAX, 5, 4},{MAX, MAX, MAX, 4, 5, MAX, 6},{2, 3, MAX, MAX, 4, 6, MAX},};// 生成图MGraph mGraph = new MGraph(data.length);Prim prim = new Prim();prim.createGraph(mGraph, data.length, data, weight);prim.primCore(mGraph, 1); // 3 2 4 5 4 7}
}

Prim算法(JAVA实现-邻接矩阵)相关推荐

  1. 最小生成树Prim算法Java版

    最小生成树Prim算法Java版 算法描述: 在一个加权连通图中,顶点集合V,边集合为E 任意选出一个点作为初始顶点,标记为visit,计算所有与之相连接的点的距离,选择距离最短的,标记visit. ...

  2. 最小生成树Prim算法java实现

    package prim;import java.util.*;public class PrimTest {public static void main(String[] args) {//交互输 ...

  3. Prim算法java实现

    原理简单介绍: 1).输入:一个加权连通图,其中顶点集合为V,边集合为E: 2).初始化:Vertex数组,Vertex作为定点,包含其索引,父节点索引,其与已构建的最小生成树中存在的边中最小权值we ...

  4. 最小生成树之prim算法

    一 背景 二  prim算法java版 package leaning.graph;/** 最小生成树之普里姆算法* */ public class PrimMiniCostSpanningTree ...

  5. Java 版 Prim 算法求最小生成树

    最小生成树: 一个具有n个顶点的加权的无相连通图,用n-1条边连接这n个顶点,并且使得连接之后的所有边的权值之和最小的树. Prim算法:先以一个结点作为最小生成树的第一个结点,然后以迭代的方式找出与 ...

  6. Prim算法求图的最小生成树(Java)

    package Algorithm.prim;import java.util.Arrays;/*** 普利姆算法解决最小生成树问题 Prim算法的实现过程 首先以一个结点作为最小生成树的初始结点,然 ...

  7. 贪婪算法在求解最小生成树中的应用(JAVA)--Prim算法

    贪婪算法:通过一系列步骤来构造问题的解,每一步对目前构造的部分分解做一个拓展,直到获得问题的完整解为止,而算法的核心思想就在于,算法的每一步都必须满足以下条件:可行(满足问题的约束条件).局部最优(当 ...

  8. prim算法详解java_Prim算法(三)之 Java详解

    普里姆算法介绍 普里姆(Prim)算法,是用来求加权连通图的最小生成树的算法. 基本思想 对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G ...

  9. java实现Prim算法

    1 问题描述 何为Prim算法? 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex ...

最新文章

  1. 江西省移动物联网发展战略新闻发布会举行-2017年10月江西IDC排行榜与发展报告...
  2. 《Generative Face Completion》论文笔记
  3. 网络推广期间发现网站快照更新过慢会影响正常网络推广吗?
  4. 基于改进SURF算法的实时视频拼接
  5. hdu 1532(最大流)
  6. class ts 扩展方法_JUnit 5自定义扩展
  7. Linux16.04配置OpenCV3.2
  8. centos 6.5 防火墙开放指定端口
  9. 《海量日志数据分析与应用》场景介绍及技术点分析
  10. 编程之美——3.1字符串移位包含问题
  11. TCP连接的建立和断开
  12. ffmpeg源码简析(八)解码 av_read_frame(),avcodec_decode_video2(),avformat_close_input()
  13. 超详细3D建模教学他来了
  14. python SMTP发送带图片的邮件时,报TypeError: Could not guess image MIME subtype错误的解决办法
  15. ubuntu-20.04.3-详细安装教程(图文)附下载地址
  16. Android9.0系统源码_编译刷机——从下载到编译
  17. Unity3D 实现本地排行榜功能
  18. 蓝牙耳机的LDAC、aptX指的都是什么?
  19. 这几所院校会压分!请注意!
  20. 示波器波形保存至PC端的设置

热门文章

  1. 初步熟悉新webserver goahead
  2. Oracle表中序列号的添加
  3. cellpadding 与cellspace 属性
  4. WebView---android webview组件如何使用 Webview与js交互
  5. Nacos 配置管理
  6. 电脑接显示屏后提示计算机休眠,解决方法:主机正常。电脑显示器(hp)睡眠状态...
  7. JDBC-----什么是JDBC
  8. 《APUE》在Ubuntu上使用apue.h
  9. 2019届校招实习生惨痛经历
  10. 4、OOA 面向对象分析