問題描述:ios
在部分揹包問題中,能夠沒必要拿走整個一件物品,而是能夠拿走該物品的任意部分。以此求得在限定揹包總重量,從給定的物品中進行選擇的狀況下的最佳(總價值最高)的選擇方案。算法
細節須知:windows
分別輸出到同文件夾下兩個文本文件中,名稱分別是:「backpack-object.txt」和「backpack-weight.txt」。數據結構
算法原理:app
先求出全部物品的單位重量價值並進行由大到小的排序。其次從排序處於首位的物品開始選擇直到沒法完整裝入揹包的物品,將其部分裝入揹包以填滿揹包的總重量,從而求得價值最高的選擇方案。函數
1 #include <cstdio> 2 #include <iostream> 3 #include <ctime> 4 #include <windows.h> 5 #include <algorithm> 6 #include <fstream> 7 using namespace std; 8 struct object 9 { 10 int no; 11 double weight; 12 double value; 13 double average; 14 }; 15 bool cmp(const object &x, const object &y) 16 { 17 return x.average > y.average;//從小到大排<,若要從大到小排則> 18 } 19 void greedySelector(int m,int W,int solution[],struct object object[]){ 20 int i = 0,V = 0,j = 0; 21 while(object[i].weight < W) 22 { 23 solution[i] = 1; 24 W = W - object[i].weight; 25 V = V + object[i].value; 26 i++; 27 } 28 V = V + (W/object[i].weight)*object[i].value; 29 solution[i] = 1; 30 cout << "The corresponding value of the optimal option is:" << V << endl; 31 /*for( i = 0; i < m; i++) 32 { 33 if(solution[i] == 1) 34 { 35 cout << object[i].no << endl; 36 } 37 }*/ 38 } 39 int main(void) 40 { 41 LARGE_INTEGER nFreq; 42 LARGE_INTEGER nBeginTime; 43 LARGE_INTEGER nEndTime; 44 ofstream fout1; 45 ofstream fout2; 46 srand((unsigned int)time(NULL)); 47 int m,i,j,t; 48 double W; 49 double cost; 50 cout << "Please enter the number of times you want to run the program:"; 51 cin >> t; 52 fout1.open("backpack-object.txt",ios::app); 53 if(!fout1){ 54 cerr<<"Can not open file 'backpack-object.txt' "<<endl; 55 return -1; 56 } 57 fout1.setf(ios_base::fixed,ios_base::floatfield); //防止輸出的數字使用科學計數法 58 fout2.open("backpack-weight.txt",ios::app); 59 if(!fout2){ 60 cerr<<"Can not open file 'backpack-weight.txt' "<<endl; 61 return -1; 62 } 63 fout2.setf(ios_base::fixed,ios_base::floatfield); //防止輸出的數字使用科學計數法 64 for (j = 0;j < t;j++) 65 { 66 cout << "——————————————————The "<< j + 1 << "th test —————————————————"<<endl; 67 m = 1 + rand()%100000; //物品個數 68 W = 10 + rand()%100000; //揹包總重量 69 fout1 << m << ","; 70 fout2 << (int)W << ","; 71 int solution[m]; 72 object object[m]; 73 for( i = 0;i < m;i++) 74 { 75 object[i].no = i + 1; 76 object[i].value = 1 + rand()%10000; 77 object[i].weight = 1 + rand()%10000; 78 object[i].average = object[i].value/object[i].weight; 79 } 80 QueryPerformanceFrequency(&nFreq); 81 QueryPerformanceCounter(&nBeginTime); 82 sort(object,object + m,cmp); 83 greedySelector(m,W,solution,object); 84 QueryPerformanceCounter(&nEndTime); 85 cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart; 86 fout1 << cost << endl; 87 fout2 << cost << endl; 88 cout << "The running time is:" << cost << " s" << endl; 89 } 90 fout1.close(); 91 fout2.close(); 92 cout << endl; 93 cout << "Success!" << endl; 94 return 0; 95 }
程序設計思路:spa
① 數據結構:結構體中存儲物品序號、物品的重量、物品的價值、物品的單位重量價值;設計
② 利用C++自帶的sort函數對結構體按照物品的單位重量價值進行降序排列;code
③ 從排序處於首位的物品開始選擇直到沒法完整裝入揹包的物品,將其部分裝入揹包以填滿揹包的總重量,從而求得價值最高的選擇方案。orm
時間複雜性分析:
首先,須要對輸入的物品單位重量價值進行非減序排序,須要用O(nlogn)的時間。其次,當輸入的物品已按物品單位重量價值非減序排列,算法只需θ(n)的時間選擇n個物品,使算法能夠求得價值最高的選擇方案。
生成的數據可導入EXCEL中進行數據分析生成分析圖表。