C++_揹包問題求解

問題描述

問題描述:設有n件體積分別爲w1、w2……wn的物品和一個能裝載總體積爲T的揹包,要求從n件物品中挑選若干件物品,其總體積之和恰好裝滿揹包。若能,則揹包有解,否則無解;

求解方法:先將n件物品順序排列,依次裝入揹包,每裝入一件即檢查當時揹包物品體積是否超過T,若裝入該物品後不超過揹包容量T,則裝入,否則棄之取下一個,直到裝滿揹包爲止。若在裝入若干物品後背包未滿,但又無其他物品可選時,說明已裝入揹包內的物品不合適,需從揹包中取出最後裝入的物品,繼續在其他未裝入的物品中挑選,如此重複知道裝滿揹包(有解)或者無物品可選(無解);

輸入輸出樣例:若T=10;W=(4,7,3,5,4,2)時,執行程序,輸出結果爲Wi=(4,4,2)。

設計思路

設計思路:設一維數組W[1:n]用來存放n件物品的體積,棧S[1:n]用來存放放入揹包內的物品的序號,T爲揹包能容納的體積,i爲待選物品序號。每進棧一件物品,就從T中減去該物品的體積,若T-W[i]>=0,則該物品可選,若T-W[i]<0,則該物品不可選,若i>n,則需退棧,若此時棧空,則說明無解。

數據結構:W[1:n]:存放n件物品的體積。S[1:n]:存放放入揹包內物品的序號。

算法描述:

PACK( T, n, W, S, top )

top<-0; i<-1

while(T>0) and (i<=n) do

  if (T-W[i]=0) or (T-W[i])>=0) and (i<n) then

{top<-top+1; s[top]<-i; T<-T-W[i]}

If (T=0) then {“揹包有解“ return”}

else { if(i=n) and (top>0) then //取出棧頂物品//

      { i<-s[top]; top<-top-1,T<-T+W[i] }

    i<-i+1//準備挑選下一件物品// }

end ( while )

“揹包無解“ return

測試用例及結果說明

揹包容量:T=10;

物品質量:W[6]={4, 7, 3, 5, 4, 2 };

測試結果:揹包裝的物品質量爲:4,4,2;

設計及測試過程

第一步:提出問題;

第二步:問題轉換;

第三步:算法構思;

第四步:僞碼描述;

第五步:代碼編寫;

第六步:代碼測試;

第七步:代碼修正;

參考書籍:《計算機軟件技術基礎》 清華大學出版社 第三版

評價和改進

算法優點:簡潔易懂。

算法缺點:採用回溯求解,效率較低。

功能優點:能夠準確找到揹包解(揹包有解時)。

功能缺點:找到揹包第一個解後即退出,不能找到全部解。

功能拓展:在遍歷所有可能解之前不結束程序,記錄解的值之後繼續執行程序知道找出所有解。

思考的問題:如何輸出所有解。

附:源程序

#include <iostream>

#define N 7

using namespace std;

int main()

{

    int i, w[N], s[N],vm[N], C, top, j, vi[N], V=0, Vmax=0, vitop;

    cout<<"請輸入揹包容量"<<endl;

    cin>>C;

    cout<<"請輸入6件物品體積及其價值"<<endl;

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

    {

         cout<<"第"<<i+1<<"件物品的體積爲  ";

         cin>>w[i];

         cout<<"價值爲  ";

         cin>>vi[i];

         cout<<endl;

    }

    w[6]=0;

    vi[6]=0;

    top=0;

    i=0;

    while(C>=0&&i<N)

    {

         cout<<"1>"<<endl;

         if(C-w[i]>=0&&i<N-1)

         {

             top++;

             s[top]=i;

             C=C-w[i];

             V=V+vi[i];

         }

         if(V>Vmax)

         {

             Vmax=V;

             vitop=top;

             cout<<" vitop="<<vitop<<endl;

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

                  vm[j]=s[j];

         }

         else

         {

         if(i==N-1&&top>0)

         {

             i=s[top];

             top--;

             C=C+w[i];

             V=V-vi[i];

         }

         }

         i++;

    }

    cout<<"揹包所能容納最大物品價值爲  "<<Vmax<<endl<<"其中包含"<<endl;

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

             {

                  j=vm[i];

                  cout<<"體積爲  "<<w[j]<<"  價值爲  "<<vi[j]<<"  的第  "<<j+1<<"  件物品  "<<endl;

             }

    system("pause");

    return 0;

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章