極大團(maximal clique)算法:Born_kerbosch算法


 

不了解極大團(maximal clique)的,請看極大團這篇文章

參考資料:

Bron_Kerbosch算法

團、極大團、最大團介紹

當給出一個圖后,我們應該怎么去尋找其中的極大子團呢?

尋找極大子團的最簡單的思想是:

1.生成原始圖的所有子圖(可能的子圖有2*n個,n代表頂點個數)

2.判斷這些子圖是不是團

3.將不是極大團的團刪除

 

Born_Kerbosch算法

這個算法主要構造三個集合:

R集合:存儲當前極大團中加入的頂點

P集合:存儲可能還加入的點

X集合:存儲的是已經假如過某個極大團的點(作用是判重,因為會從每個頂點開始,枚舉所有團,如果不對已經加入到某個極大團的頂點進行標記,可能會有重復極大團的出現)

 

基礎Born_kerbosch算法

1.對於任意一個在集合P中的頂點V,我們把V加入到R集合(集合P中的每一個頂點均與R集合中所有的點是連接的,所以加入頂點V后,依然能保證集合R是個團),然后對在P集合中且與V相連的這部分點中,尋找下一個可能加入到R集合的點。(意思就時加入點v至R集合后更新P集合,使P集合中的任意一個點依然能和R集合中每一個點都是連接的。因為這里新R集合中加入了V,所以只要是原p集合中且與v頂點相連的這些頂點就是與新R集合中所有頂點相連)

2.回溯時把頂點V從P中移除並加入到X集合,表示在當前狀態下包含頂點V的極大團已經計算完畢。

3.R集合為極大團時,必須滿足P與X都是空的。P存放的是還可能加入到極大團R中的點,P集合為空表示已經沒有點能加入到R中了。而X中存放的是已經完成極大團計算的點,且X集合中的任意一個點必然是與R中每個頂點都連接(因為我們每次向下dfs時,還對P和X分別進行取與R集合內都連接的操作來保證,而且X中的點就是從R中取出的點,當然會和R集合中的每個點都連接),即X中的點必然可以和R集合構成極大團。如果X集合不為空的話,可以把X的點加入到R集合中從而構成一個團R1,R1的頂點數大於R,說明R就不是一個極大團,R1集合中的極大團是之前計算包含x集合中的點的極大團的時候計算過了的,故當且僅當P、X集合都為空時R才是一個極大團。

算法圖例

 

Born_Kerbosch算法的優化

在上面這個方法中,我們進行了許多不必要的判斷,例如在我們找到了極大團{1、2、3}之后,依然去對{1、3},{2、3},{3}這些團進行了判斷,然而這些顯然不是極大團。所以現在考慮的是對其進行優化,使程序不用進行不必要的遞歸。
當我們將一個結點u,放入到R集合后,再取下一個結點,取的必然是u的鄰居結點(因為再更新P和X時,會將不是鄰居結點的結點都過濾掉)。通俗的講就是如果取完u之后我們再取與u相鄰的點v也能加入到極大團,那么我們只取u就好了,因為我們由u開始遞歸,已經找到了u及其鄰居結點v等等結點構成的極大團了,沒有必要再去從v開始尋找極大團,這會增加不必要的計算。至於v可能可以其他結點構成另一個極大團,如果這個極大團包括了u,那么由u開始就已經找到了這個極大團了;如果這個極大團不包括u,那說明這個極大團里面一定存在和u結點不相連的結點k,那沒必要從v開始尋找這個極大團了,從u的非鄰居結點k開始,一樣可以找到這個極大團。這樣對u及其鄰居結點構成的極大團,只需要從u開始尋找一次就可以了,接下來就直接從u的非鄰居結點k開始尋找極大團,這樣可以減少許多不必要的計算。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM