演算法筆記之回溯法(1)

2021-09-19 17:52:35 字數 3267 閱讀 4360

回溯法的思想是:能進則進,進不了換,換不了退

隱約束指對能否得到問題的可行解和最優解做出的約束。隱約束包括約束函式限界函式

關鍵步驟是:

定**空間;

確定解空間的組織結構(子集樹、排列數、m叉樹等);

搜尋解空間。

回溯法階梯的關鍵是設計有效的顯約束隱約束

每個物品重量w和價值v如下表所示,購物車容量為w,求不超過購物車重量的最大價值。w1

234數值

2542

w123

4數值63

54解空間=的所有子集(包括這種子集),你像這裡面就是,,,,…。顯約束為xi=0或1。

確定解空間的組織結構。由於顯約束的緣故,可以看出解空間為子集樹。

搜尋解空間

搜尋過程見問題求解。

(1)首先初始化。w=,v=,sumw=2+5+4+2=13,sumv=6+3+5+4=18,因為sumw>w,所以不能裝完,所以需要進行後續的操作。此時定義乙個cp=rp=bestp=0,x[i]=0,cw=0。

注意:在這裡w和v的下標都是從1開始。並且以左子樹為xi=1,右子樹xi=0。

(2)開始搜尋第一層(t=1)。cw=cw+w[1]=2cp=cp+v[1]=6,將2號結點加入左子樹。(2號結點是第乙個商品)

(3)拓展2號結點。考慮cw+w[2]=7左子樹。(3號結點是第2個商品)

(4)拓展3號結點。考慮cw+w[3]=11>w,所以x[3]=0,然後計算cp+rp=9+4=13>bestp(此時bestp還是0),所以將4號結點加入右子樹。(4號結點是第3個商品)

(5)拓展4號結點。考慮cw+w[4]=9左子樹。(5號結點是第4個商品)

(6)拓展5號結點。由於此時t>n,故已經找到了乙個當前的最優解,令bestp=cp(值為13),5號結點成為死結點。返回到上一結點。

(7)回溯拓展4號。此時cp=9,若將5號結點加入右子樹,cp+rp=9由於3號結點已經研究過,左子樹不可行,所以回溯到2號結點。

(8)擴充套件2號結點(t=2)。之前擴充套件了左子樹,所以現在考慮右子樹。此時cp=6,bound(t+1)=cp+rp=15>bestp,因此滿足限界條件,擴充套件右子樹,令x[2]=0,生成6號結點。(也就是第2個商品不要了)

(9)擴充套件6號結點(t=3)。cw+w[3]=6左子樹。(7號結點是第3件商品)。

(10)拓展7號結點(t=4)

cw+w[4]=8左子樹。令x[4]=1,cw=cw+w[4]=8,cp=cp+v[4]=15。(8號結點是第4件商品)

(11)拓展8號結點(t=5)。由於此時t>n,故已經找到了乙個當前的最優解,令bestp=cp(值為15),8號結點成為死結點。返回到上一結點。

(12)拓展7號結點(t=4)。考察bound(t+1)=cp+rp=11<15,成為死結點。

(13)拓展6號結點(t=3)。bound(t+1)=cp+rp=10<15,成為死結點。

(14)拓展1號結點(t=1),bound(t+1)=12<15,成為死結點。演算法結束。

double bound(int i)//計算上界

return rp+cp;

}void backtrack(int t)//t當前在第t層

bestp = cp;

return;

}if (cw + w[t] <= w)//還未到重量,可以搜尋左子樹

//若左子樹不滿足,然後看右子樹,判斷限界條件

if (bound(t + 1) > bestp)

}void initial_parameter(double w, int n)

if (sumw <= w)

backtrack(1);

cout << "放入購物車的最大價值為" << bestp << "元。" << endl;

cout << "放入購物車的物品序號為:";

for (i = 1; i <= n; i++)

cout << endl;

}

1.演算法複雜度

(1)時間複雜度:o(12n+n 2n)=o(n * 2n)。

(2)空間複雜度:o(n)。

2.演算法優化

實際上,經常我們在計算bound()函式的時候對於rp多算太多了,因為很有可能rp到某一步就超過了購物車的中梁,所以我們可以縮小上界,從而加快剪枝速度,提高搜尋效率。

上界函式bound():當前價值cp+剩餘容量可容納的剩餘物品的最大價值brp(為了能裝最大價值,所以在計算上界函式的時候可以對商品分割,但實際的時候不允許),即修改為

double bound(int i)

;bool cmp(object a1, object a2)

然後將 initial_parameter(double w, int n)的if(sumw<=w)這個語段後面加入:

sort(q,q+n,cmp);

for(i=1;i<=n;i++)

for(i=1;i<=n;i++)

然後將

for (i = 1; i <= n; i++)

修改為

for (i = 1; i <= n; i++)

部落酋長希望組織一支保衛部落的衛隊,要在居民中選出最多的居民加入,並保證衛隊中任何兩個人都不是仇敵。程式設計計算構建部落護衛隊的最佳方案。

定義問題的解空間。問題的解空間為 的所有子集(包括這種子集),你像這裡面就是,,,,…。顯約束為xi=0或1。

解空間的組織結構:子集樹,深度為n。

搜尋解空間:

bool isplace(int t)

}return status;

}//回溯法主體

void backtrack(int t)

if (isplace(t))

if (cn + n - t > bestn)//這裡可以進行優化

}

1.時間複雜度:o(n* 2n),空間複雜度為o(n)。

演算法筆記之回溯法(2)

假設地圖共有7個區域,分別是a b c d e f g,對上面順序進行編號,每個區域用乙個結點表示,相鄰的區域有連線,那麼地圖就轉化成乙個無向連線圖。定義問題的解空間。圖的m著色問題解空間形式為n元組,每個分量取值為1,2,3,m,即問題的解是乙個n元向量。由此可得,問題的解空間為,其中顯約束為xi...

演算法筆記之回溯法(2)

假設地圖共有7個區域,分別是a b c d e f g,對上面順序進行編號,每個區域用乙個結點表示,相鄰的區域有連線,那麼地圖就轉化成乙個無向連線圖。定義問題的解空間。圖的m著色問題解空間形式為n元組,每個分量取值為1,2,3,m,即問題的解是乙個n元向量。由此可得,問題的解空間為,其中顯約束為xi...

回溯 皇后 演算法筆記 演算法筆記 回溯法

1 0 1揹包問題 思路 構造乙個二叉樹,每個商品都有兩種狀態,要或者不要。如果要就在這個節點的左枝掛子節點,如果不要就在右節點掛子節點。如果全部商品都分配完狀態之後就回溯,回溯到乙個還有其他選擇的節點,接著往這個選擇發展節點,然後再回溯,然後再往下。直到無路可走,就結束了。假如限制重量是10,總共...