目录

1 问题描述

2 解决方案

2.1 贪心法

 


1 问题描述

何为Prim算法?

此处引用网友博客中一段介绍(PS:个人感觉网友的这篇博客对于Prim算法讲解的很清楚,本文与之相区别的地方在于具体实现代码的不同,该网友是使用C++实现,而本文是使用Java实现。其他理论讲解可以参考该网友的博客哦,具体链接看文末参考资料)

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

原理简单介绍:

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;

2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;

3).重复下列操作,直到Vnew = V:

a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。

2 解决方案

2.1 贪心法

本文具体编码使用数据参考自《算法设计与分析基础》第三版,下面是其具体图示:

具体代码如下:

package com.liuzhen.chapter8;

import java.util.ArrayList;

public class Prim {
/*
* 参数G:给定的图,其顶点分别为0~G.length-1,相应权值为具体元素的值
* 函数功能:返回构造生成的最小生成树,以二维数组形式表示,其中元素为0表示最小生成树的边
*/
public void getMinTree(int[][] G) {
int[][] result = G;
int[] vertix = new int[G.length]; //记录顶点是否被访问,如果已被访问,则置相应顶点的元素值为-2
for(int i = 0;i < G.length;i++)
vertix[i] = i;
ArrayList<Integer> listV = new ArrayList<Integer>(); //保存已经遍历过的顶点
listV.add(0); //初始随意选择一个顶点作为起始点,此处选择顶点0
vertix[0] = -2; //表示顶点0被访问
while(listV.size() < G.length) { //当已被遍历的顶点数等于给定顶点数时,退出循环
int minDistance = Integer.MAX_VALUE; //用于寻找最小权值,初始化为int最大值,相当于无穷大的意思
int minV = -1; //用于存放未被遍历的顶点中与已被遍历顶点有最小权值的顶点
int minI = -1; //用于存放已被遍历的顶点与未被遍历顶点有最小权值的顶点 ;即G[minI][minV]在剩余的权值中最小
for(int i = 0;i < listV.size();i++) { //i 表示已被访问的顶点
int v1 = listV.get(i);
for(int j = 0;j < G.length;j++) {
if(vertix[j] != -2) { //满足此条件的表示,顶点j未被访问
if(G[v1][j] != -1 && G[v1][j] < minDistance) {//G[v1][j]值为-1表示v1和j是非相邻顶点
minDistance = G[v1][j];
minV = j;
minI = v1;
}
}
}
}
vertix[minV] = -2;
listV.add(minV);
result[minI][minV] = 0;
result[minV][minI] = 0;
}
System.out.println("使用Prim算法,对于给定图中的顶点访问顺序为:");
System.out.println(listV);
System.out.println("使用Prim算法,构造的最小生成树的二维数组表示如下(PS:元素为0表示树的边):");
for(int i = 0;i < result.length;i++) {
for(int j = 0;j < result[0].length;j++)
System.out.print(result[i][j]+"\t");
System.out.println();
}
} public static void main(String[] args) {
Prim test = new Prim();
int[][] G = {{-1,3,-1,-1,6,5},
{3,-1,1,-1,-1,4},
{-1,1,-1,6,-1,4},
{-1,-1,6,-1,8,5},
{6,-1,-1,8,-1,2},
{5,4,4,5,2,-1}};
test.getMinTree(G);
}

运行结果:

使用Prim算法,对于给定图中的顶点访问顺序为:
[0, 1, 2, 5, 4, 3]
使用Prim算法,构造的最小生成树的二维数组表示如下(PS:元素为0表示树的边):
-1 0 -1 -1 6 5
0 -1 0 -1 -1 0
-1 0 -1 6 -1 4
-1 -1 6 -1 8 0
6 -1 -1 8 -1 0
5 0 4 0 0 -1

参考资料:

1.《算法设计与分析基础》第3版  Anany Levitin 著 潘彦 译

2.最小生成树-Prim算法和Kruskal算法

算法笔记_054:Prim算法(Java)的更多相关文章

  1. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

  2. 数据结构与算法--最小生成树之Prim算法

    数据结构与算法--最小生成树之Prim算法 加权图是一种为每条边关联一个权值或称为成本的图模型.所谓生成树,是某图的一棵含有全部n个顶点的无环连通子图,它有n - 1条边.最小生成树(MST)是加权图 ...

  3. 算法起步之Prim算法

    原文:算法起步之Prim算法 prim算法是另一种最小生成树算法.他的安全边选择策略跟kruskal略微不同,这点我们可以通过一张图先来了解一下. prim算法的安全边是从与当前生成树相连接的边中选择 ...

  4. 一步一步写算法(之prim算法 下)

    原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...

  5. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  6. 一步一步写算法(之prim算法 上)

    原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...

  7. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  8. 算法笔记_018:旅行商问题(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 减治法 2.2.1 Johson-Trotter算法 2.2.2 基于字典序的算法   1 问题描述 何为旅行商问题?按照非专业的说法,这个问 ...

  9. 算法笔记_066:Kruskal算法详解(Java)

    目录 1 问题描述 2 解决方案 2.1 构造最小生成树示例 2.2 伪码及时间效率分析 2.3 具体编码(最佳时间效率)   1 问题描述 何为Kruskal算法? 该算法功能:求取加权连通图的最小 ...

随机推荐

  1. CentOS中Ctrl+Z、Ctrl+C、Ctrl+D的区别

    Ctrl+C和Ctrl+Z都是中断命令,但作用不同. Ctrl+C是发送SIGINT信号,终止一个进程. Ctrl+Z是发送SIGSTOP信号,挂起一个进程,将作业放置到后台(暂停状态).与此同时,可 ...

  2. Flask实战第57天:UEditor编辑器集成以及配置上传文件到七牛

    相关链接 UEditor:http://ueditor.baidu.com/website/​ 下载地址:http://ueditor.baidu.com/website/download.html# ...

  3. JCL: What is EXCP

      JCL: What is EXCP ?   EXCP stands for EXecute Channel Program. These are the I/O subsystem hardwar ...

  4. 【uva 10294】 Arif in Dhaka (First Love Part 2) (置换,burnside引理|polya定理)

    题目来源:UVa 10294 Arif in Dhaka (First Love Part 2) 题意:n颗珠子t种颜色 求有多少种项链和手镯 项链不可以翻转 手镯可以翻转 [分析] 要开始学置换了. ...

  5. 【POJ 2154】Color

    http://poj.org/problem?id=2154 还是先套上Burnside引理:\[\begin{aligned} ans & =\sum_{i=1}^n n^{(i,n)-1} ...

  6. Java本地方法(native方法)的实现

    Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能. 可以将 ...

  7. (转) Unity3D常用代码收集总结

    //创建一个名为"Player"的游戏物体 //并给他添加刚体和立方体碰撞器. player=new GameObject("Player"); player. ...

  8. SSL协议的握手过程(摘录)

    SSL协议的握手过程 为了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议.SSL 协议既用到了公钥加密技术(非对称加密)又用到了对称加密技术,SSL对传输内容的加密是采用的对 ...

  9. java锁对象

    在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的封锁,用来控制对竞争资源并发访问的控制,这些内容主要集中在java.util.concurrent.locks 包下面,里面有三个重要的接口 ...

  10. Hive技术拾遗

    1. SELECT语句可以使用正则表达式做列选择,下面的语句查询除了ds和h 之外的所有列:SELECT `(ds|hr)?+.+` FROM sales 2. LEFT SEMI JOIN的限制是, ...