<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
    六。 最小支撐樹MST
    給定一個簡單有向圖,要求權值最小的生成樹,即求最小支撐樹問題。
    所謂生成樹,就是說樹的頂點集合等于給定圖的頂點集合,且邊集合包含于圖的邊集合。
    也就說找出構成樹的,經過所有頂點的,且權值最小的邊集。
    樹的定義是要求無回路的,然后是要求連通的。

    有兩個比較經典的算法是:
    1)Prim算法: 該算法的思想跟Dijstra算法非常相似,Dijstra算法中每次求出下一個頂點時依據的是離初始頂點最近的,而Prim算法則找離V1整個集合最近的,也就是從V1中某個節點出發到該頂點的邊的權值最小。
    其原理也是每次找局部最優,最后構成全局最優。
    實現如下

    @Override
        
    public Edge[] prim() {
            MinHeap
    <Edge> heap=new MinHeap<Edge>(Edge.class,numEdges);
            Edge[] edges
    =new Edge[numVertexes-1];
            
    //we start from 0
            int num=0;//record already how many edges;
            int startV=0;
            Arrays.fill(visitTags, 
    false);
            Edge e;
            
    for(e=firstEdge(startV);isEdge(e);e=nextEdge(e))
            {
                heap.insert(e);
            }
            visitTags[startV]
    =true;
            
            
    while(num<numVertexes-1&&!heap.isEmpty())//tree's edge number was n-1
            {
                
                e
    =heap.removeMin();
            
                startV
    =toVertex(e);
                
    if(visitTags[startV])
                {
                    
    continue;
                }
                visitTags[startV]
    =true;
                edges[num
    ++]=e;
                
    for(e=firstEdge(startV);isEdge(e);e=nextEdge(e))
                {
                    
    if(!visitTags[toVertex(e)])//can't add already visit vertex, this may cause cycle
                    heap.insert(e);
                }
                
                    
                
            }
            
    if(num<numVertexes-1)
            {
                
    throw new IllegalArgumentException("not connected graph");
            }
            
    return edges;
        }

    /**
         * A Graph example
         * we mark the vertexes  with 0,1,2,.14 from left to right , up to down
         * S-8-B-4-A-2-C-7-D
         * |   |   |   |   |
         * 3   3   1   2   5
         * |   |   |   |   |
         * E-2-F-6-G-7-H-2-I
         * |   |   |   |   |
         * 6   1   1   1   2
         * |   |   |   |   |
         * J-5-K-1-L-3-M-3-T
         * 
         
    */
        
    public static void testPrimMST() {
        

            
            DefaultGraph g
    =new DefaultGraph(15);
            g.setEdge(
    018);
            g.setEdge(
    108);//its a undirected graph
            g.setEdge(124);
            g.setEdge(
    214);
            g.setEdge(
    232);
            g.setEdge(
    322);
            g.setEdge(
    347);
            g.setEdge(
    437);
            
            g.setEdge(
    053);
            g.setEdge(
    503);
            g.setEdge(
    163);
            g.setEdge(
    613);
            g.setEdge(
    271);
            g.setEdge(
    721);
            g.setEdge(
    382);
            g.setEdge(
    832);
            g.setEdge(
    495);
            g.setEdge(
    945);
            
            
            g.setEdge(
    562);
            g.setEdge(
    652);
            g.setEdge(
    676);
            g.setEdge(
    766);
            g.setEdge(
    787);
            g.setEdge(
    877);
            g.setEdge(
    892);
            g.setEdge(
    982);
            
            
            g.setEdge(
    1056);
            g.setEdge(
    5106);
            g.setEdge(
    1161);
            g.setEdge(
    6111);
            g.setEdge(
    1271);
            g.setEdge(
    7121);
            g.setEdge(
    1381);
            g.setEdge(
    8131);
            g.setEdge(
    1492);
            g.setEdge(
    9142);
            
            g.setEdge(
    10115);
            g.setEdge(
    11105);
            g.setEdge(
    11121);
            g.setEdge(
    12111);
            g.setEdge(
    12133);
            g.setEdge(
    13123);
            g.setEdge(
    13143);
            g.setEdge(
    14133);
            
            g.assignLabels(
    new String[]{"S","B","A","C","D","E","F","G","H","I","J","K","L","M","T"});
            Edge[] edges
    =g.prim();
            
    int total=0;
            
    for(int i=0;i<edges.length;i++)
            {
                System.out.println(edges[i].toString(g));
                total
    +=edges[i].getWeight();
            }
            System.out.println(
    "MST total cost:"+total);
    }

    2)Kruskal算法:
    該算法開始把,每個節點看成一個獨立的兩兩不同的等價類,每次去權值最小的邊,如果關聯這條邊的兩個頂點在同一個等價類里那么這條邊不能放入MST(最小生成樹)中,否則放入MST中,并把這兩個等價類合并成一個等價類。
    繼續從剩余邊集里選最小的邊,直到最后剩余一個等價類了。
    該算法涉及等價類的合并/查找,一般用父指針樹來實現。下面先給出父指針樹實現的并查算法。
    帶路徑壓縮的算法,其查找時間代價可以看做是常數的。

    package algorithms;

    /**
     * 
    @author yovn
     *
     
    */
    public class ParentTree {
        
        
        
    private static class PTreeNode
        {
            
    int parentIndex=-1;
            
    int numChildren=0;//only make sense in root

            
    void setParent(int i) {
                
                parentIndex
    =i;
                
            }
        }
        PTreeNode[] nodes;
        
    int numPartions;
        
    public ParentTree(int numNodes)
        {
            nodes
    =new PTreeNode[numNodes];
            numPartions
    =numNodes;
            
    for(int i=0;i<numNodes;i++)
            {
                nodes[i]
    =new PTreeNode();
                nodes[i].parentIndex
    =-1;//means root
                
            }
            
        }
        
        
    /**
         * use path compress
         * 
    @param i
         * 
    @return
         
    */
        
    public int find(int i)
        {
            
    if(nodes[i].parentIndex==-1)
            {
                
    return i;
            }
            
    else
            {
                nodes[i].setParent(find(nodes[i].parentIndex));
    //compress the path
                return nodes[i].parentIndex;
            }
        }
        
        
    public int numPartions()
        {
            
    return numPartions;
        }
        
    public boolean union(int i,int j)
        {
            
    int pi=find(i);
            
    int pj=find(j);
            
    if(pi!=pj)
            {
                
    if(nodes[pi].numChildren>nodes[pj].numChildren)
                {
                    nodes[pj].setParent(pi);
                    nodes[pj].numChildren
    +=nodes[pi].numChildren;
                    nodes[pi].numChildren
    =0;
                    
                }
                
    else
                {
                    nodes[pi].setParent(pj);
                    nodes[pi].numChildren
    +=nodes[pj].numChildren;
                    nodes[pj].numChildren
    =0;
                }
                numPartions
    --;
                
    return true;
            }
            
    return false;
        }
        
    }


    從邊集里權最小的邊,我們又可以借助最小值堆來完成。有了父指針樹以及最小值堆,現實Kruskal算法就很簡單了:

    @Override
        
    public Edge[] kruskal() {
            Edge[] edges
    =new Edge[numVertexes-1];
            ParentTree ptree
    =new ParentTree(numVertexes);
            MinHeap
    <Edge> heap=new MinHeap<Edge>(Edge.class,numEdges);
            
    for(int i=0;i<numVertexes;i++)
            {
                
    for(Edge e=firstEdge(i);isEdge(e);e=nextEdge(e))
                {
                    heap.insert(e);
                }
            }
            
    int index=0;
            
    while(ptree.numPartions()>1)
            {
                Edge e
    =heap.removeMin();
                
    if(ptree.union(fromVertex(e),toVertex(e)))
                {
                    edges[index
    ++]=e;
                }
            }
            
    if(index<numVertexes-1)
            {
                
    throw new IllegalArgumentException("Not a connected graph");
            }
            
    return edges;
            
        }
    OK,到此,圖論的大概的算法算是復習完了。

    posted on 2007-12-14 23:48 DoubleH 閱讀(3680) 評論(1)  編輯  收藏 所屬分類: Memorandum

    Feedback

    # re: 圖及其算法復習(Java實現) 三:最小支撐樹(Prim,Kruskal算法) 2010-10-27 23:16 斯蒂芬
    toString沒有定義。
    不好使  回復  更多評論
      

    主站蜘蛛池模板: 亚洲欧洲日产韩国在线| 亚洲自偷自偷在线成人网站传媒 | 亚洲中文字幕成人在线| 国产精品福利在线观看免费不卡| 亚洲无线观看国产精品| 可以免费看黄的网站| 免费精品国自产拍在线播放| 久久伊人久久亚洲综合| 我要看免费的毛片| 久久国产一片免费观看| 亚洲午夜久久久久久尤物| 亚洲XX00视频| 99re热免费精品视频观看| 一级一片免费视频播放| 亚洲一区免费在线观看| 亚洲片国产一区一级在线观看| 亚洲免费福利视频| 春意影院午夜爽爽爽免费| 亚洲宅男天堂a在线| 国产精品V亚洲精品V日韩精品| 国产大片免费网站不卡美女| 日韩毛片一区视频免费| 久久精品国产99国产精品亚洲| 亚洲一区无码精品色| 免费AA片少妇人AA片直播| 成人国产精品免费视频| 亚洲人成网亚洲欧洲无码| 亚洲av无码成人黄网站在线观看| 免费国产在线观看| 少妇高潮太爽了在线观看免费| 十八禁视频在线观看免费无码无遮挡骂过 | 偷自拍亚洲视频在线观看| 亚洲日韩中文字幕天堂不卡| 伊人久久亚洲综合| 免费观看国产精品| 日韩欧美一区二区三区免费观看| 一区二区三区观看免费中文视频在线播放 | 国产成人亚洲精品电影| 亚洲六月丁香婷婷综合| 亚洲色图视频在线观看| 国产亚洲AV无码AV男人的天堂|