在上一篇中,我们提到了用来求解边数不是特别多的(例如完全图)生成最小生成树的Kruskal算法。对于稠密图,Kruskal算法的效率不高,这时候我们可以用同样经典的Prim算法求解最小生成树问题。
Prim算法的核心思想是按照当前点集到还未加入的点集的最短边来加入新的点,直到加入n个点来得到最小生成树,设无向连通图有n个顶点。
Prim算法一般包含如下重要步骤:
1. 任意选定一个初始点作为当前点集
2. 求当前点集到还未加入的点集的最短边,并把对应的点加入到当前点集--时间复杂度是 O(n^2)
由此看出,Prim算法总的时间复杂度主要由求点集间最短边决定,所以为 O(n^2) 。
同样,合理的数据结构对于算法的实现十分重要。
主体类:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* 稠密边图的最小生成树的Prim算法实现
* @author ql_math
*
*/
public class PrimForMinimumSpanningTree implements MinimumSpanningTreeGeneration{
/**最小生成树的边的连接*/
private int[][] connectionSatus;
public double generateMinimumSpanningTree(double[][] graphicArray) {
int start_point=1;//可以任意选择一个初始点,这里选择第一个点
SimpleGraphics graph=new SimpleGraphics(graphicArray);
List<Integer> current_set=new LinkedList<Integer>();//当前点集合
current_set.add(start_point);
initPointsConnectionSatus(graph.getPSize(),start_point);//初始化最小生成树的边的连接
int i=1;
double shortestLength=0;
while(i<graph.getPSize())//贪心思想加入和当前点集合最近距离的某个点p
{
shortestLength+=getShortestPointsPair(connectionSatus, current_set,graph);
i++;
}
return shortestLength;
}
public int[][] getConnectionSatus() {
return connectionSatus;
}
/**
* 获得和当前点集合最近距离的某个点p,返回对应的距离
* @param connectionSatus
* @param current_set
* @param graph
* @return
*/
private double getShortestPointsPair(int[][] connectionSatus, List<Integer> current_set, SimpleGraphics graph) {
double minLength=Double.MAX_VALUE;
int[] pair=new int[2];
for(Integer i:current_set)
{
double[] arr=graph.getAdjacencyPoints(i);//获得与当前点连接的点集合
for(int j=0; j<graph.getPSize();j++)
{
if(arr[j]>graph.ERROR&&!current_set.contains(j))
{
if(arr[j]<minLength)
{
minLength=arr[j];
pair[1]=j;
pair[0]=i;
}
}
}
}
current_set.add(pair[1]);//加入新的点
connectionSatus[pair[1]][1]=pair[0];//更新最小生成树的边的连接
return minLength;
}
/**
* 初始化最小生成树的边的连接(所有点都与初始选择点连接)
* @param graph
* @param start_point
* @return
*/
private int[][] initPointsConnectionSatus(int pSize,
int start_point) {
connectionSatus=new int[pSize][2];
for(int i=0;i<pSize;i++)
connectionSatus[i]=new int[]{i,start_point};
return connectionSatus;
}
public String toString()
{
StringBuffer stf=new StringBuffer();
for(int[] i: connectionSatus)
{
stf.append(Arrays.toString(i)+"\r\n");
}
return stf.toString();
}
/**
* @param args
*/
public static void main(String[] args) {
MinimumSpanningTreeGeneration st=new PrimForMinimumSpanningTree();
double[][] graphicArray={{0,0,300,80,50},{0,0,70,75,200},
{300,70,0,60,0},{80,75,60,0,90},{50,200,0,90,0}};
System.out.println("最小生成树的权值和是:"+st.generateMinimumSpanningTree(graphicArray));
System.out.println("最小生成树的连接情况是:\r\n"+st.toString());
}
}
分享到:
相关推荐
根据给定的文件信息,本篇内容将围绕“数据结构实验报告9-图-Prim算法求最小生成树”展开,具体涉及的知识点包括Prim算法的基本原理及其应用、图的邻接矩阵存储结构的设计与实现、最小生成树的概念及求解过程、以及...
Kruskal算法同样基于贪心策略,但它的核心是按照边的权重对所有边进行排序,然后依次选择未造成环路的边加入到最小生成树中。具体步骤如下: 1. 将所有边按权重升序排序。 2. 初始化一个并查集(Disjoint Set)数据...
### 使用Prim和Kruskal算法构建最小生成树 在图论中,最小生成树(Minimum Spanning Tree, ...这两种算法都是通过贪心策略来构建最小生成树,最终得到的最小生成树将覆盖图中的所有顶点,并且其所有边的权重之和最小。
Prim算法是一种贪心策略,它从一个起始顶点开始,逐步添加边,每次添加一条与已选择顶点集形成最小权重边的新边。这个过程不断进行,直到所有的顶点都被包含在内,形成一棵树。算法的关键在于维护一个优先队列(如...
### 图的最小生成树Prim算法详解 在计算机科学与图论中,图的最小生成树(Minimum Spanning Tree,MST)是一个加权无向图的子图,它包含图中的所有顶点,并且所有边的权重之和最小。Prim算法是一种贪心算法,用于...
prim算法求最小生成树这个代码假设图使用邻接矩阵表示,图的节点数为`num_nodes`,`graph`是一个二维数组,`graph[i][j]`表示节点i和节点j之间的边的权重。返回值是一个列表,列表中的每个元素是一条边,表示最小...
Prim算法和Kruskal算法是两种常用求解最小生成树的算法。 1. **Prim算法**: Prim算法是从一个顶点开始,逐步扩展生成树,每次添加一条与当前生成树相连且权值最小的边。它以贪心策略为基础,确保每一步都选择...
在实际应用中,比如网络设计和优化问题中,Prim算法和Kruskal算法是最常用的两种求解最小生成树的策略。Prim算法从顶点开始构建最小生成树,逐步增加边直到包括所有顶点,且每次增加的边会使得树的总权重最小;...
Kruskal算法是一种贪心算法,用于求解无向加权图的最小生成树。它是由Joseph Kruskal于1956年提出的。该算法的核心思想是从图的所有边中选取最小权重的边加入到生成树中,只要这条边不构成环路即可。通过不断重复这...
最小生成树(Minimum Spanning Tree, MST)是图论中的一个重要概念,用于寻找连接图中所有顶点的边的集合,使得这些边的总权重最小。在计算机科学中,MST算法常用于解决网络设计、资源分配等问题。本文主要讨论两种...
要解决最小生成树问题,两种著名的贪心算法——Prim算法和Kruskal算法被广泛采用。这两种算法都是基于贪心策略,即在每一步中选择当前最优的选择,以期最终达成全局最优解。 **Prim算法**的核心在于从某个顶点开始...
Prim算法是求解最小生成树的一种贪心算法,它是由美国计算机科学家罗伯特·C·普里姆(Robert C. Prim)在1957年提出的。Prim算法的基本思想是从图中的某一顶点开始,逐步增加新的顶点和边,直到所有顶点都被包含...
Prim算法是从一个初始顶点开始,逐步扩展生成树,每次添加一条与当前生成树连接且权值最小的边。这个过程持续到所有顶点都被包含在内。在C++中,可以使用优先队列(如`std::priority_queue`)来高效地找到最小边,...
Kruskal和Prim算法都是求解最小生成树的有效方法,但各有优缺点。Kruskal算法更适合稀疏图,因为它的时间复杂度为O(E log E),而Prim算法则适用于所有类型的图,特别是稠密图,因为其时间复杂度可以达到O(E log V)。...
因此,Prim算法适合求解稠密图的最小生成树。 2. Kruskal 算法 Kruskal算法是另一种常用的构造最小生成树的方法。该算法的思想是,先构造一个只含n个顶点,而边集为空的子图,然后从图的边集中选取一条权值最小的...
Prim算法是一种贪心算法,它从图中的任意一个顶点开始,逐步将顶点加入到生成树中,每次都选择与当前树连接且权重最小的边。以下是Prim算法的步骤: - 从图中选择一个顶点作为起点,将其添加到生成树中。 - 找出未...
Prim算法是一种用于求解无向图最小生成树的贪心算法,由Vojtech Jarník在1930年提出,后被Edsger Dijkstra改进并推广。该算法从一个初始顶点开始,逐步扩展生成树,每次添加一条使得生成树与图中尚未包含在树内的...
Prim算法是图论中一个经典的最小生成树问题的解决方法之一,通常使用贪心策略来构建最小生成树。本报告旨在详细探讨贪心算法的基本概念、原理以及在Prim算法中的具体应用,并结合实际编程经验进行深入分析。 #### ...
在本课程设计中,我们重点关注的是PRIM算法,这是一种经典的求解最小生成树的算法。Prim算法由Vojtěch Jarník于1930年提出,后由Roy V. Prim于1957年再次独立发现,因此得名。它的基本思想是从图中任意选择一个...