1. 程式人生 > >回溯法,回溯法解裝載問題

回溯法,回溯法解裝載問題

一、回溯法有“通用的解題法”之稱,可以系統的搜尋一個問題的所有解或任一解。它在問題的解空間中按深度優先策略,從根節點出發,搜尋解空間樹。演算法搜尋至解空間樹的任一節點時,先判斷該節點是否包含問題的解,如果肯定不包含則跳過對以該節點為根的子樹的搜尋,回到其父節點回溯。否則,進入該子樹,繼續按深度優先策略搜尋。

利用回溯法解問題時一般按以下三步驟:

1)定義問題的解空間;

2)確定易於搜尋的解空間結構;

3)以深度優先策略搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋;

二、回溯法應用——裝載問題

一批集裝箱共n個要裝上2艘載重量分別為c1和c2的輪船,其中集裝箱i的重量為Wi且W1+W2+……+Wn<=c1+c2;試確定一個合理的裝載方案使這n個集裝箱裝上這兩艘輪船。

#include<stdlib.h>
#include<stdio.h>
#include<iostream.h>

typedef int Status;
typedef int Type;

int n=0;    //集裝箱數
Type *x=(Type*)malloc((50)*sizeof(Type));//當前解
Type *bestx=(Type*)malloc((50)*sizeof(Type));//當前最優解
Type c=0,   //第一艘輪船的載重量
    cw=0,       //當前載重量
    bestw=0,    //當前最優載重量
    r=0,
    *w=(Type*)malloc((50)*sizeof(Type));    //集裝箱重量陣列

int Backtrack(int i)//搜尋第i層節點
{
    int j_index;
/*如果到達葉結點,則判斷當前的cw,如果比前面得到的最優解bestw 好,則替換原最優
解。*/
    if(i>n)
    {
        if(cw>bestw)
        {
            for(j_index=1; j_index<=n; j_index++)
                bestx[j_index]=x[j_index]; bestw=cw;
        }
        return 1;
    }

    //搜尋子樹
    r-=w[i];
   if(cw+w[i]<=c)//搜尋左子樹,如果當前剩餘空間可以放下當前物品也就是,cw + w[ i ] <= c
    {
        x[i]=1;
        cw+=w[i];//把當前載重 cw += w[ i ]
        Backtrack(i+1);//遞迴訪問其左子樹,Backtrack( i + 1 )
        cw-=w[i];//訪問結束,回到呼叫點, cw - = w[ i ]
    }

    if(cw+r>bestw)//搜尋右子樹
    {
        x[i]=0;
          Backtrack(i+1);
     }
     r+=w[i];
}
Type* Initiate()
{
     int index=1;
     printf("輸入集裝箱個數:");
     scanf("%d",&n);
     printf("輸入輪船載重量:");
     scanf("%d",&c);

     while(index<=n)//陣列從1號單元開始儲存
      {
          printf("輸入集裝箱%d 的重量:",index);
          scanf("%d",&w[index]);
          index++;
     }

     bestw = 0;
     cw = 0;
     r = 0;
     for(index =1;index <= n; index++)
          r += w[index]; //初始時r 為全體物品的重量和
     printf("n=%d c=%d cw=%d bestw=%d r=%d\n",n,c,cw,bestw,r);

     for(index=1;index<=n;index++)
      {
          printf("w[%d]=%d          ",index,w[index]);
     }
     printf("\n");
     return w;
}
int main()
{
     int i;
     Initiate();
    //計算最優載重量
     Backtrack(1);
     for(i=1;i<=n;i++)
      {
          printf("%d        ",w[i]);
          printf("%d\n",bestx[i]);
          }
     return bestw;
}