遗传算法 0-1背包_0-1背包算法

遗传算法 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背包问题 ,我们的贪婪方法失败了,我们在分数背包问题中使用了这种方法。 因此,对于此优化问题,我们仅有的唯一方法是使用动态编程解决,要将动态编程应用于此问题,我们必须在此问题中做三件事:

  1. Optimal substructure

    最佳子结构

  2. Writing the recursive equation for substructure

    编写子结构的递归方程

  3. 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。 我将拿一个项目,观察有两种方法可以考虑该项目

  1. it could be included in knapsack

    它可以包含在背包中

  2. 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)

使用自底向上动态规划的算法: (Algorithm using Bottom up Dynamic Programming: )

Input :
{w1,w2,.........wn }, W , {V1 ,V2 ,……..Vn}

Output : 
T[n,W]
1. for i = 0 to W do 
    T[0,i] = 0
2. 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]
}


背包问题的C ++实现 (C++ Implementation of Knapsack problem)

1) Using recursive method

1)使用递归方法

#include<stdio.h> 

// 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    Weight
10              5
40              4
30              6
50              3

Maximum profit we can obtain = 90


2) Using Bottom-up Dynamic programming

2)使用自下而上的动态编程

#include<stdio.h> 

int 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    Weight
10              5
40              4
30              6
50              3

DP 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    10
i=2  0    0    0    0    40   40   40   40   40  50    50
i=3  0    0    0    0    40   40   40   40   40  50    70
i=4  0    0    0    50   50   50   50   90   90  90    90

Maximum profit we can obtain = 90


翻译自: https://www.includehelp.com/icp/0-1-knapsack-algorithm.aspx

遗传算法 0-1背包

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值