[分享] Greedy-Set-Cover linear

作者: anfranion (南‧生命的意義是經歷)   2012-06-08 16:50:19
分享給大家:)
***
(0) [符號說明]
S: Set F: Set的Set(全部的Set)
X: element的集合
(1) 為了方便我們先把所有的Set標上編號,
也就是變成S_1, S_2, ..., S_|F| // O(|F|)
(2) 對於每個element,我們給他一個"setList",用來記錄有包含他自己的set:
maxNum = 0; // 這是為了之後開表格用的,紀錄擁有最多元素的Set大小
for ( all S in F ) {
S.eleNum = 0; // 計算每個Set的Size
for ( all ele in S ) {
ele.chosen = false; // flag for 每個element只需被抓到一次
ele.setList.add( S );
S.eleNum++;
}
if ( S.eleNum > max )
max = S.eleNum;
} // O(sigma_S_in_F |S|)
(3) 建出一個有max+1格的bucket的list,其bucket對應的容量大小分別是0~max
接著再把每個Set依照其eleNum放到對應的bucket去:
for ( all S in F ) { // O(|F|)
bucket[S.eleNum].add( S );
S.pos = bucket[S.eleNum].size() - 1; // 紀錄位置,之後remove可以const
}
(4) 從bucket容量最大的一路做到最小的,每做一個相對於選取一個Set
當一個element被選到時,我們就可以將其其他的Set的size-1,
並且移動到比較小的籃子裡:
for ( k = max downto 1 ) { // O(|X|)
if ( bucket[k].size() == 0 )
continue;
for ( all S in bucket[k] ) { // O(|F|)
for ( all e in S ) {
if ( e.chosen == true )
continue;
for ( all E in e.setList ) {
oriSize = E.eleNum;
E.eleNum

Links booklink

Contact Us: admin [ a t ] ucptt.com