• 最小生成树算法prim and kruskal


    一.最小生成树定义:

     从不同顶点出发或搜索次序不同,可得到不同的生成树
     生成树的权:对连通网络来说,边附上权,生成树也带权,我们把生成树各边的权值总和称为生成树的权
     最小代价生成树:在一个连通网的所有生成树中, 各边的代价之和最小的那棵生成树称为该连通网的最小代价生成树(Minimum Cost Spanning Tree),简称为最小生成树(MST)。

    二.最小生成树prim算法

    算法思路:step1:假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于V),TE={}开始。

                  step2:在所有的u属于U,v属于V-U的边(u,v)属于E中找一条代价最小的边(u0,v0)并入集合TE。同时v0并入U。

                  step3:更新边(u,v)的最小值。

                  step4:c重复step2 and step3直到U=V。

    code:

      1 //MiniSpanTree_Prim.cpp
      2 //This function is to create MiniSpanTree_Prim with Prim Algorithm
      3 # include <iostream.h>
      4 # include <malloc.h>
      5 # include <conio.h>
      6 
      7 # define INFINITY 1000
      8 # define MAX_VERTEX_NUM 20
      9 # define OK 1
     10 typedef enum{DG,DN,UDG,UDN} GraphKind;
     11 typedef int EType;
     12 typedef int InfoType;
     13 typedef int VertexType;
     14 typedef int VRType;
     15 typedef int lowcost;
     16 
     17 typedef struct        //define Closedege structure
     18 {   VertexType adjvex;
     19     VRType    lowcost;
     20 }Closedge;
     21 
     22 typedef struct ArcCell    //define MGraph structure
     23 {  EType adj;
     24    InfoType *info;
     25 }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
     26 
     27 typedef struct
     28 {  VertexType vexs[MAX_VERTEX_NUM];
     29    AdjMatrix  arcs;
     30    int vexnum,arcnum;
     31    GraphKind kind;
     32 }MGraph;
     33 
     34 int CreatUDN(MGraph &G)        //CreatUDN() sub-function
     35 {  int IncInfo,i=0,j=0,k,v1,v2,w;
     36    cout<<endl<<"Please input the number of G.vexnum (eg,G.vexnum=4) : ";
     37    cin>>G.vexnum;                  //input the number of vex
     38    cout<<"Please input the number of G.arcnum (eg,G.arcnum=4) : ";
     39    cin>>G.arcnum;        //input the number of arc
     40    for(i=0;i<G.vexnum;++i)
     41      for(j=i;j<G.vexnum;++j)
     42       {     G.arcs[i][j].adj=G.arcs[j][i].adj=INFINITY;    //initial weigh
     43      G.arcs[i][j].info=G.arcs[j][i].info=NULL;
     44       }
     45    cout<<"Please input IncInfo (0 for none)                   : ";
     46    cin>>IncInfo;        //if need information, input non-zero
     47    cout<<"Plese input arc(V1-->V2), For example: (V1=1,V2=3),(V1=2,V2=4)..."<<endl;
     48    for(k=0;k<G.arcnum;++k)    //input arc(v1,v2)
     49    {   cout<<endl<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : ";
     50        cin>>v1;
     51        cout<<"Please input the "<<k+1<<"th arc's v2 (0<v2<G.vexnum) : ";
     52        cin>>v2;
     53        cout<<"Please input the "<<k+1<<"th arc's weight             : ";
     54        cin>>w;
     55        i=v1;
     56        j=v2;
     57        while(i<1||i>G.vexnum||j<1||j>G.vexnum)    //if (v1,v2) illegal
     58        {   cout<<"Please input the "<<k+1<<"th arc's v1 (0<v1<G.vexnum) : ";
     59        cin>>v1;
     60        cout<<"Please input the "<<k+1<<"th arc's v2 (0<v1<G.vexnum) : ";
     61        cin>>v2;
     62        cout<<"Please input the "<<k+1<<"th arc's weight             : ";
     63        cin>>w;
     64        i=v1;
     65        j=v2;
     66        } //while end
     67        i--;
     68        j--;
     69    G.arcs[i][j].adj=G.arcs[j][i].adj=w;        //
     70    cout<<"G.arcs["<<i+1<<"]["<<j+1<<"].adj=";
     71    cout<<"G.arcs["<<j+1<<"]["<<i+1<<"].adj="<<G.arcs[j][i].adj<<endl;
     72    if(IncInfo)
     73      {   cout<<"Please input the "<<k+1<<"th arc's Info : ";
     74      cin>>*G.arcs[i][j].info;        //input information
     75      }
     76    } //for end
     77    return (OK);
     78 } //CreatUDN() end
     79 
     80 int Minimum(Closedge *closedge,int Vexnum)    //Minimum() sub-function
     81 {   int min=1,j;                        //return min (closedge[min].lowcost)
     82     if(closedge[min].lowcost==0)
     83       min++;                //closedge[min].lowcost!=0
     84     for(j=0;j<Vexnum;++j)
     85       if(closedge[j].lowcost<closedge[min].lowcost
     86           &&closedge[j].lowcost>0)
     87     min=j;
     88     return (min);
     89 } //Minimim() end
     90 
     91 int LocatedVex(MGraph G,VertexType u)    //LocatedVex() sub-fuction
     92 {  return (u);
     93 }
     94 
     95 void MiniSpanTree_Prim(MGraph G,VertexType u)    //MiniSpanTree_Prim() sub-function
     96 {  int k,j,i,Vexnum=G.vexnum;
     97    k=LocatedVex(G,u);
     98    Closedge closedge[MAX_VERTEX_NUM];
     99    for(j=0;j<G.vexnum;++j)    //initial closedge[]
    100      if(j!=k)
    101      {    closedge[j].adjvex=u;      // (u,j)
    102     closedge[j].lowcost=G.arcs[k][j].adj;
    103      }
    104    closedge[k].lowcost=0;    //U include k
    105    for(i=1;i<G.vexnum;++i)
    106    {  k=Minimum(closedge,Vexnum);    //select k=min(closedge[vi].lowcost)
    107       cout<<endl<<"("<<closedge[k].adjvex+1<<","<<k+1<<")";
    108       cout<<"="<<G.arcs[closedge[k].adjvex][k].adj;
    109       closedge[k].lowcost=0;    //U include k
    110       for(j=0;j<G.vexnum;++j)   //renew closedge[k]
    111     if(G.arcs[k][j].adj<closedge[j].lowcost)
    112        {  closedge[j].adjvex=k;
    113           closedge[j].lowcost=G.arcs[k][j].adj;
    114        } //if end
    115    } //for end
    116 } //Minimun() end
    117 
    118 void main()              //main() function
    119 {   MGraph G;
    120     VertexType u=0;
    121     cout<<endl<<endl<<"MiniSpanTree_Prim.cpp";
    122     cout<<endl<<"====================="<<endl;
    123     CreatUDN(G);        //call CreatUDN(G) function
    124     cout<<endl<<"The MiniSpanTree_Prim is created as follow order:";
    125     MiniSpanTree_Prim(G,u);    //call MiniSpanTree_Prim() function
    126     cout<<endl<<endl<<"...OK!...";
    127     getch();
    128 } //main() end

    三.最小生成树kruskal算法

    算法思路:step1:假设联通网N=(V,{E}),则领最小生成树的初始状态为只有n个定点而无边的非联通图T=(V,{}),同中每个定点自成一个连通分量。

                  step2:在E中选择代价最小的边,若改边的定点落在T中不同的连通分量上,则将此边加入到T中,否则舍弃此边而选择下一条代价最小的边。

         step3:依次类推知道T中所有定点都在同一连通分量上。

    时间复杂度:O(eloge)

    #include<iostream>
    #include<vector>
    #include<map>
    using namespace std;
    class edge
    {
    public:
        edge(char a,char b,int wight):ma(a),mb(b),mwight(wight){}
        edge(const edge &other)
        {
            ma = other.ma;
            mb = other.mb;
            mwight = other.mwight;
        }
        edge & operator=(const edge & other)
        {
            ma = other.ma;
            mb = other.mb;
            mwight = other.mwight;
            return *this;
        }
        char getma()
        {
            return ma;
        }
        char getmb()
        {
            return mb;
        }
    private:
        char ma;
        char mb;
        int mwight;
    };
    
    void  kruskal(vector<edge> & edges,map<char,int> & vertexs,vector<edge> &myedge)
    {
        
        vector<edge>::iterator begin = edges.begin();
        for (;begin != edges.end(); begin++)
        {
            int vera = vertexs[begin->getma()];
            int verb = vertexs[begin->getmb()];
            if ( vera != verb)
            {
                myedge.push_back(*begin);
                map<char,int>::iterator item = vertexs.begin();
                for(;item != vertexs.end();item++)
                {
                    if (item->second == vera)
                    {
                        item->second = verb;
                    }
                }        
            }
        }
    }
    
    void main()
    {
        char ch;
        int i;
        edge edges[] = {
            edge('a','c',1),
            edge('d','f',2),
            edge('b','e',3),
            edge('c','f',4),
            edge('a','d',5),
            edge('c','d',5),
            edge('c','b',5),
            edge('a','b',6),
            edge('c','e',6),
            edge('c','f',6)
        };
        map<char,int> vertex;
        vector<edge> myedges(edges,edges+sizeof(edges)/sizeof(edge)),result;
        for( ch='a', i =0;i<6;ch++,i++)
        {
            vertex.insert(std::pair<char,int>(ch,i));
        }
        kruskal(myedges,vertex,result);
        for (vector<edge>::iterator start = result.begin(); start != result.end(); start++)
        {
            cout<<start->getma()<<"--"<<start->getmb()<<" "<<endl;
        }
    }
  • 相关阅读:
    最大化等比例测试演化Demo-传统方法
    Layout-3相关代码:3列布局代码演化三]
    Layout-3相关代码:3列布局代码演化[二]
    Layout-2相关代码:3列布局代码演化[一]
    Layout-1相关代码
    【比赛打分展示双屏管理系统-专业版】Other.ini 配置文件解读以及排行榜界面及专家评语提交展示等具体配置
    Android 开源简单控件
    Android Drawable资源
    Android Service与Thread的区别
    Android事件处理
  • 原文地址:https://www.cnblogs.com/churi/p/3691720.html
Copyright © 2020-2023  润新知