不了解極大團(maximal clique)的,請看極大團這篇文章
參考資料:
當給出一個圖后,我們應該怎么去尋找其中的極大子團呢?
尋找極大子團的最簡單的思想是:
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算法的優化
