目录

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. 可持久化线段树(cf1080F)

    大佬博客 https://www.cnblogs.com/zinthos/p/3899565.html 题目:https://codeforces.com/problemset/problem/108 ...

  2. Luogu P3391 【模板】文艺平衡树(FHQ-Treap)

    题意 给出一个长为$n$序列$[1,2,...,n]$,$m$次操作,每次指定一段区间$[l,r]$,将这段区间翻转,求最终序列 题解 虽然标题是$Splay$,但是我要用$FHQ\ Treap$,考 ...

  3. Codeforces Round #278 (Div. 1) Strip (线段树 二分 RMQ DP)

    Strip time limit per test 1 second memory limit per test 256 megabytes input standard input output s ...

  4. SCU 4444 Travel (补图最短路)

    Travel The country frog lives in has \(n\) towns which are conveniently numbered by \(1, 2, \dots, n ...

  5. jvm 哪些是不会被gc回收的

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com

  6. 【推导】Codeforces Round #410 (Div. 2) C. Mike and gcd problem

    如果一开始就满足题意,不用变换. 否则,如果对一对ai,ai+1用此变换,设新的gcd为d,则有(ai - ai+1)mod d = 0,(ai + ai+1)mod d = 0 变化一下就是2 ai ...

  7. atomic与nonatomic的区别

    原子性(atomic):某操作具备整体性,也就是说,系统其他部分无法观察到其中间步骤所生成的临时结果,而只能看到操作前与操作后的结果,那么就称改操作就是“原子的”(atomic),或者说,该操作具备“ ...

  8. KVC的用法

    示例1:基本赋值取值 @interface Book : NSObject {     NString *name;}@end #import "Book.h"@implement ...

  9. WPF中的动画——(六)演示图板

    前面所介绍的都是单一的动画,它只能修改单一属性.有的时候,我们需要将一组动画一起进行,对于一个按钮,我们可能有如下需求: 选择该按钮时,该按钮增大并更改颜色. 单击该按钮时,该按钮缩小并恢复其原始大小 ...

  10. POJ 2187 Beauty Contest (求最远点对,凸包+旋转卡壳)

    Beauty Contest Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 24283   Accepted: 7420 D ...