黄色在线观看视频-黄色在线免费看-黄色在线视频免费-黄色在线视频免费看-免费啪啪网-免费啪啪网站

查看全部128種考試
1
2
3
4
5
6
7
8
9
10
xihuyu2000  
【字體: 常用算法設計方法
常用算法設計方法
djks.exam8.com 來源:老頑童 更新:2005-4-20 17:27:00 計算機等級考試 考試論壇

      1、回溯法的一般描述

    可用回溯法求解的問題P,通常要能表達為:對于已知的由n元組(x1x2,…,xn)組成的一個狀態空間E={x1,x2,…,xn)∣xiSi i=1,2,…,n},給定關于n元組中的一個分量的一個約束集D,要求E中滿足D的全部約束條件的所有n元組。其中Si是分量xi的定義域,且 |Si| 有限,i=1,2,…,n。我們稱E中滿足D的全部約束條件的任一n元組為問題P的一個解。

    解問題P的最樸素的方法就是枚舉法,即對E中的所有n元組逐一地檢測其是否滿足D的全部約束,若滿足,則為問題P的一個解。但顯然,其計算量是相當大的。

    我們發現,對于許多問題,所給定的約束集D具有完備性,即i元組(x1,x2,…,xi)滿足D中僅涉及到x1,x2,…,xi的所有約束意味著jj<i)元組(x1,x2,…,xj)一定也滿足D中僅涉及到x1,x2,…,xj的所有約束,i=1,2,…,n。換句話說,只要存在0jn-1,使得(x1,x2,…,xj)違反D中僅涉及到x1,x2,…,xj的約束之一,則以(x1,x2,…,xj)為前綴的任何n元組(x1,x2,…,xjxj+1,…,xn)一定也違反D中僅涉及到x1,x2,…,xi的一個約束,ni>j。因此,對于約束集D具有完備性的問題P,一旦檢測斷定某個j元組(x1x2,…,xj)違反D中僅涉及x1x2,…,xj的一個約束,就可以肯定,以(x1x2,…,xj)為前綴的任何n元組(x1x2,…,xjxj+1,…,xn)都不會是問題P的解,因而就不必去搜索它們、檢測它們;厮莘ㄕ轻槍@類問題,利用這類問題的上述性質而提出來的比枚舉法效率更高的算法。

    回溯法首先將問題Pn元組的狀態空間E表示成一棵高為n的帶權有序樹T,把在E中求問題P的所有解轉化為在T中搜索問題P的所有解。樹T類似于檢索樹,它可以這樣構造:

       Si中的元素可排成xi(1) xi(2) ,…,xi(mi-1) ,|Si| =mi,i=1,2,…,n。從根開始,讓T的第I層的每一個結點都有mi個兒子。這mi個兒子到它們的雙親的邊,按從左到右的次序,分別帶權xi+1(1) ,xi+1(2) ,…,xi+1(mi) ,i=01,2,…,n-1。照這種構造方式,E中的一個n元組(x1,x2,…,xn)對應于T中的一個葉子結點,T的根到這個葉子結點的路徑上依次的n條邊的權分別為x1x2,…,xn,反之亦然。另外,對于任意的0in-1En元組(x1,x2,…,xn)的一個前綴I元組(x1x2,…,xi)對應于T中的一個非葉子結點,T的根到這個非葉子結點的路徑上依次的I條邊的權分別為x1,x2,…,xi,反之亦然。特別,E中的任意一個n元組的空前綴(),對應于T的根。

       因而,在E中尋找問題P的一個解等價于在T中搜索一個葉子結點,要求從T的根到該葉子結點的路徑上依次的n條邊相應帶的n個權x1x2,…,xn滿足約束集D的全部約束。在T中搜索所要求的葉子結點,很自然的一種方式是從根出發,按深度優先的策略逐步深入,即依次搜索滿足約束條件的前綴1元組(x1i)、前綴2元組(x1,x2)、…,前綴I元組(x1,x2,…,xi),…,直到i=n為止。

       在回溯法中,上述引入的樹被稱為問題P的狀態空間樹;樹T上任意一個結點被稱為問題P的狀態結點;樹T上的任意一個葉子結點被稱為問題P的一個解狀態結點;樹T上滿足約束集D的全部約束的任意一個葉子結點被稱為問題P的一個回答狀態結點,它對應于問題P的一個解。

【問題】       組合問題

    問題描述:找出從自然數12、……、n中任取r個數的所有組合。

    例如n=5r=3的所有組合為: 

112、3              21、24              31、2、5

              413、4              51、35              61、4、5

              723、4              823、5              924、5

              103、4、5

則該問題的狀態空間為:

E={x1x2x3)∣xiS ,i=1,2,3 }     其中:S={1,2,34,5}

約束集為:    x1<x2<x3

       顯然該約束集具有完備性。

問題的狀態空間樹T

                                    

                                

 

 

 

 

 

 

 

 

 

 

 

 

 


2、回溯法的方法

       對于具有完備約束集D的一般問題P及其相應的狀態空間樹T,利用T的層次結構和D的完備性,在T中搜索問題P的所有解的回溯法可以形象地描述為:

       T的根出發,按深度優先的策略,系統地搜索以其為根的子樹中可能包含著回答結點的所有狀態結點,而跳過對肯定不含回答結點的所有子樹的搜索,以提高搜索效率。具體地說,當搜索按深度優先策略到達一個滿足D中所有有關約束的狀態結點時,即“激活”該狀態結點,以便繼續往深層搜索;否則跳過對以該狀態結點為根的子樹的搜索,而一邊逐層地向該狀態結點的祖先結點回溯,一邊“殺死”其兒子結點已被搜索遍的祖先結點,直到遇到其兒子結點未被搜索遍的祖先結點,即轉向其未被搜索的一個兒子結點繼續搜索。

    在搜索過程中,只要所激活的狀態結點又滿足終結條件,那么它就是回答結點,應該把它輸出或保存。由于在回溯法求解問題時,一般要求出問題的所有解,因此在得到回答結點后,同時也要進行回溯,以便得到問題的其他解,直至回溯到T的根且根的所有兒子結點均已被搜索過為止。

       例如在組合問題中,從T的根出發深度優先遍歷該樹。當遍歷到結點(1,2)時,雖然它滿足約束條件,但還不是回答結點,則應繼續深度遍歷;當遍歷到葉子結點(1,2,5)時,由于它已是一個回答結點,則保存(或輸出)該結點,并回溯到其雙親結點,繼續深度遍歷;當遍歷到結點(1,5)時,由于它已是葉子結點,但不滿足約束條件,故也需回溯。

3、回溯法的一般流程和技術

       在用回溯法求解有關問題的過程中,一般是一邊建樹,一邊遍歷該樹。在回溯法中我們一般采用非遞歸方法。下面,我們給出回溯法的非遞歸算法的一般流程:

N

Y

N

Y

N

N

Y

Y

建立根結點root

建立root的第一個孩子結點node

建樹完畢?

Node是葉子?

Node是解?

處理解

回溯node=parent(node)

Node還有孩子?

建立node的孩子結點node=parent(node)

建立node的孩子結點node=parent(node)

結束

開始


    在用回溯法求解問題,也即在遍歷狀態空間樹的過程中,如果采用非遞歸方法,則我們一般要用到棧的數據結構。這時,不僅可以用棧來表示正在遍歷的樹的結點,而且可以很方便地表示建立孩子結點和回溯過程。

    例如在組合問題中,我們用一個一維數組Stack[ ]表示棧。開始棧空,則表示了樹的根結點。如果元素1進棧,則表示建立并遍歷(1)結點;這時如果元素2進棧,則表示建立并遍歷(12)結點;元素3再進棧,則表示建立并遍歷(1,23)結點。這時可以判斷它滿足所有約束條件,是問題的一個解,輸出(或保存)。這時只要棧頂元素(3)出棧,即表示從結點(1,23)回溯到結點(12)。

【問題】       組合問題

    問題描述:找出從自然數1,2,…,n中任取r個數的所有組合。

    采用回溯法找問題的解,將找到的組合以從小到大順序存于a[0],a[1],…,a[r-1]中,組合的元素滿足以下性質:

(1)       a[i+1]>a[i],后一個數字比前一個大;

(2)       a[i]-i<=n-r+1。

    按回溯法的思想,找解過程可以敘述如下:

       首先放棄組合數個數為r的條件,候選組合從只有一個數字1開始。因該候選解滿足除問題規模之外的全部條件,擴大其規模,并使其滿足上述條件(1),候選組合改為1,2。繼續這一過程,得到候選組合1,2,3。該候選解滿足包括問題規模在內的全部條件,因而是一個解。在該解的基礎上,選下一個候選解,因a[2]上的3調整為4,以及以后調整為5都滿足問題的全部要求,得到解1,2,412,5。由于對5不能再作調整,就要從a[2]回溯到a[1],這時,a[1]=2,可以調整為3,并向前試探,得到解1,34。重復上述向前試探和向后回溯,直至要從a[0]再回溯時,說明已經找完問題的全部解。按上述思想寫成程序如下:

【程序】

# define   MAXN    100

int a[MAXN];

void comb(int m,int r)

{     int i,j;

       i=0;

       a[i]=1;

       do {

              if (a[i]-i<=m-r+1

              {     if (i==r-1)

                     {     for (j=0;j<r;j++)

                                   printf(“%4d”,a[j]);

                            printf(“\n”);

                     }

                     a[i]++;

                     continue;

              }

              else

              {     if (i==0)

                            return;

                     a[--i]++;

              }

       }     while (1)

}

 

main()

{     comb(5,3);

}

【問題】       填字游戲

    問題描述:在3×3個方格的方陣中要填入數字1NN10)內的某9個數字,每個方格填一個整數,似的所有相鄰兩個方格內的兩個整數之和為質數。試求出所有滿足這個要求的各種數字填法。

    可用試探發找到問題的解,即從第一個方格開始,為當前方格尋找一個合理的整數填入,并在當前位置正確填入后,為下一方格尋找可填入的合理整數。如不能為當前方格找到一個合理的可填證書,就要回退到前一方格,調整前一方格的填入數。當第九個方格也填入合理的整數后,就找到了一個解,將該解輸出,并調整第九個的填入的整數,尋找下一個解。

    為找到一個滿足要求的9個數的填法,從還未填一個數開始,按某種順序(如從小到大的順序)每次在當前位置填入一個整數,然后檢查當前填入的整數是否能滿足要求。在滿足要求的情況下,繼續用同樣的方法為下一方格填入整數。如果最近填入的整數不能滿足要求,就改變填入的整數。如對當前方格試盡所有可能的整數,都不能滿足要求,就得回退到前一方格,并調整前一方格填入的整數。如此重復執行擴展、檢查或調整、檢查,直到找到一個滿足問題要求的解,將解輸出。

回溯法找一個解的算法:

{     int m=0,ok=1;

       int n=8;

       do{

              if (ok)     擴展;

              else         調整;

              ok=檢查前m個整數填放的合理性;

       }     while ((!ok||m!=n)&&(m!=0))

       if (m!=0) 輸出解;

       else         輸出無解報告;

}

    如果程序要找全部解,則在將找到的解輸出后,應繼續調整最后位置上填放的整數,試圖去找下一個解。相應的算法如下:

回溯法找全部解的算法:

{     int m=0,ok=1;

       int n=8;

       do{

              if (ok)    

{     if (m==n)      

{     輸出解;

調整;

}

else  擴展;

                     }

                     else         調整;

              ok=檢查前m個整數填放的合理性;

       }     while (m!=0);

}

    為了確保程序能夠終止,調整時必須保證曾被放棄過的填數序列不會再次實驗,即要求按某種有許模型生成填數序列。給解的候選者設定一個被檢驗的順序,按這個順序逐一形成候選者并檢驗。從小到大或從大到小,都是可以采用的方法。如擴展時,先在新位置填入整數1,調整時,找當前候選解中下一個還未被使用過的整數。將上述擴展、調整、檢驗都編寫成程序,細節見以下找全部解的程序。

【程序】

# include <stdio.h>

# define N     12

void write(int a[ ])

{     int i,j;

       for (i=0;i<3;i++)

       {     for (j=0;j<3;j++)

                     printf(“%3d”,a[3*i+j]);

              printf(“\n”);

       }

       scanf(“%*c”);

}

 

int b[N+1];

int a[10];

int isprime(int m)

{     int i;

       int primes[ ]={2,3,5,7,11,17,19,23,29,-1};

       if (m==1||m%2=0) return 0;

       for (i=0;primes[i]>0;i++)

              if (m==primes[i])   return 1;

       for (i=3;i*i<=m;)

       {     if (m%i==0)   return 0;

              i+=2;

       }

       return 1;

}

 

int checkmatrix[ ][3]={  {-1},{0,-1},{1,-1},{0,-1},{1,3,-1},

                                   {2,4,-1},{3,-1},{4,6,-1},{5,7,-1}};

int selectnum(int start)

{     int j;

       for (j=start;j<=N;j++)

              if (b[j]) return j

       return 0;

}

 

int check(int pos)

{     int i,j;

       if (pos<0)              return 0;

       for (i=0;(j=checkmatrix[pos][i])>=0;i++)

              if (!isprime(a[pos]+a[j])

                     return 0;

       return 1;

}

 

int extend(int pos)

{     a[++pos]=selectnum(1);

       b[a][pos]]=0;

       return pos;

}

 

int change(int pos)

{     int j;

       while (pos>=0&&(j=selectnum(a[pos]+1))==0)

              b[a[pos--]]=1;

       if (pos<0)              return –1

       b[a[pos]]=1;

       a[pos]=j;

       b[j]=0;

       return pos;

}

 

void find()

{     int ok=0,pos=0;

       a[pos]=1;

       b[a[pos]]=0;

       do {

              if (ok)

                     if (pos==8)

                     {     write(a);

                            pos=change(pos);

                     }

                     else  pos=extend(pos);

              else  pos=change(pos);

              ok=check(pos);

       }     while (pos>=0)

}

 

void main()

{     int i;

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

              b[i]=1;

       find();

}

 

上一頁  [1] [2] [3] [4] [5] [6] 下一頁

轉帖于:計算機等級考試_考試吧
文章搜索  
看了本文的網友還看了:
計算機等級考試權威輔導教材: 訂書電話:010-62168566  更多>>>
網友評論
昵 稱: *  評 分: 1分 2分 3分 4分 5分
標題:   匿名發表    (共有條評論)查看全部評論>>
版權聲明 -------------------------------------------------------------------------------------
  如果計算機等級考試網所轉載內容不慎侵犯了您的權益,請與我們聯系,我們將會及時處理。如轉載本計算機等級考試網內容,請注明出處。
關于本站  網站聲明  廣告服務  聯系方式  付款方式  站內導航  客服中心  友情鏈接  考試論壇  網站地圖
Copyright © 2004-2008 考試吧計算機等級考試網 All Rights Reserved    
中國科學院研究生院權威支持(北京) 電 話:010-62168566 傳 真:010-62192699
百度大聯盟黃金認證  十佳網絡教育機構  經營許可證號:京ICP060677
主站蜘蛛池模板: 成年视频在线 | 亚洲va中文字幕 | 亚洲一区二区三区四区在线 | 国产 日韩 欧美 高清 | 亚洲无矿砖码专区2020 | 在线色视频网站 | 国产欧美大片 | 色婷婷精品综合久久狠狠 | 狠狠躁夜夜躁人人爽天天天天 | 欧美日韩图区 | 三级三级三级网站网址 | 国产精品久久一区一区 | 亚洲国产黄色 | 亚洲成人中文 | 91av中文| 欧美黄色一级在线 | 成人午夜免费剧场 | 国产成人乱码一区二区三区 | 成年人视频免费 | 国产一国产一级新婚之夜 | 视频在线h| 日韩在线理伦片免费观看 | 天天碰免费视频 | 99色网| 亚洲国产精品视频 | 99视频在线精品免费观看18 | 黄站免费| 老师影院 | 午夜免费影院 | 一级成人a毛片免费播放 | 午夜免费看片 | 国产又爽又黄又舒服又刺激视频 | 人人爱天天做夜夜爽 | 国产成人精品免费视频大全五级 | 欧美日韩不卡中文字幕在线 | 欧美一区二区三区免费观看视频 | 免费在线观看a | 日本久久一区二区 | 免费看黄在线观看 | 性欧美videos另类视频 | 91蜜臀视频 |