有一个连通图G(V,E)并给出了每个边的权重或成本。Kruskal的算法将使用图形和成本找到最小生成树。
这是合并树方法。最初,有不同的树,此算法将采用成本最小的那些边合并它们,并形成一棵树。
在此问题中,所有边均根据其成本列出并排序。从列表中,取出成本最低的边并添加到树中,然后每一次检查是否形成边,如果形成一个循环,则从列表中丢弃边并移至下一条边。
该算法的时间复杂度为O(E log E)或O(E log V),其中E是许多边,V是许多顶点。
Input: Adjacency matrixOutput: Edge: B--A And Cost: 1 Edge: E--B And Cost: 2 Edge: F--E And Cost: 2 Edge: C--A And Cost: 3 Edge: G--F And Cost: 3 Edge: D--A And Cost: 4 Total Cost: 15
kruskal(g: Graph, t: Tree)
输入-给定图g和空树t
输出-具有选定边的树t
Begin create set for each vertices in graph g for each set of vertex u do add u in the vertexSet[u] done sort the edge list. count := 0 while count <= V – 1 do //as tree must have V – 1 edges ed := edgeList[count] //take an edge from edge list if the starting vertex and ending vertex of ed are in same set then merge vertexSet[start] and vertexSet[end] add the ed into tree t count := count +1 done End
#include<iostream> #define V 7 #define INF 999 using namespace std; //图的成本矩阵 int costMat[V][V] = { {0, 1, 3, 4, INF, 5, INF}, {1, 0, INF, 7, 2, INF, INF}, {3, INF, 0, INF, 8, INF, INF}, {4, 7, INF, 0, INF, INF, INF}, {INF, 2, 8, INF, 0, 2, 4}, {5, INF, INF, INF, 2, 0, 3}, {INF, INF, INF, INF, 4, 3, 0} }; typedef struct { int u, v, cost; }edge; void swapping(edge &e1, edge &e2) { edge temp; temp = e1; e1 = e2; e2 = temp; } class Tree { int n; edge edges[V-1]; //as a tree has vertex-1 edges public: Tree() { n = 0; } void addEdge(edge e) { edges[n] = e; //add edge e into the tree n++; } void printEdges() { //print edge, cost and total cost int tCost = 0; for(int i = 0; i<n; i++) { cout << "Edge: " << char(edges[i].u+'A') << "--" <<char(edges[i].v+'A'); cout << " And Cost: " << edges[i].cost << endl; tCost += edges[i].cost; } cout << "Total Cost: " << tCost << endl; } }; class VSet { int n; int set[V]; //a set can hold maximum V vertices public: VSet() { n = -1; } void addVertex(int vert) { set[++n] = vert; //add vertex to the set } int deleteVertex() { return set[n--]; } friend int findVertex(VSet *vertSetArr, int vert); friend void merge(VSet &set1, VSet &set2); }; void merge(VSet &set1, VSet &set2) { //将两个顶点集合并在一起 while(set2.n >= 0) set1.addVertex(set2.deleteVertex()); //addToSet(vSet1,delFromSet(vSet2)); } int findVertex(VSet *vertSetArr, int vert) { //在不同的顶点集中找到顶点 for(int i = 0; i<V; i++) for(int j = 0; j<=vertSetArr[i].n; j++) if(vert == vertSetArr[i].set[j]) return i; //node found in i-th vertex set } int findEdge(edge *edgeList) { //从Graph的成本矩阵中找到边并存储到edgeList- int count = -1, i, j; for(i = 0; i<V; i++) for(j = 0; j<i; j++) if(costMat[i][j] != INF) { count++; //填充位置“计数”的边缘列表 edgeList[count].u = i; edgeList[count].v = j; edgeList[count].cost = costMat[i][j]; } return count+1; } void sortEdge(edge *edgeList, int n) { //以成本的升序对图的边缘进行排序 int flag = 1, i, j; for(i = 0; i<(n-1) && flag; i++) { //modified bubble sort is used flag = 0; for(j = 0; j<(n-i-1); j++) if(edgeList[j].cost > edgeList[j+1].cost) { swapping(edgeList[j], edgeList[j+1]); flag = 1; } } } void kruskal(Tree &tr) { int ecount, maxEdge = V*(V-1)/2; //max n(n-1)/2 edges can have in a graph edge edgeList[maxEdge], ed; int uloc, vloc; VSet VSetArray[V]; ecount = findEdge(edgeList); for(int i = 0; i < V; i++) VSetArray[i].addVertex(i); //each set contains one element sortEdge(edgeList, ecount); //ecount number of edges in the graph int count = 0; while(count <= V-1) { ed = edgeList[count]; uloc = findVertex(VSetArray, ed.u); vloc = findVertex(VSetArray, ed.v); if(uloc != vloc) { //check whether source abd dest is in same set or not merge(VSetArray[uloc], VSetArray[vloc]); tr.addEdge(ed); } count++; } } int main() { Tree tr; kruskal(tr); tr.printEdges(); }
输出结果
Edge: B--A And Cost: 1 Edge: E--B And Cost: 2 Edge: F--E And Cost: 2 Edge: C--A And Cost: 3 Edge: G--F And Cost: 3 Edge: D--A And Cost: 4 Total Cost: 15
最小生成树的Kruskal算法 描述:有A、B、C、D四个点,每两个点之间的距离(无方向)是(第一个数字是两点之间距离,后面两个字母代表两个点):(1,’A’,’B’),(5,’A’,’C’),(3,’A’,’D’),(4,’B’,’C’),(2,’B’,’D’),(1,’C’,’D’) 生成边长和最小的树,也就是找出一种连接方法,将各点连接起来,并且各点之间的距离和最小。 思路说明: Krusk
这里有一个图,我需要用Prim和Kruskal的算法找到G的最小生成树。 我用普里姆的算法找到了最小生成树。这是我的尝试。 我很难用Kruskal的算法找到最小生成树。我看过许多与Kruskal的图算法相关的视频,但最终得到的图与Prim的算法相同。 谁能给我演示一下如何用Kruskal的算法找到图的最小生成树吗?
问题 用Kruskal算法求无向图 G 的最小生成树。 解法 Kruskal算法是一种贪心算法。初始时将图 G 的边集 E 按照权值,从小到大进行排序,并且生成树。从最小权值的边开始,依次考虑每一条边,对于边 e_i 来说,若将它加入生成树集合 S 中, e_i 不会与 S 中已有的边形成环,那么选取边 e_i 作为生成树中的一条边,将其加入集合 S ;反之若将 e_i 加入 S 中会与已有的边形
本文向大家介绍python最小生成树kruskal与prim算法详解,包括了python最小生成树kruskal与prim算法详解的使用技巧和注意事项,需要的朋友参考一下 kruskal算法基本思路:先对边按权重从小到大排序,先选取权重最小的一条边,如果该边的两个节点均为不同的分量,则加入到最小生成树,否则计算下一条边,直到遍历完所有的边。 prim算法基本思路:所有节点分成两个group,一个为
主要内容:生成树,最小生成树数据结构提供了 3 种存储结构,分别称为线性表、树和图,如图 1 所示。 图 1 3 种存储结构 a) 是线性表,b) 是树,c) 是图。 在图存储结构中,a、b、c 等称为顶点,连接顶点的线称为边。 线性表是最简单的存储结构,很容易分辨。树和图有很多相似之处,它们的区别是:树存储结构中不允许存在环路,而图存储结构中可以存在环路(例如图 1 c) 中,c-b-f-c、b-a-f-b 等都是环路)。
最小生成树 一个有 n 个结点的带权无向图,在满足所有顶点都连接的前提下使得所有的边的权总和最小,即为最小生成树(Minimum Spanning Tree MST)。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。 N个顶点,一定有N-1条边 包含所有顶点 所有顶点都可以直接或间接连接到另外的顶点 普里姆算法 普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找