Prim算法实现最小生成树MST

来源:互联网 发布:java netty websocket 编辑:程序博客网 时间:2024/06/12 01:17

//实现文件

#include <queue>#include <vector>#include <list>#include <cassert>#include <iostream>using namespace std;//用STL中的优先队列实现namespace prim_priority{const static int MAX_VERTEX_NUM = 100;const static int INVALID_VNAME = -1;const static double INVALID_LENGTH = 10000.0;typedef struct _Node {int vname;int vname_pre;double len;_Node(void){vname = INVALID_VNAME;vname_pre = INVALID_VNAME;len = INVALID_LENGTH;}_Node(int v, int v_pre, double l):vname(v),vname_pre(v_pre),len(l){}}Node, *pNode;class Cmp{public:bool operator()(const Node &l, const Node &r){return l.len > r.len;}};vector< list<Node> > vGraph;//graphvector<Node> vPath;double iMinPathLen;//min tree path lengthint iVertexNum;double Prim(void){iVertexNum = vGraph.size()-1;assert(iVertexNum<MAX_VERTEX_NUM);vPath.clear();iMinPathLen = 0;priority_queue< Node, vector<Node>, Cmp > pq;bool used[MAX_VERTEX_NUM];memset(used, false, sizeof(used));int iUsedNum(0), iCurVertex(1);Node tmp;iUsedNum = 1;used[iCurVertex] = true;while ( iUsedNum<iVertexNum ){for ( list<Node>::iterator it=vGraph[iCurVertex].begin(); it!=vGraph[iCurVertex].end(); ++it){if ( !used[it->vname])pq.push(*it);}while (!pq.empty() && !(used[(Node(pq.top())).vname_pre] && !used[(Node(pq.top())).vname]) )pq.pop();if (pq.empty())break;tmp = pq.top();pq.pop();vPath.push_back(tmp);iMinPathLen += tmp.len;used[tmp.vname] = true;iCurVertex = tmp.vname;++iUsedNum;}return iMinPathLen;}void PrintMinPath(void){cout << "minpath: " << iMinPathLen << endl;}void PrintPath(void){cout << "path selection process" << endl;for ( unsigned int i=0; i<vPath.size(); ++i )cout << vPath[i].vname_pre << "-->" << vPath[i].vname << "("<< vPath[i].len <<")" << endl;}void PrintResult(void){PrintPath();PrintMinPath();}void PrintGraph(void){cout << "graph:" << endl;int i(1);vector<list<Node> >::iterator it=vGraph.begin();for ( ++it; it!=vGraph.end(); ++it){cout << i << ": ";for ( list<Node>::iterator l=(*it).begin();l!=(*it).end(); ++l)cout << l->vname << "("<< l->len << ") ";cout << endl;++i;}}};//普通实现方式namespace prim_simple{const static int MAX_VERTEX_NUM = 100;const static int INVALID_VERTEX = -1;const static double INVALID_WEIGHT = 100000.0;typedef struct _TreeEdge{int v1;int v2;double w;_TreeEdge(int _v1, int _v2, double _w):v1(_v1), v2(_v2), w(_w){}_TreeEdge(void){v1 = v2 = INVALID_VERTEX;w = INVALID_WEIGHT;}}TreeEdge;typedef struct _ChosenEdge{int v2;double w;_ChosenEdge(void){v2 = INVALID_VERTEX;w = INVALID_WEIGHT;}}ChosenEdge;double vGraph[MAX_VERTEX_NUM][MAX_VERTEX_NUM];TreeEdge vMSTree[MAX_VERTEX_NUM];ChosenEdge vCEdge[MAX_VERTEX_NUM];bool vbInTree[MAX_VERTEX_NUM];int iVertexNum;double dMinWPath;double Prim(void){//initmemset( vbInTree, false, sizeof(vbInTree));dMinWPath = 0.0;assert(iVertexNum>0 && iVertexNum<MAX_VERTEX_NUM);int i(1);for ( ;i<iVertexNum; ++i ){vCEdge[i].v2 = 1;vCEdge[i].w = vGraph[i][1];}vMSTree[1].v1 = 1;vMSTree[1].v2 = 0;vMSTree[1].w = -1.0;vbInTree[1] = true;//calcint j(0), k(0);for ( i=2; i<=iVertexNum; ++i){for ( k=1; k<=iVertexNum && vbInTree[k]; ++k);if ( k>iVertexNum )break;for ( j=k; j<=iVertexNum; ++j){if ( !vbInTree[j] && vCEdge[k].w>vCEdge[j].w )k = j;}//addvMSTree[i].v1 = k;vMSTree[i].v2 = vCEdge[k].v2;vMSTree[i].w  = vCEdge[k].w;dMinWPath += vCEdge[k].w;vbInTree[k] = true;//adjustfor ( j=1; j<=iVertexNum; ++j ){if ( !vbInTree[j] && vCEdge[j].w>vGraph[j][k]){vCEdge[j].w = vGraph[j][k];vCEdge[j].v2 = k;}}}return dMinWPath;}void PrintMinPath(void){cout << "minpath: " << dMinWPath << endl;}void PrintPath(void){cout << "path selection process" << endl;for ( int i=1; i<=iVertexNum; ++i ){cout << vMSTree[i].v2 << "-->" << vMSTree[i].v1<< "("<< vMSTree[i].w <<")" << endl;}}void PrintResult(void){PrintPath();PrintMinPath();}void PrintGraph(void){cout << "graph:" << endl;for (int i=1; i<=iVertexNum; ++i){cout << i <<": ";for ( int j=1; j<=iVertexNum; ++j){if ( vGraph[j][i]<INVALID_WEIGHT ){cout<< j <<"(" << vGraph[j][i] << ") ";}}cout << endl;}}void PrintAll(void){PrintGraph();PrintResult();}};


//测试文件

#include <iostream>#include <cstdlib>#include "Prim.h"using namespace std;int main(){//测试优先队列实现的Prim算法{using namespace prim_priority;cout << "prim_priority" << endl;list<Node> l;//v0l.push_back(Node(-1, 0, -1));vGraph.push_back(l);//v1l.clear();l.push_back(Node(2, 1, 2));l.push_back(Node(3,1, 4));l.push_back(Node(4,1, 1));vGraph.push_back(l);//v2l.clear();l.push_back(Node(1,2, 2));l.push_back(Node(4,2, 3));l.push_back(Node(5,2, 10));vGraph.push_back(l);//v3l.clear();l.push_back(Node(1,3, 4));l.push_back(Node(4, 3,2));l.push_back(Node(6,3, 5));vGraph.push_back(l);//v4l.clear();l.push_back(Node(1, 4,1));l.push_back(Node(2, 4,3));l.push_back(Node(3, 4,2));l.push_back(Node(5,4, 7));l.push_back(Node(6, 4,8));l.push_back(Node(7, 4,4));vGraph.push_back(l);//v5l.clear();l.push_back(Node(2, 5,10));l.push_back(Node(4, 5,7));l.push_back(Node(7, 5,6));vGraph.push_back(l);//v6l.clear();l.push_back(Node(3, 6,5));l.push_back(Node(4, 6,8));l.push_back(Node(7, 6,1));vGraph.push_back(l);//v7l.clear();l.push_back(Node(4, 7,4));l.push_back(Node(5, 7,6));l.push_back(Node(6, 7,1));vGraph.push_back(l);Prim();PrintGraph();PrintResult();}cout << endl;//测试普通方式实现的Prim算法{using namespace prim_simple;cout << "prim_simple" << endl;iVertexNum = 7;for ( int i=0; i<MAX_VERTEX_NUM*MAX_VERTEX_NUM; ++i)vGraph[i/MAX_VERTEX_NUM][i%MAX_VERTEX_NUM] = INVALID_WEIGHT;//v1vGraph[2][1] = 2;vGraph[3][1] = 4;vGraph[4][1] = 1;//v2vGraph[1][2] = 2;vGraph[4][2] = 3;vGraph[5][2] = 10;//v3vGraph[1][3] = 4;vGraph[4][3] = 2;vGraph[6][3] = 5;//v4vGraph[1][4] = 1;vGraph[2][4] = 3;vGraph[3][4] = 2;vGraph[5][4] = 7;vGraph[6][4] = 8;vGraph[7][4] = 4;//v5vGraph[2][5] = 10;vGraph[4][5] = 7;vGraph[7][5] = 6;//v6vGraph[3][6] = 5;vGraph[4][6] = 8;vGraph[7][6] = 1;//v7vGraph[4][7] = 4;vGraph[5][7] = 6;vGraph[6][7] = 1;Prim();PrintAll();}system("pause");return 0;}


原创粉丝点击