日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于Warshall算法的连通图及欧拉图判定方法

發(fā)布時間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Warshall算法的连通图及欧拉图判定方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1736年歐拉解決了哥尼斯堡七橋問題。他在這一具體問題的基礎(chǔ)上進(jìn)一步研究,最終找到了一個簡便的原則可以鑒別一個圖(多重圖)能否一筆畫成。

本文中,筆者使用布爾矩陣來存儲一個無向圖,并結(jié)合集合論中“傳遞閉包”的概念給出了一種歐拉圖的判定方法。

本文旨在給初學(xué)者提供一種可行解,第一次發(fā)文,筆者技藝不精,若文章中有錯誤之處,還望各位同仁能夠海涵,希望與大家共同進(jìn)步。


一些概念的解釋:

包含圖的所有頂點(diǎn)和所有邊的閉跡成為歐拉閉跡

存在一條歐拉閉跡的圖成為歐拉圖

RRR是集合XXX上的一個二元關(guān)系,則XXX上的所有包含RRR的傳遞關(guān)系的交稱為RRR傳遞閉包,用R+{R\mathop{{}}\nolimits^{{+}}}R+表示。即:R+=?R?R’R’(其中R’傳遞){R\mathop{{}}\nolimits^{{+}}={\mathop{ \bigcap }\limits_{{R \subseteq R\text{'}}}{{R\text{'}}}} \left( \text{其}\text{中}R\text{'}\text{傳}\text{遞} \right) } R+=R?R??R(R)亦即R+{R\mathop{{}}\nolimits^{{+}}}R+是包含RRR的傳遞關(guān)系中最小的那個。

Warshall算法是1962年由Warshall提出的一種計算關(guān)系傳遞閉包的十分有效的算法,將在下文詳細(xì)說明。

注:本文中說的圖都是指無向圖


歐拉圖的判斷

在王義和編著的《離散數(shù)學(xué)引論》(第三版)中,給出了一個圖GGG是歐拉圖的充要條件:

GGG是一個歐拉圖當(dāng)且僅當(dāng)GGG是連通的且每個頂點(diǎn)的度都是偶數(shù)。

因此,歐拉圖的判斷可分為兩步:先判斷圖是否連通,再依次檢查每一個頂點(diǎn)的度是否為偶數(shù)即可。


布爾矩陣與無向圖

在集合論中,我們曾經(jīng)使用布爾矩陣來存儲一個二元關(guān)系。一個無向圖也可看做非空頂點(diǎn)集VVV上的一個反自反且對稱的二元關(guān)系,因此也可使用布爾矩陣來存儲一個無向圖。


連通圖與傳遞閉包

GGG是一個連通圖,當(dāng)且僅當(dāng)圖中任兩個不同頂點(diǎn)間至少有一條路連接。

設(shè)圖G=(U,V)G=(U,V)G=(U,V)是一個連通圖,R?V×VR\subseteq V\times VR?V×V是圖GGG對應(yīng)的二元關(guān)系,R+{R\mathop{{}}\nolimits^{{+}}}R+是關(guān)系RRR的傳遞閉包。對?u,v∈V{ \forall u,v \in V}?u,vV
如果u,vu,vu,v鄰接,則(u,v),(v,u)∈R,(u,v),(v,u)\in R,(u,v),(v,u)R,R?R+R\subseteq R^+R?R+ 從而(u,v),(v,u)∈R+(u,v),(v,u)\in {R\mathop{{}}\nolimits^{{+}}}(u,v),(v,u)R+
如果u,vu,vu,v不鄰接,由于GGG 是連通圖,u,vu,vu,v之間必存在一條路u,u1,u2,......,un,v{u,u\mathop{{}}\nolimits_{{1}},u\mathop{{}}\nolimits_{{2}},......,u\mathop{{}}\nolimits_{{n}},v }u,u1?,u2?,......,un?,v
那么序?qū)?span id="ozvdkddzhkzd" class="katex--inline">(u,u1),(u1,u2),......,(un,v)∈R(u,u_1),(u_1,u_2),......,(u_n,v)\in R(u,u1?),(u1?,u2?),......,(un?,v)R,而R+R^+R+又是包含RRR的最小傳遞關(guān)系,因此(u,v)∈R+(u,v)\in R^+(u,v)R+,由對稱性,(v,u)∈R+(v,u)\in R^+(v,u)R+
而對于圖GGG中某點(diǎn)uuu自身,uuu不可能是孤立點(diǎn),因此一定有某點(diǎn)vvv與之鄰接,因此(u,v),(v,u)∈R(u,v),(v,u)\in R(u,v),(v,u)R,從而(u,u)∈R+(u,u)\in R^+(u,u)R+

由此我們可以得出結(jié)論:一個連通圖自身對應(yīng)的二元關(guān)系 RRR 的傳遞閉包R+R^+R+ 包含了頂點(diǎn)集VVV上的所有二元序?qū)Α_@在R+R^+R+的布爾矩陣中表現(xiàn)為:所有位置上的值均為1,沒有出現(xiàn)0的位置。如果R+R^+R+某一個位置上的值為0,那么說明這個位置對應(yīng)的兩個頂點(diǎn)之間必?zé)o路連接。

因此,判斷一個圖是否是無向圖,只需求出它的傳遞閉包,再遍歷所有位置看是否有0即可。

下面的問題就只剩下,如何求解傳遞閉包?


Warshall算法

在王義和編著的《離散數(shù)學(xué)引論》(第三版)中,給出了傳遞閉包R+R^+R+的一個計算公式:

設(shè)XXXnnn元集,RRRXXX上的二元關(guān)系,則R+=?i=1nRi。{R\mathop{{}}\nolimits^{{+}}={\mathop{ \bigcup }\limits_{{i=1}}^{{n}}{R\mathop{{}}\nolimits^{{i}}}}}。R+=i=1?n?Ri

在此基礎(chǔ)上,Warshall提出了一種傳遞閉包的算法,在《離散數(shù)學(xué)引論》中也給出了其形式化描述:
(由矩陣BBB計算其傳遞閉包B+B^+B+)

1.A←B;A\leftarrow B;AB;
2.k←1;k \leftarrow1;k1;
3.i←1;i \leftarrow 1;i1;
4.如果aik=1a_{ik}=1aik?=1,則對j=1,2,...,nj=1,2,...,nj=1,2,...,naij←aij∨akj;a_{ij}\leftarrow a_{ij}\vee a_{kj};aij?aij?akj?;
5.i←i+1i\leftarrow i+1ii+1ifi≤nthengoto4;if\text{ ?}i \le n\text{ ?}then\text{ ?}goto\text{ ?}4;if??in??then??goto??4
6.k←k+1k\leftarrow k+1kk+1ifk≤nthengoto3else停;{if\text{ ?}k \le n\text{ ?}then\text{? }goto\text{ ?}3\text{? }else\text{ ?}\text{停}};if??kn??then??goto??3??else??;
這個算法結(jié)束時,AAA中就是矩陣B+B^+B+中的全部元素。


程序代碼

對一個圖GGG,在程序中只需利用Warshall算法求出它的傳遞閉包,再檢查所有位置中是否有0即可判斷這個圖的連通性。如果是連通圖,在此基礎(chǔ)上再檢查每一個頂點(diǎn)的度的奇偶性即可判斷這個圖是否是歐拉圖。

需要注意的是,存儲無向圖時,布爾矩陣應(yīng)該表示為一個對稱的、主對角線上全是0的矩陣。

最后在此附上沒有使用C99特性的C語言代碼:

/*程序功能:輸入圖G,判斷G是否是歐拉圖 *程序輸入:第1行包括兩個整數(shù)N和M,分別表示圖G中的頂點(diǎn)個數(shù)和邊的個數(shù)(N<100) * 接下來的M行中每行包括兩個整數(shù),表示鄰接的兩個點(diǎn)的序號 *程序輸出:如果G是歐拉圖,則輸出Yes,否則輸出No */#include <stdio.h> #define MAX_SIZE 100//華沙算法判斷圖是否連通,連通返回1,否則返回0 //傳入?yún)?shù)為待判定的圖的布爾矩陣和矩陣的大小 int isConnected(int graph[MAX_SIZE][MAX_SIZE], int n) {int i, j, k;int a[MAX_SIZE][MAX_SIZE];//先拷貝矩陣graph到a中,防止后續(xù)操作修改原矩陣for (i = 0; i < n; i++){for (j = 0; j < n; j++){a[i][j] = graph[i][j];}}//華沙算法求傳遞閉包,結(jié)果放在矩陣a中for (k = 0; k < n; k++){for (i = 0; i < n; i++){for (j = 0; j < n; j++){if (a[i][k]){a[i][j] = a[i][j] || a[k][j];}//a[i][j] = a[i][j] || (a[i][k] && a[k][j]);}}}//連通圖對應(yīng)關(guān)系的傳遞閉包應(yīng)該全1for (i = 0; i < n; i++){for (j = 0; j < n; j++){if (a[i][j] == 0){return 0;}}}return 1; }int main() {int N, M;int i, j;int Graph[MAX_SIZE][MAX_SIZE] = {0};int v1, v2; //臨時存儲兩個頂點(diǎn)序號int deg[MAX_SIZE] = {0}; //存儲每個頂點(diǎn)的度printf("Input the number of dots and edges:\n");scanf("%d%d", &N, &M);printf("Input the edges:\n");for (i = 0; i < M; i++){scanf("%d%d", &v1, &v2);Graph[v1-1][v2-1] = Graph[v2-1][v1-1] = 1;}//先判斷圖G是否連通if (!isConnected(Graph, N)){printf("No\n");return 0;}//再判斷圖G中每個頂點(diǎn)的度是否均為偶數(shù)for (i = 0; i < N; i++){for (j = 0; j < N; j++){deg[i] += Graph[i][j];}if (deg[i] % 2 == 1) //如果有度為奇數(shù)的點(diǎn)直接輸出No{printf("No\n");return 0;}}printf("Yes\n");return 0; }

參考文獻(xiàn):王義和《離散數(shù)學(xué)引論》(第三版)

總結(jié)

以上是生活随笔為你收集整理的基于Warshall算法的连通图及欧拉图判定方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。