久久久国产精品秘人口麻豆|永久免费AV无语国产|人成电影免费中文字幕|久久AV嫩草影院2

    1. <dfn id="yitbn"><samp id="yitbn"><progress id="yitbn"></progress></samp></dfn>

          <div id="yitbn"></div>

          1. 網(wǎng)站首頁
            分類導航
            試題中心
            下載中心
            英語學習
            繽紛校園
            考試論壇
            網(wǎng)站留言
            客服中心
             常用算法設計方法
            【字體:
            常用算法設計方法
            http://www.eeeigo.com 來源:老頑童 點擊: 更新:2005-4-20

            【問題】       n皇后問題

                問題描述:求出在一個n×n的棋盤上,放置n個不能互相捕捉的國際象棋“皇后”的所有布局。

                   這是來源于國際象棋的一個問題;屎罂梢匝刂v橫和兩條斜線4個方向相互捕捉。如圖所示,一個皇后放在棋盤的第4行第3列位置上,則棋盤上凡打“×”的位置上的皇后就能與這個皇后相互捕捉。

                  

            1

            2

            3

            4

            5

            6

            7

            8

             

             

            ×

             

             

            ×

             

             

            ×

             

            ×

             

            ×

             

             

             

             

            ×

            ×

            ×

             

             

             

             

            ×

            ×

            Q

            ×

            ×

            ×

            ×

            ×

             

            ×

            ×

            ×

             

             

             

             

            ×

             

            ×

             

            ×

             

             

             

             

             

            ×

             

             

            ×

             

             

             

             

            ×

             

             

             

            ×

             

                從圖中可以得到以下啟示:一個合適的解應是在每列、每行上只有一個皇后,且一條斜線上也只有一個皇后。

                   求解過程從空配置開始。在第1列至第m列為合理配置的基礎上,再配置第m+1列,直至第n列配置也是合理時,就找到了一個解。接著改變第n列配置,希望獲得下一個解。另外,在任一列上,可能有n種配置。開始時配置在第1行,以后改變時,順次選擇第2行、第3行、…、直到第n行。當?shù)?/SPAN>n行配置也找不到一個合理的配置時,就要回溯,去改變前一列的配置。得到求解皇后問題的算法如下:

                   {     輸入棋盤大小值n;

                          m=0;

                          good=1;

                          do {

                                 if (good)

                                        if (m==n)

                                        {     輸出解;

                                               改變之,形成下一個候選解;

                                        }

                                        else  擴展當前候選接至下一列;

                                 else  改變之,形成下一個候選解;

                                 good=檢查當前候選解的合理性;

                          } while (m!=0);

                   }

                   在編寫程序之前,先確定邊式棋盤的數(shù)據(jù)結構。比較直觀的方法是采用一個二維數(shù)組,但仔細觀察就會發(fā)現(xiàn),這種表示方法給調(diào)整候選解及檢查其合理性帶來困難。更好的方法乃是盡可能直接表示那些常用的信息。對于本題來說,“常用信息”并不是皇后的具體位置,而是“一個皇后是否已經(jīng)在某行和某條斜線合理地安置好了”。因在某一列上恰好放一個皇后,引入一個一維數(shù)組(col[ ]),值col[i]表示在棋盤第i列、col[i]行有一個皇后。例如:col[3]=4,就表示在棋盤的第3列、第4行上有一個皇后。另外,為了使程序在找完了全部解后回溯到最初位置,設定col[0]的初值為0當回溯到第0列時,說明程序已求得全部解,結束程序運行。

                   為使程序在檢查皇后配置的合理性方面簡易方便,引入以下三個工作數(shù)組:

            (1)       數(shù)組a[ ],a[k]表示第k行上還沒有皇后;

            (2)       數(shù)組b[ ],b[k]表示第k列右高左低斜線上沒有皇后;

            (3)       數(shù)組 c[ ],c[k]表示第k列左高右低斜線上沒有皇后;

                棋盤中同一右高左低斜線上的方格,他們的行號與列號之和相同;同一左高右低斜線上的方格,他們的行號與列號之差均相同。

                   初始時,所有行和斜線上均沒有皇后,從第1列的第1行配置第一個皇后開始,在第mcol[m]行放置了一個合理的皇后后,準備考察第m+1列時,在數(shù)組a[ ]、b[ ]c[ ]中為第m列,col[m]行的位置設定有皇后標志;當從第m列回溯到第m-1列,并準備調(diào)整第m-1列的皇后配置時,清除在數(shù)組a[ ]b[ ]c[ ]中設置的關于第m-1列,col[m-1]行有皇后的標志。一個皇后在m列,col[m]行方格內(nèi)配置是合理的,由數(shù)組a[ ]、b[ ]c[ ]對應位置的值都為1來確定。細節(jié)見以下程序:

            【程序】

            # include <stdio.h>

            # include <stdlib.h>

            # define   MAXN    20

            int n,m,good;

            int col[MAXN+1],a[MAXN+1],b[2*MAXN+1],c[2*MAXN+1];

             

            void main()

            {     int j;

                   char awn;

                   printf(“Enter n:    “);   scanf(“%d”,&n);

                   for (j=0;j<=n;j++)   a[j]=1;

                   for (j=0;j<=2*n;j++)      cb[j]=c[j]=1;

                   m=1;       col[1]=1;        good=1;  col[0]=0;

                   do {

                          if (good)

                                 if (m==n)

                                 {     printf(“\t”);

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

                                               printf(“%3d\t%d\n”,j,col[j]);

                                        printf(“Enter  a  character (Q/q  for  exit)!\n”);

                                        scanf(“%c”,&awn);

                                        if (awn==’Q’||awn==’q’)      exit(0);

                                        while (col[m]==n)

                                        {     m--;

                                               a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=1;

                                        }

                                        col[m]++;

                                 }

                                 else

                                 {     a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=0;

                                        col[++m]=1;

                                 }

                          else

                          {     while (col[m]==n)

                                 {     m--;

                                        a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=1;

                                 }

                                 col[m]++;

                          }

                          good=a[col[m]]&&b[m+col[m]]&&c[n+m-col[m]];

                   } while (m!=0);

            }

                   試探法找解算法也常常被編寫成遞歸函數(shù),下面兩程序中的函數(shù)queen_all()和函數(shù)queen_one()能分別用來解皇后問題的全部解和一個解。

            【程序】

            # include <stdio.h>

            # include <stdlib.h>

            # define   MAXN    20

            int n;

            int col[MAXN+1],a[MAXN+1],b[2*MAXN+1],c[2*MAXN+1];

            void main()

            {     int j;

                   printf(“Enter n:    “);   scanf(“%d”,&n);

                   for (j=0;j<=n;j++)   a[j]=1;

                   for (j=0;j<=2*n;j++)      cb[j]=c[j]=1;

                   queen_all(1,n);

            }

             

            void queen_all(int k,int n)

            {     int i,j;

                   char awn;

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

                          if (a[i]&&b[k+i]&&c[n+k-i])

                          {     col[k]=i;

                                 a[i]=b[k+i]=c[n+k-i]=0;

                                 if (k==n)

                                 {     printf(“\t”);

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

                                               printf(“%3d\t%d\n”,j,col[j]);

                                        printf(“Enter  a  character (Q/q  for  exit)!\n”);

                                        scanf(“%c”,&awn);

                                        if (awn==’Q’||awn==’q’)      exit(0);

                                 }

                                 queen_all(k+1,n);

                                 a[i]=b[k+i]=c[n+k-i];

                          }

            }

                   采用遞歸方法找一個解與找全部解稍有不同,在找一個解的算法中,遞歸算法要對當前候選解最終是否能成為解要有回答。當它成為最終解時,遞歸函數(shù)就不再遞歸試探,立即返回;若不能成為解,就得繼續(xù)試探。設函數(shù)queen_one()返回1表示找到解,返回0表示當前候選解不能成為解。細節(jié)見以下函數(shù)。

            【程序】

            # define   MAXN    20

                   int n;

                   int col[MAXN+1],a[MAXN+1],b[2*MAXN+1],c[2*MAXN+1];

                   int queen_one(int k,int n)

                   {     int i,found;

                          i=found=0;

                          While (!found&&i<n)

                          {     i++;

                                 if (a[i]&&b[k+i]&&c[n+k-i])

                                 {     col[k]=i;

                                        a[i]=b[k+i]=c[n+k-i]=0;

                                        if (k==n) return 1;

                                        else

                                               found=queen_one(k+1,n);

                                        a[i]=b[k+i]=c[n+k-i]=1;

                                 }

                          }

                          return found;

                   }

            六、貪婪法

                   貪婪法是一種不追求最優(yōu)解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因為它省去了為找最優(yōu)解要窮盡所有可能而必須耗費的大量時間。貪婪法常以當前情況為基礎作最優(yōu)選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。

                   例如平時購物找錢時,為使找回的零錢的硬幣數(shù)最少,不考慮找零錢的所有各種發(fā)表方案,而是從最大面值的幣種開始,按遞減的順序考慮各幣種,先盡量用大面值的幣種,當不足大面值幣種的金額時才去考慮下一種較小面值的幣種。這就是在使用貪婪法。這種方法在這里總是最優(yōu),是因為銀行對其發(fā)行的硬幣種類和硬幣面值的巧妙安排。如只有面值分別為1、511單位的硬幣,而希望找回總額為15單位的硬幣。按貪婪算法,應找111單位面值的硬幣和41單位面值的硬幣,共找回5個硬幣。但最優(yōu)的解應是35單位面值的硬幣。

            【問題】       裝箱問題

                問題描述:裝箱問題可簡述如下:設有編號為0、1、…、n-1n種物品,體積分別為v0v1、…、vn-1。將這n種物品裝到容量都為V的若干箱子里。約定這n種物品的體積均不超過V,即對于0in,有0viV。不同的裝箱方案所需要的箱子數(shù)目可能不同。裝箱問題要求使裝盡這n種物品的箱子數(shù)要少。

                   若考察將n種物品的集合分劃成n個或小于n個物品的所有子集,最優(yōu)解就可以找到。但所有可能劃分的總數(shù)太大。對適當大的n,找出所有可能的劃分要花費的時間是無法承受的。為此,對裝箱問題采用非常簡單的近似算法,即貪婪法。該算法依次將物品放到它第一個能放進去的箱子中,該算法雖不能保證找到最優(yōu)解,但還是能找到非常好的解。不失一般性,設n件物品的體積是按從大到小排好序的,即有v0v1≥…≥vn-1。如不滿足上述要求,只要先對這n件物品按它們的體積從大到小排序,然后按排序結果對物品重新編號即可。裝箱算法簡單描述如下:

            {     輸入箱子的容積;

                   輸入物品種數(shù)n

                   按體積從大到小順序,輸入各物品的體積;

                   預置已用箱子鏈為空;

                   預置已用箱子計數(shù)器box_count0;

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

                   {     從已用的第一只箱子開始順序尋找能放入物品i 的箱子j;

                          if (已用箱子都不能再放物品i

                          {     另用一個箱子,并將物品i放入該箱子;

                                 box_count++;

                          }

                          else

                                 將物品i放入箱子j;

                   }

            }

                   上述算法能求出需要的箱子數(shù)box_count,并能求出各箱子所裝物品。下面的例子說明該算法不一定能找到最優(yōu)解,設有6種物品,它們的體積分別為:6045、35、20、2020單位體積,箱子的容積為100個單位體積。按上述算法計算,需三只箱子,各箱子所裝物品分別為:第一只箱子裝物品1、3;第二只箱子裝物品2、45;第三只箱子裝物品6。而最優(yōu)解為兩只箱子,分別裝物品14、52、3、6。

                   若每只箱子所裝物品用鏈表來表示,鏈表首結點指針存于一個結構中,結構記錄尚剩余的空間量和該箱子所裝物品鏈表的首指針。另將全部箱子的信息也構成鏈表。以下是按以上算法編寫的程序。

            【程序】

            # include <stdio.h>

            # include <stdlib.h>

            typedef  struct  ele

            {     int  vno;

                   struct  ele  *link;

            }     ELE;

            typedef  struct  hnode

            {     int  remainder;

                   ELE  *head;

                   Struct  hnode  *next;

            }     HNODE;

             

            void  main()

            {     int  n, i, box_count, box_volume, *a;

                   HNODE  *box_h,  *box_t,  *j;

                   ELE   *p,  *q;

                   Printf(“輸入箱子容積\n”);

                   Scanf(“%d”,&box_volume);

                   Printf(“輸入物品種數(shù)\n”);

                   Scanf(“%d”,&n);

                   A=(int *)malloc(sizeof(int)*n);

                   Printf(“請按體積從大到小順序輸入各物品的體積:”);

                   For (i=0;i<n;i++)    scanf(“%d”,a+i);

                   Box_h=box_t=NULL;

                   Box_count=0;

                   For (i=0;i<n;i++)

                   {     p=(ELE *)malloc(sizeof(ELE));

                          p->vno=i;

                          for (j=box_h;j!=NULL;j=j->next)

                                 if (j->remainder>=a[i])   break;

                          if (j==NULL)

                          {     j=(HNODE *)malloc(sizeof(HNODE));

                                 j->remainder=box_volume-a[i];

                                 j->head=NULL;

                                 if (box_h==NULL)        box_h=box_t=j;

                                 else  box_t=boix_t->next=j;

                                 j->next=NULL;

                                 box_count++;

                          }

                          else  j->remainder-=a[i];

                          for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);

                          if (q==NULL)

                          {     p->link=j->head;

                                 j->head=p;

                          }

                          else

                          {     p->link=NULL;

                                 q->link=p;

                          }

                   }

                   printf(“共使用了%d只箱子,box_count);

                   printf(“各箱子裝物品情況如下:”);

                   for (j=box_h,i=1;j!=NULL;j=j->next,i++)

                   {     printf(“%2d只箱子,還剩余容積%4d,所裝物品有;\n”,I,j->remainder);

                          for (p=j->head;p!=NULL;p=p->link)

                                 printf(“%4d”,p->vno+1);

                          printf(“\n”);

                   }

            }

             

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

            文章錄入:xihuyu2000    責任編輯:xihuyu2000  
             版權聲明
               如果本網(wǎng)站所轉載內(nèi)容不慎侵犯了您的權益,請與我們聯(lián)系,我們將會及時處理。如轉載本網(wǎng)內(nèi)容,請注明出處。
             發(fā)表評論
            關于本站 網(wǎng)站聲明 廣告服務  聯(lián)系方式  付款方式  站內(nèi)導航  客服中心  友情鏈接   
            Copyright © 2004-2006 考試吧 (eeeigo.com) All Rights Reserved 
            中國科學院研究生院中關村園區(qū)(北京市海淀區(qū))