C++動態規劃求解0-1揹包問題

問題描述:ios

給定n種物品和一揹包。物品i的重量是wi,其價值爲vi,揹包的容量爲C。問:應該如何選擇裝入揹包的物品,是的裝入揹包中物品的總價值最大?算法

細節須知:windows

暫無。app

算法原理:spa

a.最優子結構性質設計

0-1揹包問題具備最優子結構性質。設(y1,y2,…,yn)是所給0-1揹包問題的一個最優解,則(y2,…,yn)是下面相應子問題的一個最優解。code

b.遞歸關係orm

設所給0-1揹包問題的子問題blog

的最優值爲m(i,j),即m(i,j)是揹包容量爲j,可選擇物品爲i,i+1,…,n時0-1揹包問題的最優值。有0-1揹包問題的最優子結構性質,能夠創建以下計算m(i,j)的遞歸式遞歸

    

 1 #include <iostream>
 2 #include <fstream>
 3 #include <ctime>
 4 #include <algorithm>
 5 #include <windows.h>
 6 using namespace std;  7 #define N 10000
 8 
 9 //int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的體積二、三、四、5  10 //int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的價值三、四、五、6  11 //int bagV = 8; //揹包大小
 12 int dp[N][N];                    //動態規劃表  13 //int item[5]; //最優解狀況
 14 
 15 void findMax(int k,int n,int w[],int v[]) {                    //動態規劃
 16     for (int i = 1; i <= k; i++) {  17         for (int j = 1; j <= n; j++) {  18             if (j < w[i])  19                 dp[i][j] = dp[i - 1][j];  20             else
 21                 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);  22  }  23  }  24 }  25 
 26 void findWhat(int i, int j,int w[],int v[],int item[]) {                //最優解狀況
 27     if (i > 0) {  28         if (dp[i][j] == dp[i - 1][j]) {  29             item[i] = 0;  30             findWhat(i - 1, j,w,v,item);  31  }  32         else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {  33             item[i] = 1;  34             findWhat(i - 1, j - w[i],w,v,item);  35  }  36  }  37 }  38 
 39 void print(int k,int n,int item[]) {  40     /*for (int i = 0; i < k+1; i++) { //動態規劃表輸出  41  for (int j = 0; j < n+1; j++) {  42  cout << dp[i][j] << ' ';  43  }  44  cout << endl;  45  }  46  cout << endl;*/
 47     cout <<"The item number that should be put into the backpack is:";  48     for (int i = 0; i < k+1; i++){            //最優解輸出
 49         if(item[i] == 1)  50           cout << i << ' ';  51  }  52     cout << endl;  53 }  54 
 55 int main(void)  56 {  57  LARGE_INTEGER nFreq;  58  LARGE_INTEGER nBeginTime;  59  LARGE_INTEGER nEndTime;  60  ofstream fout;  61     double cost;  62     int i,j,m,n,k;  63     cout << "Please enter the number of times you want to run the program:";  64     cin >> m;  65     //int object_amount[m];  66     //double runtime[m];
 67     fout.open("backpack.txt",ios::app);  68     if(!fout){  69         cerr<<"Can not open file 'backpack.txt' "<<endl;  70         return -1;  71  }  72     fout.setf(ios_base::fixed,ios_base::floatfield);       //防止輸出的數字使用科學計數法
 73     srand((unsigned int)time(NULL));  74     for(i = 0; i < m; i++){  75         n = rand()%10000;  76         k = rand()%10000;  77         //object_amount[i] = k;
 78         fout<<k<<",";  79         int item[k];  80         cout << "The " << i+1 << "th test's backpack lattice number is:" << n << endl;  81         cout << "The " << i+1 << "th test's object amount is:" << k << endl;  82         int w[k];  83         int v[k];  84         memset(dp,0,sizeof(dp));  85         w[0] = 0;  86         v[0] = 0;  87         for(j=1;j<k;j++){  88             w[j]=rand()%100;  89             v[j]=rand()%1000;  90  }  91         QueryPerformanceFrequency(&nFreq);  92         QueryPerformanceCounter(&nBeginTime);  93  findMax(k,n,w,v);  94  findWhat(k,n,w,v,item);  95  print(k,n,item);  96         QueryPerformanceCounter(&nEndTime);  97         cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;  98         //runtime[i]=cost;
 99         fout<<cost<<endl; 100         cout<<"The running time is:"<<cost<<" s"<<endl; 101  } 102 /* fout.open("backpack.txt",ios::app); 103  if(!fout){ 104  cerr<<"Can not open file 'backpack.txt' "<<endl; 105  return -1; 106  } 107  fout.setf(ios_base::fixed,ios_base::floatfield); //防止輸出的數字使用科學計數法 108  for(i=0;i<m;i++){ 109  fout<<object_amount[i]<<","<<runtime[i]<<endl; 110  }*/
111  fout.close(); 112     cout<<"Success!"<<endl; 113     return 0; 114 }

程序設計思路:

根據算法原理中所述遞歸關係,遞歸計算所有的m(i,j),獲得不一樣狀況下的最優解。

假設m[1][c]給出所要求的的0-1揹包問題的最優值。相應的最優解計算以下:

若是m[1][c]=m[2][c],則x1=0;不然x1=1.當x1=0是,由m[2][c]繼續構造最優解;當x1=1時,有m[2][c-w1]繼續構造最優解。以此類推,可構造出相應的最優解(x1,x2,…,xn)。

時間複雜性分析:

從計算m(i,j)的遞歸式容易看出,對於0-1揹包問題的求解算法須要O(nc)計算時間,而算法解出最優方案須要O(n)計算時間,當揹包容量c很大時,算法須要的計算時間較多。

生成的數據可導入EXCEL中進行數據分析生成分析圖表。

相關文章
相關標籤/搜索