算法分析与设计——蛮力法0/1背包
生活随笔
收集整理的這篇文章主要介紹了
算法分析与设计——蛮力法0/1背包
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
蠻力法0/1背包
蠻力法
蠻力法是一種簡單直接解決問題的方法,常常直接基于問題的描述,所以蠻力法也是最容易應用的方法。
蠻力法所依賴 的基本技術是遍歷,即采用一定的策略依次處理待求解問題的所有元素,從而找出問題的解。由于其需要依次窮舉待處理的元素,因此蠻力法是一種典型的指數級時間算法。
問題
給定n個重量為{w1,w2,···,wn}、價值為{v1,v2,···,vn}的物品和一個容量為C的背包,0/1背包是一個求解這些物品中的一個最有價值的子集,并且能夠裝入到背包中。
應用實例
有n項可投資的項目,每個項目需要投入資金si,可獲利潤為vi,現有可用資金M,應選擇那些項目來投資才能獲得最大利潤。
想法
用蠻力法解決0/1背包問題,需要考慮給定n個物品集合的所有子集,找出所有重量不超過背包容量的子集,計算每個可能子集的總價值,然后找到價值最大的子集。例如,給定4個物品的重量為{7,3,4,5},價值為{42,12,40,25},和一個容量為10的背包,下表為求解的過程。
| 1 | ? | 0 | 0 |
| 2 | {1} | 7 | 42 |
| 3 | {2} | 3 | 12 |
| 4 | {3} | 4 | 40 |
| 5 | {4} | 5 | 25 |
| 6 | {1,2} | 10 | 54 |
| 7 | {1,3} | 11 | 不可行 |
| 8 | {1,4} | 12 | 不可行 |
| 9 | {2,3} | 7 | 52 |
| 10 | {2,4} | 8 | 37 |
| 11 | {3,4} | 9 | 65 |
| 12 | {1,2,3} | 14 | 不可行 |
| 13 | {1,2,4} | 15 | 不可行 |
| 14 | {1,3,4} | 16 | 不可行 |
| 15 | {2,3,4} | 12 | 不可行 |
| 16 | {1,2,3,4} | 19 | 不可行 |
偽代碼
輸入:重量{w1,w2,···,wn},價值{v1,v2,···,vn},容量C
輸出:裝入背包的物品編號
2.1 初始化背包的價值value=0;背包的重量weight=0;
2.2 對子集T的每一個元素j
2.2.1 如果weight+wj<C,則weight=weight+wj;value=value+vj;
2.2.2 否則,轉入步驟2考察下一個子集;
2.3 如果maxValue<value,則maxValue=value;S=T;
源代碼
#include<iostream> #include<cstdio> #include<cstdlib> //用于計算程序運算時間 #include<ctime>using namespace std;#define N 100struct goods{ int sign;//物品序號 int wight;//物品重量 int value;//物品價值 };int n, maxValue, cv, cw, C;//物品數量,價值最大,當前價值,當前重量,背包容量 int X[N],cx[N];//最終存儲狀態,當前存儲狀態 struct goods goods[N];int Force(int i) {if(i > n-1){if(maxValue < cv && cw + goods[i].wight <= C){for(int k = 0;k < n;k++)X[k] = cx[k];//存儲最優路徑maxValue = cv;}return maxValue;}cw = cw + goods[i].wight;cv = cv + goods[i].value;cx[i] = 1;//裝入背包Force(i+1);cw = cw-goods[i].wight;cv = cv-goods[i].value;cx[i] = 0;//不裝入背包Force(i+1);return maxValue; }int main() {clock_t starttime,finish; //用于計算時間double time;starttime=clock();//用于計算程序運行時間printf("物品種類n:");scanf("%d",&n);printf("背包容量C:");scanf("%d",&C);for(int i = 0; i < n; i++){printf("物品%d的重量w[%d]及其價值v[%d]:",i+1,i+1,i+1);scanf("%d%d",&goods[i].wight,&goods[i].value);}int sum1 = Force(0);printf("蠻力法求解0/1背包問題:\nX=[");for(int i = 0; i < n; i++){cout << X[i]<<" ";}printf("] 裝入總價值%d\n",sum1);finish=clock();time = (double)(finish-starttime)/1000;//時間單位為秒starttime=clock();//用于計算程序運行時間cout<<"time is:"<<time<<endl;return 0; }算法分析
對于一個具有n個元素的集合,其子集數量是2n,所以無論生成子集的算法效率有多高,蠻力法求解0/1背包都會是一個Ω(2n)的算法。
總結
以上是生活随笔為你收集整理的算法分析与设计——蛮力法0/1背包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机视觉编程——图像搜索
- 下一篇: 道路检测 | SNE-RoadSeg论文