問題描述:
給定無向圖g=(
v, e),其中
v是非空集合,稱為頂點集;e是
v中元素構成的無序二元組的集合,稱為邊集,無向圖中的邊均是頂點的無序對,無序對常用圓括號「( )」表示。如果u
∈v,且對任意兩個頂點u,
v∈u有(
u, v)∈
e,則稱u是
g的完全子圖。
g的完全子圖u是
g的團當且僅當
u不包含在
g的更大的完全子圖中。
g的最大團是指
g中所含頂點數最多的團。如果u
∈v且對任意u,
v∈u有(
u, v)∈e,則稱u是
g的空子圖。
g的空子圖u是
g的獨立集當且僅當
u不包含在
g的更大的空子圖中。
g的最大獨立集是
g中所含頂點數最多的獨立集。
對於任一無向圖g=(
v, e),其補圖
g'=(
v',
e')定義為:v'=
v,且(u,
v)∈e'當且僅當(u,
v)∈e。
如果u是g
的完全子圖,則它也是
g'的空子圖,反之亦然。因此,
g的團與
g'的獨立集之間存在一一對應的關係。特殊地,u是
g的最大團當且僅當u是
g'的最大獨立集。
問題定義:
解空間樹中結點型別:bbnode
活結點優先佇列中元素型別為 cliquenode(cn 表示與該節點相應的團的定點數,un表示結點為根的子樹中的最大頂點樹的上界。level表示結點在子集空間樹中所處的層次;ch 左右兒子的結點標記)
ch=1 左兒子 ch=0 右兒子
ptr 指向解空間樹中相應結點的指標
cn+n-level+1表示定點數上界的un值。
**描述:
相關結構體定義:
classbbnode;
class
cliquenode
private
:
intcn,
un,level;
bbnode *ptr;
};class
clique;
addlivenode:將當前構造的活結點 加入到子集空間樹中並插入活結點優先佇列中。
void clique::addlivenode(maxheap&h,int cn,int un,int level,bbnode e,boolch)
演算法核心**:bbmaxclique
子集樹的根節點是 初始擴充套件結點 cn為0
i 表示當前擴充套件結點的解空間樹中所處的層次。
首先考察左兒子:
頂點加入當前團,檢查該頂點與當前團中其他頂點是否有邊相連。
都有邊,可行,納入 活結點 優先佇列中,addlivenode(),接著考察當前擴充套件結點的 右兒子結點,僅當un>bestn時,右子樹中可能含有最優解 ;
否則,不可行。
int clique::bbmaxclique(intbestx)
}if(ok)
if(cn+n-i >=bestn)
addlivenode(h,cn+1,cn+n-i+1,i+1,e,true
); cliquenode n;
h.deletemax(n);
e =n.ptr;
cn =n.cn;
i =n.level;
}for(int j=n;j>0;j--)
return
bestn;
}
分支限界 最大團問題
給定有乙個無向圖,找出最大團個數。最大團也就是該圖中最大的完全圖 各頂點之間都有邊 演算法思想 設p為所有點集的集合,依次取出p中的頂點作為團的起始點,也就是以該點為起點開始拓展,每次檢視相鄰頂點是否與團內各點聯通,若true,則加入該點。為了進一步降低時間複雜度,採取記憶化遞迴的方式,從後向前遍歷...
最大團問題 0 1揹包 再談分支限界
對於分支限界,其實思想和回溯很像,只是具體的實現方法不一樣。回溯用到遞迴,是深度優先搜尋 分支限界是用最大堆進行迴圈,是廣度優先搜尋。1.最大團問題 給出乙個無向連通圖,求出其最大完全子圖的節點數 分析 每乙個節點進行分析,如果可以放進去,則定為1,放入左節點,要是不能放進去,則定為0,放入右節點。...
最大團問題
include cstdio include queue include cstring define max 20 using namespace std int n 城市數量 int x max 解向量 struct node priority queuepq void enqueue int ...