圖論算法

若干定義

圖范指由頂點(diǎn)V(vetex)和邊(edge)組成的集合褒颈,可以表示G=(V,E).

有向圖,無(wú)向圖

頂點(diǎn)之間有順序?yàn)橛邢驁D,無(wú)順序?yàn)闊o(wú)向圖


WX20190418-161310@2x.png
有圈圖隶债,無(wú)圈圖

存在從頂點(diǎn)到自身的路徑秉溉,稱為有圈圖力惯,否則稱為無(wú)圈圖

有向圖的表示

1.二維數(shù)組表示法:
A[u][v] = true 表示存在從u到v的邊,否則不存在
其中true也可以用權(quán)值表示召嘶,用一個(gè)非常大或者非常小的值表示不存在的邊
空間需求:|v|的平方父晶,也就是頂點(diǎn)個(gè)數(shù)的平方
有點(diǎn):簡(jiǎn)單明了
缺點(diǎn):對(duì)于邊多的圖合適,但是對(duì)于稀疏的圖弄跌,效率較低
2.鄰接表示法:
通過(guò)Map表示甲喝,key為頂點(diǎn)值,value為頂點(diǎn)值對(duì)對(duì)應(yīng)的頂點(diǎn)組合


WX20190418-163257@2x.png

拓?fù)渑判?/h4>

對(duì)于有向無(wú)圈圖的一種排序铛只,拓?fù)渑判蚩赡懿恢挂粋€(gè)結(jié)果埠胖。
如下圖所示:v1-v2-v5-v4-v3-v7-v6和v1-v2-v5-v4-v7-v3-v6都是正確的拓?fù)渑判颉?/p>

WX20190508-141508@2x.png

拓?fù)渑判騻未a


WX20190522-161053@2x.png

最短路徑算法

對(duì)于賦權(quán)圖,計(jì)算點(diǎn)到點(diǎn)的最短路徑所用到的算法就是最短路徑算法淳玩。解決單源最短路徑算法一般叫做Dijkstra算法直撤。也屬于貪婪算法的一個(gè)例子。假如有如下有項(xiàng)圖G:


WX20190527-100002@2x.png

要計(jì)算從V1->V6的最短路徑蜕着,下面是具體的代碼實(shí)現(xiàn):

        int max = 10000;
        //graph定義了任意點(diǎn)到點(diǎn)的權(quán)值谊惭,如果連個(gè)點(diǎn)之間不連通,則值為max
        int[][] graph = {
                {max,2,max,1,max,max,max},
                {max,max,max,3,10,max,max},
                {4,max,max,max,max,5,max},
                {max,max,2,max,2,8,4},
                {max,max,max, max,max, max,6},
                {max,max,max,max,max,max,max},
                {max,max,max,max,max,1,max}
        };
        int []path = new int[6]; //保存了每個(gè)節(jié)點(diǎn)最短路徑的前置節(jié)點(diǎn)
        int []cost = new int[6]; //保存每個(gè)節(jié)點(diǎn)的最短路徑值

具體實(shí)現(xiàn)函數(shù):

 public static void findShortestPath(int[][] graph,int startIndex, int[] path, int[] cost,int max)
    {
        int nodeCount = graph.length;
        Boolean[] v = new Boolean[nodeCount];
        //初始化 path侮东,cost圈盔,V
        for (int i = 0; i <nodeCount ; i++)
        {
            if (i == startIndex)//如果是出發(fā)點(diǎn)
            {
                v[i] = true;//
            }
            else
            {
                cost[i] = graph[startIndex][i];
                if (cost[i] < max) path[i] = startIndex;
                else path[i] = -1;
                v[i] = false;
            }
        }
        //
        for(int i=1;i<nodeCount;i++)//求解nodeCount-1個(gè)
        {
            int minCost = max ;
            int curNode=-1;
            for (int w = 0; w < nodeCount; w++)
            {
                if (!v[w])//未在V集合中
                {
                    if(cost[w]<minCost)
                    {
                        minCost = cost[w];
                        curNode = w;
                    }
                }
            }//for  獲取最小權(quán)值的節(jié)點(diǎn)
            if (curNode == -1) break;//剩下都是不可通行的節(jié)點(diǎn),跳出循環(huán)
            v[curNode] = true;
            for (int w = 0; w < nodeCount; w++)
            {
                if (!v[w] && (graph[curNode][w] + cost[curNode] < cost[w]))
                {
                    cost[w] = graph[curNode][w] + cost[curNode];//更新權(quán)值
                    path[w] = curNode;//更新路徑
                }
            }//for 更新其他節(jié)點(diǎn)的權(quán)值(距離)和路徑
        }//
    }

執(zhí)行結(jié)果:

節(jié)點(diǎn)最短路徑值cost:v1-0,v2-2,v3-3,v4-1,v5-3,v6-6,v7-5,
前置節(jié)點(diǎn)path:0,0,3,0,3,6,3,

網(wǎng)絡(luò)流問(wèn)題

低于有向圖悄雅,有一種情況驱敲,邊上的權(quán)值表示可以通過(guò)此邊的最大流量,因此宽闲,求兩個(gè)點(diǎn)之間的最大流量众眨,稱為網(wǎng)絡(luò)流網(wǎng)體握牧,這種算法也稱為求最大流算法。假如有如下有向圖:


WX20190528-135652@2x.png

要求從s到t的最大流娩梨,一種簡(jiǎn)單的算法沿腰,先找出一條從s到t的有效路徑,這條路徑所能通多的最大流量為此條路徑的最小值狈定,之后把此條路徑的經(jīng)過(guò)的邊減去當(dāng)前所得的流量值颂龙。然后再重復(fù)操作,直到無(wú)法找到從s到t的有效路徑為止纽什。

具體代碼實(shí)現(xiàn):

private boolean getPath(int[][] graph,int start ,int end){
        Boolean[] vistor = new Boolean[end-start+1];
        for(int i = 0; i <= end ;i++){
            pre[i] = -1;
            vistor[i] = false;
        }
        vistor[start] = true;
        Queue<Integer> queue = new ArrayDeque<>();
        queue.offer(start);
        while(queue.size() > 0){
            int index = queue.poll();
            for(int i = 0;i<= end;i++){
                if(graph[index][i] > 0 && !vistor[i]){
                    queue.offer(i);
                    pre[i] = index;
                    vistor[i] = true;
                    if(i == end){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void calMaxFlow(int[][] graph,int start, int end){
        int maxFlow = 0;
        while(getPath(graph,start,end)){
            int min = 10000;
            for(int n = end; n != 0; n = pre[n]){
                if(graph[pre[n]][n] < min){
                    min = graph[pre[n]][n];
                }
            }
            for(int n = end; n!=start;n = pre[n]){
                graph[pre[n]][n] -= min;
                graph[n][pre[n]] += min;
            }
            maxFlow += min;
        }
        System.out.printf("maxFlow:"+maxFlow);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末措嵌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芦缰,更是在濱河造成了極大的恐慌企巢,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件让蕾,死亡現(xiàn)場(chǎng)離奇詭異浪规,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)探孝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門罗丰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人再姑,你說(shuō)我怎么就攤上這事萌抵。” “怎么了元镀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵绍填,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我栖疑,道長(zhǎng)垦沉,這世上最難降的妖魔是什么窘疮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上恩伺,老公的妹妹穿的比我還像新娘赚导。我一直安慰自己川蒙,他們只是感情好庙睡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著揪漩,像睡著了一般旋恼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奄容,一...
    開(kāi)封第一講書(shū)人閱讀 50,021評(píng)論 1 291
  • 那天冰更,我揣著相機(jī)與錄音产徊,去河邊找鬼。 笑死蜀细,一個(gè)胖子當(dāng)著我的面吹牛舟铜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奠衔,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谆刨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了涣觉?” 一聲冷哼從身側(cè)響起痴荐,我...
    開(kāi)封第一講書(shū)人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤血柳,失蹤者是張志新(化名)和其女友劉穎官册,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體难捌,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膝宁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了根吁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员淫。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖击敌,靈堂內(nèi)的尸體忽然破棺而出介返,到底是詐尸還是另有隱情,我是刑警寧澤沃斤,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布圣蝎,位于F島的核電站,受9級(jí)特大地震影響衡瓶,放射性物質(zhì)發(fā)生泄漏徘公。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一哮针、第九天 我趴在偏房一處隱蔽的房頂上張望关面。 院中可真熱鬧,春花似錦十厢、人聲如沸等太。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)澈驼。三九已至,卻和暖如春筛武,著一層夾襖步出監(jiān)牢的瞬間缝其,已是汗流浹背挎塌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留内边,地道東北人榴都。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像漠其,于是被迫代替她去往敵國(guó)和親嘴高。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容