`

0/1背包问题-递归、动态规划

阅读更多

问题描述:给定n种物品和一个背包,物品I的重量是Wi,其价值为Vi,背包的容量为c,问如何选择装入

背包的物品,使得装入背包的物品的总价值最大?

形式化描述:给定c求一个n元1-0向量Xi(每种物品要么装要么不装)
            Wi Xi(i从1到n连乘累加,Xi=0或1)〈=c
            Vi Xi(i从1到n连乘累加,Xi=0或1) 达到最大

/*f(j,x)是当背包载重为x,可供选择的物品为0,1...j时的最优解*/
/*最优解的递归式:*/
/* f(-1,x)=-9999(负无穷大) x<0 */
/* f(-1,x)=0 x>=0 */
/* f(j,x)=max{ f(j-1,x), f(j-1,x-w[j])+p[j] } 0<=j<n */

//背包问题的递归解法
#include<iostream>
using namespace std;

int n=3;
float w[3]={2,3,4};
int p[3]={1,2,4};
float M=6.0;

int nap(int j,float X) //返回收益
{
if(j<0) return( (X<0) ? -9999:0);
if(X<w[j]) return nap(j-1,X);
else
{
   int a=nap(j-1,X);
   int b=nap(j-1,X-w[j])+p[j];
   return a>b? a:b;
}
}

int main()
{
cout<<nap(n-1,M)<<endl;
system("pause");
return 0;
}

---------------------------------------------------------------

高级程序员教程里有,不过,是递归算法实现背包问题;

try(物品i,当前选择已达到的重量和tw,本方案可能到达的总价值tv)
{ /* 考虑物品i包含在当前方案中的可能性 */
   if(包含物品i是可接受的)
      {
         将物品i包含在当前方案中;
         if(i<n-1)
           {
             try(i+1,tw+物品i的重量,tv);
            }
         else
           {
             /*又一个完整方案,因此比前面的方案好,以它作为最佳方案*/
             当前方案作为最佳方案保存;
            }
         恢复物品i不包含状态;
      }
   /*考虑物品i不包含在此方案中的可能性*/
   if(不包含物品i仅是可能的)
     {
          if(i<n-1)
             {
                try(i+1,tw,tv-物品i的价值)
              }
          else
             {
              /*又一个完整方案,因它比前面的方案好,以它作为最佳方案*/  
              以当前方案作为最佳方案保存;
             }
      }
}

#include<iostream>
using namespace std;
#define N 100

double limitw,tolv,maxv;
int option[N],cop[N];
struct
{
double w;
double v;
}a[N];

int n;   //物品数量

void find(int i,double tw,double tv)
{
int k;
if(tw+a[i].w<=limitw)             // 包含物品i是可接受的
{
cop[i]=1;
if(i<n-1) find(i+1,tw+a[i].w,tv);
else
{
    for(k=0;k<n;++k)
      option[k]=cop[k];
    maxv=tv;
}
cop[i]=0;
}
if(tv-a[i].v>maxv)              // 不包含物品i仅是可考虑的
if(i<n-1) find(i+1,tw,tv-a[i].v);
else
{
   for(k=0;k<n;++k)
     option[k]=cop[k];
   maxv=tv-a[i].v;
}
}
   
    
int main()
{
int k;
double w,v;
tolv=0.0;
cout<<"Input the total number:\n";
cin>>n;
cout<<"Input the weight and value of everyone\n";
for(k=0;k<n;++k)
{
   cin>>w>>v;
   a[k].w=w; a[k].v=v;
   tolv+=a[k].v;
}
cout<<"Input the limit weight\n";
cin>>limitw;
maxv=0.0;
for(k=0;k<n;++k) cop[k]=0;
find(0,0.0,tolv);
cout<<"The choices number is \n";
for(k=0;k<n;++k)
    if(option[k]) cout<<k+1<<" ";    //从1开始计数
   
cout<<"\nThe total value: \n"<<maxv<<endl;

system("pause");
return 0;
}


---------------------------------------------------------------

for(int i=1;i<n;i++)
{
   for(int j=0;j<=c;j++)
   {
      if(j+W[i]<=c && f[i-1][j]+V[i]>f[i][j+W[i]])
         f[i][j+W[i]]=f[i-1][j]+V[i];
   }
}

最大值是 max{ f[n-1][k] }(0<=k<=c)


设f(n,w)表示前n个物品装w公斤重时的最大价值
递推式为
f(i,w)=max{f(i-1,w),f(i-1,w-wi)+vi}
算法如下:
开始时候f(0,i)=0 0<=i<=c
for i=1 to n
f(i,0)=0
for j=1 to c
    f(i,j)=f(i-1,j)
    if w(i)<=j and f(i,j)<f(i-1,j-w(i))+v(i) then
       f(i,j)=f(i-1,j-w(i))+v(i)
end j
end i

---------------------------------------------------------------
#include<stdio.h>
int c[10][100];/*对应每种情况的最大价值*/
int knapsack(int m,int n)
{
int i,j,w[10],p[10];
for(i=1;i<n+1;i++)
        scanf("\n%d,%d",&w[i],&p[i]);
for(i=0;i<10;i++)
      for(j=0;j<100;j++)
           c[i][j]=0;/*初始化数组*/
for(i=1;i<n+1;i++)
      for(j=1;j<m+1;j++)
           {
            if(w[i]<=j) /*如果当前物品的容量小于背包容量*/
                     {
                      if(c[i-1][j]<p[i]+c[i-1][j-w[i]])
                           /*如果本物品的价值加上背包剩下的空间能放的物品的价值大于上一次选

择的最佳方案则更新c[i][j]*/
                            c[i][j]=p[i]+c[i-1][j-w[i]];
                      else
                            c[i][j]=c[i-1][j];
                     }
              else c[i][j]=c[i-1][j];
            }
return(c[n][m]);
                    
}
int main()
{
    int m,n;int i,j;
    scanf("%d,%d",&m,&n);
    printf("Input each one:\n");
    printf("%d",knapsack(m,n));
    printf("\n");/*下面是测试这个数组,可删除*/
     for(i=0;i<10;i++)
      for(j=0;j<15;j++)
         {
          printf("%d ",c[i][j]);
             if(j==14)printf("\n");
         }
    system("pause");
}


/**  
* @author zyf 题目:给定n个物体,其中第i个物体重量wi,价值vi ,另有一个最大载重W的背包,往

里面塞东西使得总价值尽可能大  
*   
* 令f(i,j)表示用前i个物体装出重量为j的组合时的最大价值   
* f(i,j)=max{f(i-1,j), f(i-1, j-w[i])+v[i] } ,i>0, j>=w[i];   
* f(i,j) = f(i-1,j) , i>0, j<w[i];   
* f(0,j) = v[0] , i=0, j>=w[0];   
* f(0,j) = 0, i=0, j<w[0];  
*   
*/  
public class bagPro {   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        // TODO 自动生成方法存根   
           
           
        int w[] = {2,2,6,5,4};   
        int v[] = {6,3,5,4,6};   
        int c = 10;   
        int f[][] = new int [5][c+1];          
           
        int maxValue = 0;   
           
        for(int j=0 ; j<=c; j++){   
            if(j>=w[0])   
                f[0][j] =v[0];   
            else    
                f[0][j] = 0;   
        }   
           
        for(int i=1; i<w.length; i++){   
            for(int j=0; j<=c;j++){   
                if(j<w[i])   
                    f[i][j] = f[i-1][j];   
                else if(f[i-1][j]>=f[i-1][j-w[i]]+v[i])   
                    f[i][j] = f[i-1][j];   
                else  
                    f[i][j] = f[i-1][j-w[i]]+v[i];   
            }   
        }   
           
        System.out.println(f[4][c]);   
           
    }   
}   

分享到:
评论
2 楼 leizisdu 2011-11-15  
引用
if(不包含物品i仅是可能的)
感觉有些拗口
1 楼 leizisdu 2011-11-14  
博主,你牛!谢谢您的讲解

相关推荐

    0/1背包问题(蛮力、动态规划、回溯、分支限界法)

    ### 0/1背包问题(蛮力、动态规划、回溯、分支限界法) #### 实验背景 0/1背包问题是计算机科学中一个经典的组合优化问题,涉及到资源分配、决策选择等多个方面,在实际生活中也有着广泛的应用场景,如物流管理、...

    0/1背包问题的两种解法--存储优化的递归和自下而上的递归(迭代法)

    动态规划是解决0/1背包问题的主要方法。这里提到的两种解法是: 1. 存储优化的递归: 在这种方法中,我们使用一个二维数组`dp`来存储子问题的解。`dp[i][j]`表示前`i`个物品中选取若干个,其总重量不超过`j`的最大...

    0-1背包问题-递归算法 c语言实现

    ### 0-1 背包问题:递归算法 C语言实现 #### 一、问题背景及定义 0-1背包问题是一种经典的组合优化问题,在计算机科学与运筹学领域有着广泛的应用。该问题的基本形式如下:给定一组物品,每种物品都有自己的重量和...

    动态规划—0/1背包问题

    总的来说,0/1背包问题的动态规划解决方案是通过递归地构建子问题的最优解,避免了重复计算,从而有效地找到了全局最优解。这是一种强大而灵活的工具,不仅适用于0/1背包问题,还可以应用于许多其他类型的优化问题。

    0/1背包问题相关算法

    动态规划是解决0/1背包问题的常用方法,因为它保证找到最优解且效率相对较高。然而,对于特殊结构或约束的背包问题,其他算法可能会更有效。实际应用中,常常需要根据问题的具体特点和规模选择合适的求解策略。

    用回溯算法解决0/1背包问题

    ### 使用回溯算法解决0/1背包问题 在计算机科学领域,背包问题是一类经典的组合优化问题,其中0/1背包问题是指给定一组物品,每个物品都有一个重量和一个价值,目标是在不超过背包总承重的情况下,尽可能使得所选...

    vc0-1背包问题递归和动态规划的c语言代码

    ### 0-1背包问题的C语言实现:递归与动态规划 #### 一、问题背景及概述 0-1背包问题是计算机科学中一个经典的组合优化问题,它涉及到如何从一组物品中选择部分物品装入背包,使得背包的总价值最大,同时不超过背包...

    bag_0-1背包问题递归非递归动态规划_

    动态规划是解决0-1背包问题的有效方法。动态规划是一种通过构建子问题并存储其解来解决复杂问题的技术。对于0-1背包问题,我们可以创建一个二维数组`dp`,其中`dp[i][w]`表示在前`i`件物品中选择,且背包容量为`w`时...

    动态规划法和回溯法求0-1背包问题

    ### 动态规划法与回溯法解决0-1背包问题 #### 一、实验目的与背景 0-1背包问题是一种经典的组合优化问题,在实际应用中有着广泛的用途,例如资源分配、投资组合等问题都可以抽象成背包问题的形式。本实验旨在通过...

    0/1背包问题源代码

    动态规划是解决0/1背包问题的常见方法。我们可以创建一个二维数组`dp`,其中`dp[i][w]`表示在前`i`件物品中选取总重量不超过`w`时能获得的最大价值。状态转移方程为: ```markdown dp[i][w] = max(dp[i-1][w], dp[i...

    C++ 动态规划算法实现0-1背包问题

    在计算机科学中,0-1背包问题是一个经典的动态规划实例,它模拟了如何在一个容量有限的背包中选择物品以最大化价值,而每个物品都有其特定的重量和价值,并且物品要么不被选中(0),要么被完全放入背包(1)。...

    用动态规划法求解0/1背包问题

    通过上述动态规划的步骤,我们可以有效地解决0/1背包问题,找到背包能装入的最大价值。而压缩包中的1.cpp和2.H可能是实现动态规划算法的源代码文件,它们可能包含了上述过程的C++实现细节。如果需要进一步理解或优化...

    回溯法和动态规划法解01背包问题

    在提供的压缩包文件"Knapsack"中,可能包含了用某种编程语言实现的回溯法或动态规划法解01背包问题的源代码。由于代码未编译完成,你需要自行完成编译和运行,以验证和理解算法的具体实现。在调试和运行代码时,注意...

    背包问题 动态规划递归算法)

    此外,背包问题还有0-1背包(每个物品只能选一次)、完全背包(每个物品可以无限次选择)和多重背包(每个物品有固定数量,可以选多次)等变种,每种变种都需要根据实际情况调整动态规划的状态转移方程。 总之,...

    蛮力法解决0-1背包问题

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它描述的是这样的场景:你有一个容量有限的背包,里面装有若干件物品,每件物品都有自己的重量和价值,目标是选择一部分物品放入背包...

    0-1背包问题分支界限法求解-C语言实现

    ### 0-1背包问题分支界限法求解——C语言实现 #### 一、背景介绍 在计算机科学中,背包问题是一类优化问题的经典案例,它涉及到如何在满足一定约束条件下(例如背包的最大承重),从一系列物品中选择最优组合以达到...

    回溯法实现0/1背包问题

    0/1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它描述的是这样的场景:你有一个容量有限的背包,里面要装入一些物品,每种物品都有自己的重量和价值,目标是使得背包在不超过其最大...

    0-1背包递归求解Java语言描述

    0-1背包问题是一个经典的计算机科学中的优化问题,它源于组合优化和图论领域,广泛应用于资源分配、项目选择等问题。在0-1背包问题中,我们有一个容量为W的背包,以及n件物品,每件物品有其价值v[i]和重量w[i]。目标...

    算法分析与设计实验报告之0/1背包问题

    针对0/1背包问题,可以采用多种算法来求解,包括穷举法、递归法、贪心法、动态规划法、回溯法以及分支限界法等。 ##### 1. 穷举法 穷举法是最直接的方法,它通过遍历所有可能的物品组合来找到最优解。对于n个物品...

    0-1背包问题的递归源程序

    利用了递归调用,将经典的背包问题简单方便的得以实现。

Global site tag (gtag.js) - Google Analytics