`

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]);   
           
    }   
}  
分享到:
评论

相关推荐

    0-1背包问题-算法简洁易懂

    0-1背包问题算法简洁易懂 0-1背包问题简介 0-1背包问题是算法设计中的一种经典问题。它是一个组合优化问题,属于NP-hard问题。问题的描述是:给定一组物品,每个物品都有一个价值和一个重量,要求在不超过背包容量...

    利用回溯法解0-1背包问题讲解

    利用回溯法解0-1背包问题讲解 利用回溯法解0-1背包问题是子集选取问题,0-1背包问题是NP难题,回溯法可以很好地解决背包问题,以期得到最优解。 回溯法概念: * 回溯法是一个既带有系统性又带有跳跃性的搜索算法...

    0-1背包问题(回溯算法)

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

    动态规划法求解0-1背包问题实验报告.pdf

    0-1背包问题是一个经典的优化问题,主要涉及动态规划算法的运用。在这个实验报告中,学生使用Java语言解决了一个0-1背包问题的实例。以下是关于这个问题和解决方案的详细解释。 一、问题描述: 0-1背包问题的核心是...

    0-1背包_0-1背包问题_背包算法_背包_

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它源于实际生活中的装箱问题,比如如何在限定的重量限制下,选择物品以获得最大价值。在这里,我们主要探讨0-1背包问题的定义、算法...

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

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

    动态规划解决0-1背包问题

    动态规划是一种有效的算法设计策略,尤其适用于解决具有重叠子问题和最优子结构的问题,而0-1背包问题就是这种策略的一个典型应用。0-1背包问题是一个经典的组合优化问题,它源自实际生活中的资源分配问题,比如在...

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

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

    0-1背包问题 (C语言编写)

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它模拟了实际生活中的资源分配问题,例如在有限的背包容量下,如何选择物品以最大化价值。在这个问题中,每个物品都有一个重量和一个...

    NSGA2解决0-1背包问题_nsga2_cookci7_0-1NSGA2_用NSGA2解决背包问题_

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它描述的是这样的场景:有一组物品,每个物品有自己的价值和重量,且每件物品只能选择0次或1次(不能部分选取)。目标是在不超过背包...

    动态规划求解0-1背包问题的改进算法完整解释

    动态规划求解0-1背包问题的改进算法完整解释 在计算机算法设计与分析中,动态规划法是解决背包问题的常用方法之一。所谓背包问题,是指在有限的背包容量下,如何选择物品来达到最大价值的问题。在本文中,我们将对...

    0-1背包问题(动态规划)

    利用动态规划方法求解经典0-1背包问题,仅供参考,欢迎指正

    分支界限法求0-1背包问题

    0-1背包问题是一种经典的组合优化问题,在计算机科学和运筹学中有着广泛的应用。它模拟了在资源有限的情况下如何选择物品以最大化总体价值。在这个问题中,我们有一组物品,每件物品都有一个重量和一个价值,目标是...

    分支定界算法求解0-1背包问题(附MATLAB代码).rar

    0-1背包问题是一种经典的组合优化问题,在许多实际场景中都有应用,比如资源分配、生产计划、投资组合优化等。该问题的基本设定是:有一组物品,每件物品都有一个重量和一个价值,且每件物品只能选择放入背包或者不...

    0-1背包问题(回溯法)报告.doc

    0-1背包问题是一个经典的组合优化问题,常用于资源有限情况下的最优决策。在这个问题中,我们有n种物品,每种物品i有一个重量wi和一个价值vi,还有一个背包,它的容量是C。目标是选择一些物品放入背包,使得放入背包...

    C++ 0-1背包问题源代码

    在计算机科学中,0-1背包问题是一个经典的优化问题,属于NP完全问题。该问题描述如下:假设有一个背包,其最大承重为W,现在有n个物品,每个物品都有自己的重量wi和价值vi。对于每个物品,我们只能选择放或不放,不...

Global site tag (gtag.js) - Google Analytics