zoukankan      html  css  js  c++  java
  • 最小生成树(MST)

    转自:https://www.cnblogs.com/fanmu/p/6082152.html

    最小生成树

    1.定义

    2.kruskal 算法

    3.Prim 算法

    1.定义

    G=(V,E)为连通无向图,V为结点的集合,E为结点的可能连接边

    对每条边(u ,v)都赋予权重w(u ,v)

    目标:找到一个无环子集T, 既能将所有结点连接起来,又具有最小权重。

    T是由G生成的树,并把这种问题叫做最小生成树问题。

    2.kruskal算法

    主要思想:

    将V的每个结点定义为一棵树,并定义根节点(代表)为该节点,将E中的边按权重从小到大依次处理。

    首先判断边的两个结点是否属于同一棵树(根据根节点是否一致),若不是,则合并两棵树,并更新根节点;若是,则不予理会。

    (这里是为了形成无环集合,保证权重和最小

    如下图f所示,结点i、g已合并为一棵树,根节点一致,所以ig边不再纳入集合)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    global G
    G.VV=char(97:105);
    G.V=cell(9,1);
    G.Adj={'ab';'ah';'bc';'bh';'hi';'hg';'ig';'gf';'cf';'cd';'df';'de';'ef';'ic'};
    G.Bdj=[4;8;8;11;7;1;6;2;4;7;14;9;10;2];
    A=[];
    for i=1:length(G.VV) %MAKE-SET
        G.V{i}.p=G.VV(i);
        G.V{i}.rank=0;
    end
    [wei,index]=sort(G.Bdj);
    la=G.Adj(index);
    for i=1:length(la)
        x=la{i};
        a1=find(G.VV==x(1));
        a2=find(G.VV==x(2));
        if find_set(a1)~=find_set(a2)
            A=[A;x];
            union(a1,a2);
        end
    end
     
     
    function  k= find_set(i)
    %找到集合的代表,也就是根节点
    global G
    if G.V{i}.p~=G.VV(i)%这里的G.V{i}.p是G.VV(i)所在子树的根节点
        %函数的目标是找到合并之后的树(集合)的的结点
        j=find(G.VV==G.V{i}.p);
        G.V{i}.p=find_set(j);%不断更新,直到找到集合的根节点
    end
    k=G.V{i}.p;
    end
     
    function union(i,a)
    %合并两个集合,并更新集合的根节点
    %更新的原则是看子树的结点数目,多的那个的子树的代表当根节点
    %注意,这里并没有更新子树的根节点,这一步骤是在find_set里完成的
    global G
    x=find_set(i);
    y=find_set(a);
    aa=find(G.VV==x);
    bb=find(G.VV==y);
    if G.V{aa}.rank>G.V{bb}.rank
        G.V{bb}.p=G.VV(aa);
    else
        G.V{aa}.p=G.VV(bb);
        if G.V{aa}.rank==G.V{bb}.rank
            G.V{bb}.rank=G.V{bb}.rank+1;
        end
    end 
    end

      

    运行结果:

    A =

    hg
    gf
    ic
    ab
    cf
    cd
    ah
    de

    d=37

    3.prim 算法

    关于轻量级边的定义:

    主要思想:

    给定连通图G和任意根节点r,最小生成树从结点r开始,一直长大到覆盖V中所有结点为止,即不断寻找轻量级边以实现最小权重和

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    %最小生成树-prim算法
    G.VV=char(97:105);
    G.Adj={'bh';'ahc';'bifd';'cfe';'df';'cdeg';'ihf';'abig';'cgh'};%邻接链表
    G.Bdj={[4 8];[4 11 8];[8 2 4 7];[7 14 9];[9 10];[4 14 10 2];[6 1 2];[8 11 7 1];[2 6 7]};%邻接链表对应权重
    Q=G.VV;
    Q(Q==G.VV(1))=[];
    r=1;
    x(r)=G.VV(1);%给定初始点
    d=0;
     
    while length(Q)~=0
        [wei,index]=sort(unionwei(G,x,r));%!!!关键点,目的是横跨(V-Q,Q)的轻量级边的一个端点,即权重最小的一个点
        u=unionla(G,x,r);
        u=u(index);
        for i=1:length(u)
            if find(Q==u(i))
                k=i;
                break;
            end
        end
        d=d+wei(k);
        r=r+1;
        x(r)=u(k);
             
        Q(Q==u(k))=[];%找到后Q中删除,以保证每个点只被访问一次
    end
    fprintf('path:');x
    fprint(' ');
    fprintf('d= %d ',d);
     
     
    function wei0=unionwei( G,x,r )
    %合并权重向量,方便排序
    wei0=[];
    for i=1:r
        a=find(G.VV==x(i));
        wei1=G.Bdj{a};
        wei0=[wei0 wei1];
    end
    end
     
    function la0 = unionla(G,x, r )
    %合并权重对应的边
    la0=[];
    for i=1:r
        a=find(G.VV==x(i));
        la1=G.Adj{a};
        la0=[la0 la1];
    end
    end

      

      

    运行结果:

    path:
    x =

    abhgfcide


    d= 37

  • 相关阅读:
    模块化+定制化,PIX赋能多种行业实现低速无人车商业化
    支持Apollo、Autoware,PIX推出自动驾驶开发套件PIXKIT
    专为自动驾驶开发者打造的线控底盘——PIXLOOP
    甄别信息、病毒追踪、无人配送...这9个全球开源工具助力疫情抗击
    PIX无损线控改装——全系列车型及性能介绍
    PIX线控改装技术连载二 | 车辆组成模块之间的共同语言
    PIX入选Autodesk硅谷技术中心,以生成设计和金属增材制造落地L4自动驾驶通用底盘
    线控CRV,最高性价比的自动驾驶开发平台
    线控改装技术连载一之——线控开端和车辆组成
    CSS 创建
  • 原文地址:https://www.cnblogs.com/leebxo/p/10179558.html
Copyright © 2011-2022 走看看