本文共 5834 字,大约阅读时间需要 19 分钟。
遗传算法 0-1背包
Problem statement:
问题陈述:
We have given items i1, i2 , ..., in (the item we want to put in our bag) with associated weights w1, w2, ... wn and profit values V1, V2, ... Vn. Now the problem is how we can maximize the total benefit given a capacity of the bag is W and each item is allowed to be used for 0 or 1 time?
我们给了物品i 1 ,i 2 ,...,i n (我们要放入袋中的物品),并赋予了相关的权重w 1 ,w 2 ,... w n和利润值V 1 ,V 2 , ... V n 。 现在的问题是, 考虑到袋子的容量为W且每件物品允许使用0或1次,我们如何才能使总收益最大化 ?
Generally, there are two Knapsack problems first is fractional knapsack and second is 0-1 knapsack. In this article, we are discussing 0-1 knapsack algorithm. In fractional knapsack, you can cut a fraction of object and put in a bag but in 0-1 knapsack either you take it completely or you don’t take it.
通常,有两个背包问题,第一个是分数背包 ,第二个是0-1背包 。 在本文中,我们将讨论0-1背包算法 。 在小背包中 ,您可以切开一部分物体并放入袋中,但在0-1背包中,则可以完全拿走或不拿。
In order to solve the 0-1 knapsack problem, our greedy method fails which we used in the fractional knapsack problem. So the only method we have for this optimization problem is solved using Dynamic Programming, for applying Dynamic programming to this problem we have to do three things in this problem:
为了解决0-1背包问题 ,我们的贪婪方法失败了,我们在分数背包问题中使用了这种方法。 因此,对于此优化问题,我们仅有的唯一方法是使用动态编程解决,要将动态编程应用于此问题,我们必须在此问题中做三件事:
Optimal substructure
最佳子结构
Writing the recursive equation for substructure
编写子结构的递归方程
Whether subproblems are repeating or not
子问题是否重复
Now assume we have 'n' items 1 2 3 ... N. I will take an item and observe that there are two ways to consider the item either
现在假设我们有n个项目1 2 3 ... N。 我将拿一个项目,观察有两种方法可以考虑该项目
it could be included in knapsack
它可以包含在背包中
or you might not include it in knapsack
否则您可能不会将其包含在背包中
Likewise, every element has 2 choices. Therefore we have 2X2X2X2... Upto n choices i.e 2^n choices.
同样,每个元素都有2个选择。 因此,我们有2X2X2X2 ...最多 n个选择,即2 ^ n个选择 。
We have to consider the 2^n solution to find out the optimal answer but now we have to find that is there any repeating substructure present in the problem so that exempt from examining 2^n solutions.
我们必须考虑2 ^ n解来找到最佳答案,但是现在我们必须发现问题中是否存在任何重复的子结构,因此可以不必研究2 ^ n解 。
The recursive equation for this problem is given below:
下面给出了此问题的递归方程:
knapsack(i,w) = { max( Vi +knapsack(i-1,W-wi) , knapsack(i-1,W) ) 0,i=0 & W=0 Knapsack(i-1,W) , wi> W}
Knapsack(i-1,W) : is the case of not including the ith item. In this case we are not adding any size to knapsack.
背包(i-1,W):不包括第i个项目的情况。 在这种情况下,我们不会在背包中增加任何尺寸。
Vi + Knapsack(i-1,W-wi) : indicates the case where we have selected the ith item. If we add ith item then we need to add the value Vito the optimal solution.
Vi +背包(i-1,W-wi):表示我们选择了第i个项目的情况。 如果我们添加第一项,则需要将值Vito添加到最佳解决方案中。
Number of unique subproblems in 0-1 knapsack problem is (n X W). We use tabular method using Bottom-up Dynamic programming to reduce the time from O(2^n) to O(n X W).
0-1背包问题中唯一子问题的数量为(n XW) 。 我们使用自底向上动态编程的表格方法将时间从O(2 ^ n)减少到O(n XW) 。
Input :{w1,w2,.........wn }, W , {V1 ,V2 ,……..Vn}Output : T[n,W]1. for i = 0 to W do T[0,i] = 02. For i = 1 to n { 3. B[I,o] = 0 4. For(j=1 to W) do 5. If(wk<= j) and T[i-1,j-wk] + Vk> T[i-1,j] 6. Then T[i,j] = T[i-1,j-wk] + Vk 7. Else T[I,j] = T[i-1,j]}
1) Using recursive method
1)使用递归方法
#include// function that find maximum of two numbers int max(int a, int b) { return (a > b)? a : b; } int knapsack(int W, int w[], int V[], int n) { if (n == 0 || W == 0) return 0; // If weight of the nth item is larger than capacity(W) of Knapsack if (w[n-1] > W) return knapsack(W, w, V, n-1); // Return max(nth item included, nth item not included) else return max( V[n-1] + knapsack(W-w[n-1], w, V, n-1), knapsack(W, w, V, n-1) ); } // Driver program to test above function int main() { int w[] = { 5, 4, 6, 3}; int V[] = { 10, 40, 30, 50}; int W = 10; int n = 4; int Max; printf("details of all items : \n"); printf("Value\\Profit\tWeight\t\n"); for (int i = 0; i < n; i++) { printf("%d\t\t%d\n",V[i],w[i]); } printf("\n"); Max = knapsack(W, w, V, n); printf("Maximum profit we can obtain = %d", Max); return 0; }
Output
输出量
details of all items :Value\Profit Weight10 540 430 650 3Maximum profit we can obtain = 90
2) Using Bottom-up Dynamic programming
2)使用自下而上的动态编程
#includeint max(int a, int b) { return (a > b)? a : b; } int knapsack(int W, int w[], int V[], int n) { int i, j; int T[n+1][W+1]; for (i = 0; i <= n; i++) { for (j = 0; j <= W; j++) { if (i==0 || j==0) T[i][j] = 0; else if (w[i-1] <= j) T[i][j] = max(V[i-1] + T[i-1][j-w[i-1]], T[i-1][j]); else T[i][j] = T[i-1][j]; } } printf("DP table T[i,j] : \n"); for(i=0;i<=n;i++) { printf("i=%d\t",i); for(j=0;j<=W;j++) { printf("%d\t",T[i][j]); } printf("\n"); } printf("\n"); return T[n][W]; } int main() { int w[] = { 5, 4, 6, 3}; int V[] = { 10, 40, 30, 50}; int W = 10; int n = 4; int Max; printf("details of all items : \n"); printf("Value\\Profit\tWeight\t\n"); for (int i = 0; i < n; i++) { printf("%d\t\t%d\n",V[i],w[i]); } printf("\n"); Max = knapsack(W, w, V, n); printf("Maximum profit we can obtain = %d", Max); return 0; }
Output
输出量
details of all items :Value\Profit Weight10 540 430 650 3DP table T[i,j] :i=0 0 0 0 0 0 0 0 0 0 0 0 i=1 0 0 0 0 0 10 10 10 10 10 10i=2 0 0 0 0 40 40 40 40 40 50 50i=3 0 0 0 0 40 40 40 40 40 50 70i=4 0 0 0 50 50 50 50 90 90 90 90Maximum profit we can obtain = 90
翻译自:
遗传算法 0-1背包
转载地址:http://weazd.baihongyu.com/