版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第五章
回溯法2/7/20231計算機(jī)算法設(shè)計與分析計算機(jī)求解的過程求解過程可看成在狀態(tài)空間從初始狀態(tài)出發(fā)搜索目標(biāo)狀態(tài)(解所在狀態(tài))的過程。狀態(tài)空間初始狀態(tài)目標(biāo)狀態(tài)搜索可描述為:S0S1…Sn,S0為初態(tài),Sn為終態(tài)?;蛘擀?S0)且φ(Sn),這里ψ稱為初始條件,φ稱為終止條件。2/7/20232計算機(jī)算法設(shè)計與分析求解是狀態(tài)空間的搜索求解的過程可以描述為對狀態(tài)空間的搜索其中S0為初始狀態(tài),不妨設(shè)Sni為終止?fàn)顟B(tài)S0S11S12…S1k………………Sn1……Sni……SnmS0于是問題的求解就是通過搜索尋找出一條從初始狀態(tài)S0到終止?fàn)顟B(tài)Sni的路徑。Sni2/7/20233計算機(jī)算法設(shè)計與分析幾種搜索方法狀態(tài)空間的搜索實(shí)際上是一種樹/DAG的搜索,常用的方法有:廣度優(yōu)先的搜索:深度優(yōu)先的搜索:啟發(fā)式的搜索:從初始狀態(tài)開始,逐層地進(jìn)行搜索。從初始狀態(tài)開始,逐個分枝地進(jìn)行搜索。從初始狀態(tài)開始,每次選擇最有可能達(dá)到終止?fàn)顟B(tài)的結(jié)點(diǎn)進(jìn)行搜索。2/7/20234計算機(jī)算法設(shè)計與分析三種搜索的比較理論上廣度優(yōu)先搜索與深度優(yōu)先搜索的時間復(fù)雜性都是指數(shù)級。但在實(shí)際上深度優(yōu)先搜索的時間復(fù)雜性要低,在空間復(fù)雜性更要低得多。廣度優(yōu)先搜索是一定能找到解;而深度優(yōu)先搜索在理論上存在找不到解的可能。啟發(fā)式搜索是最好優(yōu)先的搜索,若評價函數(shù)設(shè)計得好則能較快地找到解,降低時間復(fù)雜性;因而評價函數(shù)的優(yōu)劣決定了啟發(fā)式搜索的優(yōu)劣。另外評價函數(shù)本身的開銷也是很重要的。2/7/20235計算機(jī)算法設(shè)計與分析樹搜索的一般形式SearchTree(SpaceT){ok=0;L=T.initial;while(!ok||L≠){a=L.first;if(aisgoal)ok=1elseControl-put-in(L,Sons(a));}ok表示搜索結(jié)束。將初始狀態(tài)放入L。從L中取出第一個元素。若a是終態(tài)則結(jié)束。否則,將a的兒子們以某種控制方式放入L中。表L用來存放待考察的結(jié)點(diǎn)。2/7/20236計算機(jī)算法設(shè)計與分析三種搜索的不同之處樹的三種搜索方法的不同就在于它們對表L使用了不同控制方式:L是一個隊列L是一個棧L的元素按照某方式排序廣度優(yōu)先搜索深度優(yōu)先搜索啟發(fā)式搜索其中,深度優(yōu)先搜索就是回溯法。2/7/20237計算機(jī)算法設(shè)計與分析遞歸回溯法的一般形式Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}Try(s+1)意味著按照這條分支繼續(xù)嘗試。Try(s+1)返回后,若不成功,則意味著這條分支失敗了。這時必須刪除原來記錄。2/7/20238計算機(jī)算法設(shè)計與分析迭代回溯法的一般形式先讓我們回顧解空間搜索的一般形式:SearchTree(SpaceT)//{Ok=0;L=T.initial;while(!Ok||L≠Φ){a=L.first;//從L中取出第一個元素
if(aisgoal)Ok=1elseControl-put-in(L,Sons(a));}Ok表示是否找到解。表L存放待考察結(jié)點(diǎn)。對L的控制方式不同,則搜索方法也不同。在回溯法中,控制方式是棧。初始將根節(jié)點(diǎn)放入L中。2/7/20239計算機(jī)算法設(shè)計與分析迭代回溯法的一般形式先讓我們回顧解空間搜索的一般形式:SearchTree(SpaceT)//{Ok=0;L=T.initial;while(!Ok||L≠){a=L.first;if(aisgoal)Ok=1elseControl-put-in(L,Sons(a));}從L中取出第一個元素。在棧操作中就是彈出棧頂元素。在通常求解問題時,解是由逐個狀態(tài)構(gòu)成的。因此,這里還需要判斷狀態(tài)是否可接受,并進(jìn)行紀(jì)錄路徑等工作。2/7/202310計算機(jī)算法設(shè)計與分析迭代回溯法的一般形式先讓我們回顧解空間搜索的一般形式:SearchTree(SpaceT)//{Ok=0;L=T.initial;while(!Ok||L≠){a=L.first;if(aisgoal)Ok=1elseControl-put-in(L,Sons(a));}若a可接收但未終止,則要將a的后繼壓入棧中。若要拋棄狀態(tài)a,當(dāng)a是最后的兒子時,還需要消除原有的紀(jì)錄甚至回溯一步。2/7/202311計算機(jī)算法設(shè)計與分析如何判斷最后一個兒子?若只要遍歷解空間樹的結(jié)點(diǎn),那么將各結(jié)點(diǎn)按棧方式控制便可實(shí)現(xiàn)深度為主搜索。在求解問題時,需要記錄解的路徑,在回溯時還需要刪除結(jié)點(diǎn)和修改相應(yīng)信息。棧中結(jié)點(diǎn)應(yīng)該分層次,而卻沒有區(qū)分其層次。這就增加了回溯判斷和操作的困難。怎么辦呢?2/7/202312計算機(jī)算法設(shè)計與分析如何判斷最后一個兒子?若只要遍歷解空間樹的結(jié)點(diǎn),那么將各結(jié)點(diǎn)按棧方式控制便可實(shí)現(xiàn)深度為主搜索。在求解問題時,需要記錄解的路徑,在回溯時還需要刪除結(jié)點(diǎn)和修改相應(yīng)信息。棧中結(jié)點(diǎn)應(yīng)該分層次,而卻沒有區(qū)分其層次。這就增加了回溯判斷和操作的困難。采用一個簡潔有效的方法:設(shè)計一個末尾標(biāo)記,每次壓棧時,先壓入末尾標(biāo)記。2/7/202313計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若棧頂元素是末尾標(biāo)記,說明這個路徑已經(jīng)到頭了,需要回溯一步?!痢聊┪?/7/202314計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若a是可以接受的,則將a加入求解的路徑中。2/7/202315計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若a是目標(biāo)節(jié)點(diǎn),則結(jié)束搜索并輸出求解的路徑。2/7/202316計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若a不是目標(biāo)節(jié)點(diǎn)且a有后繼,則將a的后繼壓入棧中。2/7/202317計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若a不是目標(biāo)節(jié)點(diǎn)又沒有后繼,則將a從解的路徑中刪除。2/7/202318計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}注意:這里的L.Push-Sons(a)要先壓入末尾標(biāo)記,然后再壓入后繼結(jié)點(diǎn)。2/7/202319計算機(jī)算法設(shè)計與分析用末尾標(biāo)記的迭代回溯Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}a既不是目標(biāo)又沒有后繼,則將a刪除。請注意Move-off與Backstep的區(qū)別?!?/7/202320計算機(jī)算法設(shè)計與分析Backastep與Move-offBackstep的動作:××末尾Move-off的動作:×非末尾Move-off需要做的只是刪除自身的記錄而轉(zhuǎn)向兄弟結(jié)點(diǎn)。而Backstep除此之外,還需要刪除父節(jié)點(diǎn)的記錄而轉(zhuǎn)向叔叔結(jié)點(diǎn)。2/7/202321計算機(jī)算法設(shè)計與分析迭代回溯法的一般形式Backtrack(TreeT){Ok=0;L.Push(T.root);while(!Ok||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){Ok=1;Output()}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}2/7/202322計算機(jī)算法設(shè)計與分析不可接受的結(jié)點(diǎn)破壞了解的相容條件的結(jié)點(diǎn)超出了狀態(tài)空間的范圍,或者說不滿足約束條件,的結(jié)點(diǎn);評價值很差的結(jié)點(diǎn),即已經(jīng)知道不可能獲得解的結(jié)點(diǎn);已經(jīng)存在于被考察的路徑之中的結(jié)點(diǎn),這種結(jié)點(diǎn)會造成搜索的死循環(huán)。2/7/202323計算機(jī)算法設(shè)計與分析N后問題要求在一個n×n的棋盤上放置n個皇后,使得她們彼此不受攻擊。按照國際象棋的規(guī)則,一個皇后可以攻擊與之同一行或同一列或同一斜線上的任何棋子。因此,N后問題等價于:要求在一個n×n的棋盤上放置n個皇后,使得任意兩個皇后不得在同一行或同一列或同一斜線上。2/7/202324計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}讓我們先回顧遞歸回溯法的一般形式:
2/7/202325計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}s為準(zhǔn)備放置后的行數(shù)。候選者為0到n–1列。2/7/202326計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}j=–1;q=0;令列標(biāo)志j為–1
,q表示未成功。(未成功且還有候選者){(!q&&j<n){列數(shù)不到n就還有候選者。挑選下一個候選者next;列數(shù)加一即為next。j++;2/7/202327計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}j=–1;q=0;(!q&&j<n){j++;(next可接受){放置后各后都安全,便可接受。用函數(shù)Safe(s,j)進(jìn)行位置(s,j)是否安全的判斷。(Safe(s,j)){2/7/202328計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}j=–1;q=0;(!q&&j<n){j++;記下該行后的位置(列數(shù))。用函數(shù)Record(s,j)記下位置(s,j)。(Safe(s,j)){記錄next;Record(s,j);2/7/202329計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if
ifelseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}j=–1;q=0;(!q&&j<n){j++;n行后都放完就成功了。
q賦值為1,表示已經(jīng)完成,退出循環(huán)。(Safe(s,j)){Record(s,j);(滿足成功條件){成功并輸出結(jié)果}(s=
=n–1){q=1;Output();}2/7/202330計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if
ifelseTry(s+1);ifreturnj=–1;q=0;(!q&&j<n){j++;(Safe(s,j)){Record(s,j);(s=
=n–1){q=1;Output();}未完成,放s+1行。(不成功)刪去next的記錄;}}不成功,刪去后在該行的位置。(!q)Move-off(s,j);}}}成功與否}q}2/7/202331計算機(jī)算法設(shè)計與分析用遞歸回溯法求N后問題Try(s){
while
if
ifelseTry(s+1);ifreturnj=–1;q=0;(!q&&j<n){j++;(Safe(s,j)){Record(s,j);(s==n–1){q=1;Output();}q}(!q)Move-off(s,j);}}}現(xiàn)在便得到了求N后的回溯程序。2/7/202332計算機(jī)算法設(shè)計與分析求解N后問題中的數(shù)據(jù)表示數(shù)組B[n]表示棋盤。若B[i]=j,0≤i,j<n,表示棋盤的第i行第j列上有皇后。數(shù)組C[j]=1表示第j列上無皇后,0≤j<n。數(shù)組D[k]=1表示第k條下行對角線(↘)上無皇后。這里k=i+j,0≤k≤2(n–1)。0123450123452/7/202333計算機(jī)算法設(shè)計與分析求解N后問題中的數(shù)據(jù)表示數(shù)組B[n]表示棋盤。若B[i]=j,0≤i,j<n,表示棋盤的第i行第j列上有皇后。數(shù)組C[j]=1表示第j列上無皇后,0≤j<n。數(shù)組D[k]=1表示第k條下行對角線(↘)上無皇后。這里k=i+j,0≤k≤2(n–1)。數(shù)組U[k]=1表示第k條上行對角線(↗)上無皇后。這里k=i–j,–n+1≤k≤n–1。0123450123452/7/202334計算機(jī)算法設(shè)計與分析求解N后問題中的子程序Record(s,j){k=s–j+n–1;B[s]=j;C[j]=0;D[s+j]=0;U[k]=0;}Move-off(s,j){k=s–j+n–1;B[s]=-1;C[j]=1;D[s+j]=1;U[k]=1;}Safe(s,j){k=s–j+n–1;if(C[j]==1&&U[k]==1&&D[s+j]==1)returntrueelsereturnfalse;}此處k是上行對角線的下標(biāo),為什么要進(jìn)行這樣一個計算呢?2/7/202335計算機(jī)算法設(shè)計與分析求解N后問題的主程序N-Queens(){intB[n],C[n],D[2n–1],U[2n–1];for(j=0,j<n;j++){B[j]=-1;C[j]=1;U[2j]=1;U[2j+1]=1;D[2j]=1;D[2j+1]=1;}try(0);Output(B);}將數(shù)組B[],C[],U[]和D[]都賦予初值。從第一行開始遞歸2/7/202336計算機(jī)算法設(shè)計與分析N后問題的迭代程序先看看迭代回溯法的一般形式:2/7/202337計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||L≠){a=L.Pop();ifelseif(aisgood){Record(a);if(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}L.Push(T.root);(aisthelastmark)Backastep();迭代從第一行(行號為0)開始,將第一行的0~n–1列和n壓入棧中,這里n作為末尾標(biāo)記。2/7/202338計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||L≠){a=L.Pop();ifelseif(aisgood){Record(a);if(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}L.Push(T.root);(aisthelastmark)Backastep();i=0;L.Push(n,
0,1,2,…);棧指針p<0,即棧為空。a是末尾標(biāo)記則回溯。p>=0)2/7/202339計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseif(aisgood){Record(a);if(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}(aisthelastmark)Backastep();i=0;L.Push(n,0,1,2,…);(a=
=n)Backastep;回溯需要退回一行,即i–
–;同時刪除該行的原紀(jì)錄。2/7/202340計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseif(aisgood){Record(a);if(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}i=0;L.Push(n,0,1,2,…);(a=
=0)Backastep;(a==n){i–
–;a=B[i];Move-off(i,a);}若置放后的位置是安全的,則是好的位置?,F(xiàn)設(shè)有謂詞safe(i,a)表示第i行第a列是安全的位置。2/7/202341計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseifif(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}i=0;L.Push(n,0,1,2,…);(a==n)
{i–
–;a=B[i];Move-off(i,a);}(Safe(i,a))
{Record(i,a);如果safe(i,a),則放下后,即Record(a)。2/7/202342計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseifif(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}i=0;L.Push(n,0,1,2,…);(a==n){i–
–;a=B[i];Move-off(i,a);}(Safe(i,a)){Record(i,a);如果到了第n行,則成功。(i=
=n–1)2/7/202343計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseifif(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}i=0;L.Push(n,0,1,2,…);(a==n){i–
–;a=B[i];Move-off(i,a);}(Safe(i,a)){Record(i,a);(i=
=n–1){i++;L.Push(n,
0,1,2,…);}}}}
只要沒到第n行,則總是有后繼的。2/7/202344計算機(jī)算法設(shè)計與分析N后問題的迭代程序Backtrack(TreeT){Ok=0;while(!Ok||p>=0){a=L.Pop();ifelseifif(aisgoal){Ok=1;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}i=0;L.Push(n,0,1,2,…);(a==n){i–
–;a=B[i];Move-off(i,a);}(Safe(i,a)){Record(i,a);{i++;L.Push(n,0,1,2,…);}}}}
于是就得到了N后問題的迭代程序。注:這里的幾個子程序與遞歸程序中的完全相同。(i=
=n–1)請同學(xué)們自己考慮棧的操作。2/7/202345計算機(jī)算法設(shè)計與分析迭代回溯解N后問題的主程序N-Queens(n){intB[n],C[n],D[2n–1],U[2n–1];T[n2];for(j=0,j<n;j++){B[j]=-1;C[j]=1;U[2j]=1;U[2j+1]=1;D[2j]=1;D[2j+1]=1;}intp=–1;//棧初始化為空//Backtrack(n,B);}T[]為棧,最多能有n2個候選者。2/7/202346計算機(jī)算法設(shè)計與分析N后問題的時間復(fù)雜性如果只要找出N后問題的一個解,那么這是一個求路徑的問題。求路徑:只需要找到一條路徑便可以得到解。設(shè)每個狀態(tài)有k個后繼,其搜索樹為K叉樹,其結(jié)點(diǎn)總數(shù)為kn+1–1,遍歷的時間為O(kn),這里n為找到解的路徑長度。N后問題的路徑深度為n,可選擇的后繼有n個,所以時間復(fù)雜性為O(nn)。2/7/202347計算機(jī)算法設(shè)計與分析旅行售貨員問題TSP:某售貨員到若干城市去推銷商品,已知各城市之間的路程(或旅費(fèi))。他要選定一條路線,經(jīng)過每個城市一遍最后回到駐地的路線,使得總的路程(或總旅費(fèi))最小。設(shè)G=(V,E)是一個帶權(quán)圖。圖中各邊的費(fèi)用(權(quán)值)為正。圖中一條周游路線是包括V中所有頂點(diǎn)的回路。一條周游路線的費(fèi)用是該路線上所有邊的費(fèi)用之和。所謂旅行售貨員問題就是要在圖G中找出一條最小費(fèi)用的周游路線。2/7/202348計算機(jī)算法設(shè)計與分析考慮TSP的遞歸回溯算法Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}線路上第s個結(jié)點(diǎn)只需依次考察n–1個結(jié)點(diǎn),即for(i=2;i<=n;i++)下一個候選就是i。2/7/202349計算機(jī)算法設(shè)計與分析考慮TSP的遞歸回溯算法Try(s){
if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}for(i=2;i<=n;i++){結(jié)點(diǎn)i尚未在路線中且總耗費(fèi)值不大。就是將結(jié)點(diǎn)i放入路線中并修改耗費(fèi)值2/7/202350計算機(jī)算法設(shè)計與分析考慮TSP的遞歸回溯算法Try(s){
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}for(i=2;i<=n;i++){if(Accept(i)){Record(s,i);s==n-1若新線路更好,就用新線路取代老線路。2/7/202351計算機(jī)算法設(shè)計與分析考慮TSP的遞歸回溯算法Try(s){
elseTry(s+1);
if(不成功)刪去next的記錄;}}return成功與否}for(i=2;i<=n;i++){if(Accept(i)){Record(s,i);if(s==n-1){if(better)TakeNewPath();無所謂成功與否,因?yàn)槊織l周游路線都要進(jìn)行比較。2/7/202352計算機(jī)算法設(shè)計與分析考慮TSP的遞歸回溯算法Try(s){
elseTry(s+1);Move-off(s,i)}return}
for(i=2;i<=n;i++){if(Accept(i)){Record(s,i);if(s==n-1){if(better)TakeNewPath();2/7/202353計算機(jī)算法設(shè)計與分析TSP的遞歸回溯算法Try(s){for(i=2;i<=n;i++)if(Accept(i)){Record(s,i);if(s==n-1)if(better)TakeNewPath();elseTry(s+1);Move-off(s,i)}return}現(xiàn)在便得到了TSP問題的遞歸回溯算法的程序。2/7/202354計算機(jī)算法設(shè)計與分析求解TSP的數(shù)據(jù)結(jié)構(gòu)數(shù)組C[n][n]存放個城市間的費(fèi)用值。數(shù)組P[n]記錄已經(jīng)找到的費(fèi)用最小的周游路線,C為其相應(yīng)的費(fèi)用,C初值為∞。數(shù)組N[n]記錄目前正在尋找的周游路線,NC為其相應(yīng)的費(fèi)用;若NC+C[N[n]][1]小于C,則路線N更佳,于是P[]=N[],C=NC+C[N[n]][1]。若結(jié)點(diǎn)next不是N中已有結(jié)點(diǎn),且C大于NC+C[N[i]][next],則結(jié)點(diǎn)next可接受。2/7/202355計算機(jī)算法設(shè)計與分析TSP的遞歸程序TryTry(s){for(i=2;i<=n;i++)if(Accept(i)){Record(s,i);if(s==n-1)if(better)TakeNewPath();elseTry(s+1);Move-off(s,i)}return}2/7/202356計算機(jī)算法設(shè)計與分析TSP的遞歸程序TryTry(s){for(i=2;i<=n;i++)ifRecord(s,i);if(s==n-1)if(better)TakeNewPath();elseTry(s+1);Move-off(s,i)}return}(C–NC>C[N[s]][i]
&&T[i]){數(shù)組T[]表示結(jié)點(diǎn)i尚未被選2/7/202357計算機(jī)算法設(shè)計與分析TSP的遞歸程序TryTry(s){for(i=2;i<=n;i++)ifRecord(s,i);if(s==n-1)ifelseTry(s+1);Move-off(s,i)}return}(C>NC+C[N[n]][1])TakeNewPath();(C–NC>C[N[s]][i]
&&T[i]){耗散值更小,則更好。2/7/202358計算機(jī)算法設(shè)計與分析Try中的子程序Record(s,i);{NC=NC+C[N[s]][i];T[i]=0;N[s+1]=i;}Move-off(s,i);{NC=NC–C[N[s]][i];T[i]=1;N[s+1]=0;}TakeNewPath(){for(i=1;i<=n;i++)P[i]=N[i];C=NC+C[N[n]][1];}2/7/202359計算機(jī)算法設(shè)計與分析遞歸回溯求TSP的主程序TSP(n,C[n][n]){for(i=1;i<=n;i++){N[i]=0;P[i]=0;T[i]=1}NC=0;C=∞;N[1]=1;T[1]=0;Try(1);Output(P);}2/7/202360計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序?yàn)榱吮阌诘绦蛑谢厮莸呐袛?,我們將城市結(jié)點(diǎn)編號為1~n,用編號0作為末尾的標(biāo)記。先回顧一下采用末尾標(biāo)記的迭代回溯法:2/7/202361計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){unfinish=true;L.Push(T.root);while(unfinish||L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal){unfinish=false;Output();}elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}要比較所有路徑,無需此句。2/7/202362計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){L.Push(T.root);while(L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}初始化后壓入第一個結(jié)點(diǎn)。2/7/202363計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);
while(L≠){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}j為棧指針。2/7/202364計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(L.size()>0){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}若棧不空。2/7/202365計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(aisthelastmark)Backastep();elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}末尾標(biāo)記為0。2/7/202366計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0)Backastep();elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}末尾標(biāo)記為0。2/7/202367計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(j–1,N[j]);j––;}elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}回溯:刪除第j個結(jié)點(diǎn),然后j––。2/7/202368計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(j–1,N[j]);j––;}elseif(aisgood){Record(a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}a不在路線中且新增后的費(fèi)用仍低。2/7/202369計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(j–1,N[j]);j––;}elseif(T[a]&&C–NC>C[N[j]][a]){Record(j,a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}已經(jīng)n個結(jié)點(diǎn)且新路線的費(fèi)用更低。這個判斷不再需要了。2/7/202370計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(j–1,N[j]);j––;}elseif(T[a]&&C–NC>C[N[i]][a]){Record(j,a);if(aisgoal)Output();elseif(ahassons)L.Push-Sons(a)elseMove-off(a);}}}已經(jīng)n個結(jié)點(diǎn)且新路線的費(fèi)用更低。2/7/202371計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){
j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(j–1,N[j]);j––;}elseif(T[a]&&C–NC>C[N[i]][a]){Record(N[j],a);if(j==n
-1){if(C>NC+C[a][1])
{TakeNewPath();}Move-off(j,a);}
else
{j++;L.Push-Sons(a)}}}
2/7/202372計算機(jī)算法設(shè)計與分析考慮TSP的迭代程序Backtrack(TreeT){j=1;N[j]=1;L.Push-Sons(1);while(j>0){a=L.Pop();if(a==0){Move-off(N[j–1],N[j]);j––;}elseif(T[a]&&C–NC>C[N[i]][a]){Record(N[j],a);if(s==n){if(C>NC+C[a][1])
{TakeNewPath();Move-off(N[j],a);}}else{j++;L.Push-Sons(a)}}}
這就是TSP的迭代程序。2/7/202373計算機(jī)算法設(shè)計與分析迭代回溯求TSP的主程序TSP(n,C[n][n]){for(i=1;i<=n;i++){N[i]=0;P[i]=0;T[i]=1}NC=0;C=∞;N[1]=1;T[1]=0;Backtrack(n,C);Output(P);}2/7/202374計算機(jī)算法設(shè)計與分析求解TSP的時間復(fù)雜性顯然TSP是一個求排列的問題。求排列:確定n個元素的滿足某種性質(zhì)的排列。其搜索樹稱為排列樹,通常有n!個葉結(jié)點(diǎn),因此遍歷排列樹需要時間為O(n!)。所以TSP問題的時間復(fù)雜性為O(n!)2/7/202375計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題類似于TSP,用一個數(shù)組P[n]存放目前取得的最優(yōu)解,用變量V表示其價值;再用一個數(shù)組N[n]來產(chǎn)生新的解,用變量NV表示其價值,用變量W表示當(dāng)前重量。如果新解更優(yōu),則替代原來的最優(yōu)解,否則就丟棄新解。然后回溯尋找下一個新解。為此,我們先回顧一下回溯法的一般遞歸算法:2/7/202376計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}考察的第s個物品2/7/202377計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}只考慮兩種情況,選或不選,即for(i=0;i<2;i++)下個候選是i。2/7/202378計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){
if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}令A(yù)ccept(s)判斷s可接受令Record(s)記錄s2/7/202379計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){if(Accept(s){Record(s,i)if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}物體s可放入背包中將物體s放入背包中2/7/202380計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){if(Accept(s){Record(s,i)
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}增加物體s未超過背包容量。if(W+w[s]*i<=C){2/7/202381計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){
if(W+w[s]*i<=C){Record(s,i)
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}將物體s放入背包中即將s放入背包中并修改權(quán)重與容量。N[s]=i;W=W+w[s]*i;NV=NV+v[s]*i;}2/7/202382計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){
if(W+w[s]*i<=C){
N[s]=i;W=W+w[s]*i;NV=NV+v[s]*i;}
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}將物體s放入背包中即將s放入背包中并修改權(quán)重與容量。2/7/202383計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){
for(i=0;i<2;i++){
if(W+w[s]*i<=C){
N[s]=i;W=W+w[s]*i;NV=NV+v[s]*i;}
if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}s==n2/7/202384計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}for(i=0;i<2;i++){(Accept(s){Record(s,i)(s==n)s=
=n{if(better)TakeNewChoice();}2/7/202385計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){做挑選候選者的準(zhǔn)備;while(未成功且還有候選者){挑選下一個候選者next;if(next可接受){記錄next;if(滿足成功條件){成功并輸出結(jié)果}elseTry(s+1);if(不成功)刪去next的記錄;}}return成功與否}for(i=0;i<2;i++){(Accept(s){Record(s,i)(s==n){if(better)TakeNewChoice();}這里無論成功與否都要繼續(xù)考察Move-off(s,i);}return}“記錄”的逆操作2/7/202386計算機(jī)算法設(shè)計與分析用回溯法解0-1背包問題Try(s){for(i=0;i<2;i++)if(Accept(i)){Record(s,i);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- EPC模式承包人建議書及承包人實(shí)施方案
- 食品檢驗(yàn)工技師高級技師-綜合題(二)-真題-無答案
- 2024-2025學(xué)年新教材高中物理第九章靜電場及其應(yīng)用第1節(jié)電荷課堂練習(xí)含解析新人教版必修3
- 四年級數(shù)學(xué)下冊四三角形三角形的分類教學(xué)反思西師大版
- 山東專用2024年高考生物二輪復(fù)習(xí)第一篇專題3考向2細(xì)胞的分化衰老凋亡和癌變學(xué)案
- 2024-2025學(xué)年高中歷史專題六穆罕默德阿里改革一亟待拯救的文明古國教學(xué)教案人民版選修1
- 網(wǎng)絡(luò)通訊技術(shù)支持與服務(wù)合同
- 網(wǎng)絡(luò)營銷趨勢分析作業(yè)指導(dǎo)書
- 網(wǎng)絡(luò)營銷搜索引擎優(yōu)化合同
- 網(wǎng)絡(luò)安全解決方案合同
- 外貿(mào)業(yè)務(wù)與國際市場培訓(xùn)課件
- 信創(chuàng)醫(yī)療工作總結(jié)
- 教師教育教學(xué)質(zhì)量提升方案
- 滅火器的規(guī)格與使用培訓(xùn)
- 2024《中央企業(yè)安全生產(chǎn)治本攻堅三年行動方案(2024-2026年)》
- 紀(jì)錄片《園林》解說詞
- 建筑專題攝影培訓(xùn)課件
- 《民間文學(xué)導(dǎo)論》課件
- 《輸血查對制度》課件
- 拳擊賽策劃方案
- 分離性障礙教學(xué)演示課件
評論
0/150
提交評論