01背包问题不同算法设计、与对比讲解

合集下载

两种算法解决0-1背包问题的比较

两种算法解决0-1背包问题的比较
量 W V j=0 1 2 3 4 5
wi
i=0 0 0 0 0 0 0
1 w1=2 v1=12
1 0 0 12 12 12 12
2 w2=1 v2=10 3 w3=3 v3=20
W=5 2 3
0 10 12 22 22 22 0 10 12 22 30 32
4 w4=2 v4=15
❖ 动态规划法求解01背包 分段:
动态规划法策略是将问题分成多个阶段,逐段推进计算, 后继实例解由直接前趋子实例解计算得到。对于01背包问题, 可利用减一技术和最优性原则,按物品数量和背包承重量分 段。 思路:根据最优子结构性质,根据前i-1件物品中最优子集的总 价值,计算前 i 件物品中最优子集的总价值,直到i=n为止。 核心技术:需要构建二维状态矩阵DP,来保存每一步的解,供 下一步计算使用。
阶段 n
求解算法
......
动态的含义:求解算法施加的状态是变化的。 当前状态只与其直接前趋状态有关,对其直接 前趋状态施加求解算法,成为当前状态。 最优性原则 (Principle of Optimality):
求解算法 一个最优问题任何实例的最优解,是由该实例
阶段 2
求解算法
阶段 1
的子实例的最优解组成的。对特定问题该原则 不一定满足(罕见),有必要检查其适用性。 子实例组成父实例,父实例分解为子实例。
计算过程是一级一级(一阶段一阶段)地向前推进,直到最终状态。
★ 动态规划法解01背包
❖ 问题描述 已知:n 个重量为weights[w1,...,wn]、价值为values[v1,...,vn ] 的物品和一个承重量W的背包。 要求:找出最有价值子集,且能装入背包中(不超重)。
物品重量、背包承重量、物品数量都是整数。

背包问题的算法研究及应用

背包问题的算法研究及应用

背包问题的算法研究及应用背包问题是一种经典的组合优化问题,常常被用来研究在有限的空间下如何使价值最大化。

背包问题可以分为 01 背包问题、完全背包问题、多重背包问题和混合背包问题等多种类型。

这些问题的求解方法也各有特点,需要根据具体问题进行选择。

本文主要介绍 01 背包问题和完全背包问题的求解算法及应用。

一、01 背包问题01 背包问题指的是在一个容量为 V 的背包中装入物品,每件物品都有自己的体积 vi 和价值 wi,问怎样装能使背包价值最大化,且物品不能重复使用。

01 背包问题可以用贪心算法或动态规划算法进行求解。

贪心算法的思想是每次选择当前最优的物品,直到背包无法继续装下为止。

但是贪心算法不能保证一定能获得最优解。

动态规划算法则是将问题分解为子问题,并通过递推关系式来求解。

具体来说,我们定义一个 dp[i][j] 表示将前 i 件物品放入容量为 j 的背包中所能获得的最大价值,则有:dp[i][j] = max(dp[i-1][j], dp[i-1][j-vi]+wi)其中 max 表示取两者中的最大值,dp[i-1][j] 表示不选择第 i 件物品,dp[i-1][j-vi]+wi 表示选择第 i 件物品放入背包中。

根据递推关系式,我们可以得到目标值为dp[n][V],其中 n 表示物品个数。

二、完全背包问题完全背包问题指的是在一个容量为 V 的背包中装入物品,每件物品都有自己的体积 vi 和价值 wi,问怎样装能使背包价值最大化,且每件物品可以无限使用。

完全背包问题和 01 背包问题类似,也可以用贪心算法或动态规划算法进行求解。

贪心算法的思想是每次选择当前最优的物品,并一直选择直到不能再在背包中装入为止。

但是贪心算法仍然不能保证获得最优解。

动态规划算法则是将问题分解为子问题,并通过递推关系式来求解。

与 01 背包问题相比,完全背包问题的递推关系式与之略有不同,具体来说,我们定义一个 dp[i][j] 表示将前 i 件物品放入容量为 j 的背包中所能获得的最大价值,则有:dp[i][j] = max(dp[i-1][j-k*vi]+k*wi)其中 max 表示取两者中的最大值,k 表示第 i 件物品中的物品数量。

贪心算法-01背包问题

贪心算法-01背包问题

贪⼼算法-01背包问题1、问题描述:给定n种物品和⼀背包。

物品i的重量是wi,其价值为vi,背包的容量为C。

问:应如何选择装⼊背包的物品,使得装⼊背包中物品的总价值最⼤?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找⼀n元向量(x1,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi xi达最⼤.即⼀个特殊的整数规划问题。

2、最优性原理:设(y1,y2,…,yn)是 (3.4.1)的⼀个最优解.则(y2,…,yn)是下⾯相应⼦问题的⼀个最优解:证明:使⽤反证法。

若不然,设(z2,z3,…,zn)是上述⼦问题的⼀个最优解,⽽(y2,y3,…,yn)不是它的最优解。

显然有∑vizi > ∑viyi (i=2,…,n)且 w1y1+ ∑wizi<= c因此 v1y1+ ∑vizi (i=2,…,n) > ∑ viyi, (i=1,…,n)说明(y1,z2, z3,…,zn)是(3.4.1)0-1背包问题的⼀个更优解,导出(y1,y2,…,yn)不是背包问题的最优解,⽭盾。

3、递推关系:设所给0-1背包问题的⼦问题的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。

由0-1背包问题的最优⼦结构性质,可以建⽴计算m(i,j)的递归式:注:(3.4.3)式此时背包容量为j,可选择物品为i。

此时在对xi作出决策之后,问题处于两种状态之⼀:(1)背包剩余容量是j,没产⽣任何效益;(2)剩余容量j-wi,效益值增长了vi ;使⽤递归C++代码如下:#include<iostream>using namespace std;const int N=3;const int W=50;int weights[N+1]={0,10,20,30};int values[N+1]={0,60,100,120};int V[N+1][W+1]={0};int knapsack(int i,int j){int value;if(V[i][j]<0){if(j<weights[i]){value=knapsack(i-1,j);}else{value=max(knapsack(i-1,j),values[i]+knapsack(i-1,j-weights[i]));}V[i][j]=value;}return V[i][j];}int main(){int i,j;for(i=1;i<=N;i++)for(j=1;j<=W;j++)V[i][j]=-1;cout<<knapsack(3,50)<<endl;cout<<endl;}不使⽤递归的C++代码:简单⼀点的修改//3d10-1 动态规划背包问题#include <iostream>using namespace std;const int N = 4;void Knapsack(int v[],int w[],int c,int n,int m[][10]);void Traceback(int m[][10],int w[],int c,int n,int x[]);int main(){int c=8;int v[]={0,2,1,4,3},w[]={0,1,4,2,3};//下标从1开始int x[N+1];int m[10][10];cout<<"待装物品重量分别为:"<<endl;for(int i=1; i<=N; i++){cout<<w[i]<<" ";}cout<<endl;cout<<"待装物品价值分别为:"<<endl;for(int i=1; i<=N; i++){cout<<v[i]<<" ";}cout<<endl;Knapsack(v,w,c,N,m);cout<<"背包能装的最⼤价值为:"<<m[1][c]<<endl;Traceback(m,w,c,N,x);cout<<"背包装下的物品编号为:"<<endl;for(int i=1; i<=N; i++){if(x[i]==1){cout<<i<<" ";}}cout<<endl;return 0;}void Knapsack(int v[],int w[],int c,int n,int m[][10]){int jMax = min(w[n]-1,c);//背包剩余容量上限范围[0~w[n]-1] for(int j=0; j<=jMax;j++){m[n][j]=0;}for(int j=w[n]; j<=c; j++)//限制范围[w[n]~c]{m[n][j] = v[n];}for(int i=n-1; i>1; i--){jMax = min(w[i]-1,c);for(int j=0; j<=jMax; j++)//背包不同剩余容量j<=jMax<c{m[i][j] = m[i+1][j];//没产⽣任何效益}for(int j=w[i]; j<=c; j++) //背包不同剩余容量j-wi >c{m[i][j] = max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//效益值增长vi }}m[1][c] = m[2][c];if(c>=w[1]){m[1][c] = max(m[1][c],m[2][c-w[1]]+v[1]);}}//x[]数组存储对应物品0-1向量,0不装⼊背包,1表⽰装⼊背包void Traceback(int m[][10],int w[],int c,int n,int x[]){for(int i=1; i<n; i++){if(m[i][c] == m[i+1][c]){x[i]=0;}else{x[i]=1;c-=w[i];}}x[n]=(m[n][c])?1:0;}运⾏结果:算法执⾏过程对m[][]填表及Traceback回溯过程如图所⽰:从m(i,j)的递归式容易看出,算法Knapsack需要O(nc)计算时间; Traceback需O(n)计算时间;算法总体需要O(nc)计算时间。

0-1背包问题的枚举算法

0-1背包问题的枚举算法

0-1背包问题的枚举算法一、问题概述0-1背包问题是一种经典的优化问题,给定一组物品,每种物品都有自己的重量和价值,而你有一个限制容量的背包。

目标是在不超过背包容量的情况下,选择物品使得总价值最大化。

然而,在某些情况下,所有的物品都不能被放入背包中,这时就需要用到0-1背包问题的枚举算法。

二、算法原理枚举算法的基本思想是从所有可能的物品组合中逐个尝试,找出满足条件的组合。

对于0-1背包问题,我们可以枚举所有可能的物品组合,对于每个组合,计算其总价值和当前背包的剩余容量,如果总价值大于当前背包容量所能获得的最大价值,那么就将这个物品放入背包中,并更新背包剩余容量和总价值。

如果当前物品的价值小于或等于当前背包容量所能获得的最大价值,那么就将这个物品标记为0(表示已经考虑过),并继续尝试下一个物品。

最终得到的组合就是最优解。

三、算法实现以下是一个简单的Python实现:```pythondefknapsack_enumeration(items,capacity):#初始化结果列表和当前价值result=[]current_value=0#枚举所有可能的物品组合foriinrange(len(items)):#标记当前物品为0(已考虑过)items[i][1]=0#计算当前物品的价值并更新总价值forjinrange(len(items)):ifj<i:#不考虑之前的物品对当前物品的价值影响current_value+=items[j][1]*items[i][0]/capacityelse:#考虑之前的物品对当前物品的价值影响(假设不考虑前一个物品的重量)current_value+=items[j][0]*(capacity-items[i][0])/capacity#将当前物品从物品列表中移除(放入背包中)delitems[i]#将当前价值添加到结果列表中result.append(current_value)returnresult```四、应用场景枚举算法在许多实际应用中都有应用,如计算机科学、运筹学、工程学等。

动态规划求解01背包问题

动态规划求解01背包问题

动态规划求解01背包问题问题给定n种物品和⼀个背包,物品(1<=i<=n)重量是w I ,其价值v i,背包容量为C,对每种物品只有两种选择:装⼊背包和不装⼊背包,即物品是不可能部分装⼊,部分不装⼊。

如何选择装⼊背包的物品,使其价值最⼤?想法该问题是最优化问题,求解此问题⼀般采⽤动态规划(dynamic plan),很容易证明该问题满⾜最优性原理。

动态规划的求解过程分三部分:⼀:划分⼦问题:将原问题划分为若⼲个⼦问题,每个⼦问题对应⼀个决策阶段,并且⼦问题之间具有重叠关系⼆:确定动态规划函数:根据⼦问题之间的重叠关系找到⼦问题满⾜递推关系式(即动态规划函数),这是动态规划的关键三:填写表格:设计表格,以⾃底向上的⽅式计算各个⼦问题的解并填表,实现动态规划过程。

思路:如何定义⼦问题?0/1背包可以看做是决策⼀个序列(x1,x2,x3,…,xn),对任何⼀个变量xi的决策时xi=1还是xi=0. 设V(n,C)是将n个物品装⼊容量为C的背包时背包所获得的的最⼤价值,显然初始⼦问题是将前i个物品装如容量为0的背包中和把0个物品装⼊容量为j的背包中,这些情况背包价值为0即V(i,0)=V(0,j)=0 0<=i<=n, 0<=j<=C接下来考虑原问题的⼀部分,设V(I,j)表⽰将前i个物品装⼊容量为j的背包获得的最⼤价值,在决策xi时,已经确定了(x1,x2,…,xi-1),则问题处于下列两种情况之⼀:1. 背包容量不⾜以装⼊物品i,则装⼊前i-1个物品的最⼤价值和装⼊前i个物品最⼤价值相同,即xi=0,背包价值没有增加2. 背包容量⾜以装⼊物品i,如果把物品i装⼊背包,则背包物品价值等于把前i-1个物品装⼊容量为j-wi的背包中的价值加上第i个物品的价值vi;如果第i个物品没有装⼊背包,则背包价值等于把前i-1个物品装⼊容量为j的背包中所取得的价值,显然,取⼆者最⼤价值作为把物品i装⼊容量为j的背包中的最优解,得到如下递推公式为了确定装⼊背包中的具体物品,从V(n,C)的值向前推,如果V(n,C)>V(n-1,C),则表明第n个物品被装⼊背包中,前n-1个物品被装⼊容量为C-wn的背包中;否则,第n个物品没有被装⼊背包中,前n-1个物品被装⼊容量为C的背包中,依次类推,直到确认第⼀个物品是否被装⼊背包中代码C++实现1. // dp_01Knapsack.cpp : 定义控制台应⽤程序的⼊⼝点。

求解0—1背包问题算法综述

求解0—1背包问题算法综述

0-1背包问题是一种常见的动态规划问题,其目标是在给定背包容量和物品集合的情况下,选择某些物品放入背包,使得背包内物品的总价值最大。

以下是求解0-1背包问题的算法综述:
1. 定义变量和参数:
* 物品集合:包括每个物品的重量和价值。

* 背包容量:表示背包能够容纳的最大重量。

* dp数组:用于存储每个状态下的最大价值,dp[i][j]表示前i个物品、背包承重为j时的最大价值。

2. 初始化dp数组:
* 对于每个物品i和背包容量j,如果物品i能够装入背包,则令dp[i][j]为0;否则,令dp[i][j]为负无穷。

3. 递推计算dp数组:
* 对于每个物品i和背包容量j,如果物品i能够装入背包,则令dp[i][j]为当前物品的价值加上前i-1个物品、背包容量为j-w[i]时的最大价值,即dp[i][j] = dp[i-1][j-w[i]] + p[i];否则,
令dp[i][j]为前i-1个物品、背包容量为j时的最大价值,即dp[i][j] = dp[i-1][j]。

4. 返回dp数组的最后一个元素,即为所求的最大价值。

以上是求解0-1背包问题的算法综述,实际实现时可以根据具体情况进行优化,以提高算法的效率和性能。

数据结构 背包问题

数据结构 背包问题

数据结构背包问题【数据结构背包问题】【背景介绍】背包问题是一类经典的组合优化问题,通过在给定的一组物品中选择一些物品放入背包,以使得放入背包的物品总价值最大或总重量最小。

【问题描述】给定一个背包,它能够容纳一定重量的物品。

再给定一组物品,每个物品有自己的重量和价值。

要求在不超过背包容量的情况下,选择物品放入背包,使得背包中物品的总价值最大。

【算法及解决思路】⒈0 背包问题:⑴动态规划法:使用一个二维数组dpij表示前i个物品在背包容量为j时的最大总价值。

dpij的计算方法是在考虑第i个物品时,如果将其放入背包,则总价值为dpi-1j-wi + vi,如果不放入背包,则总价值为dpi-1j。

则dpij的值为这两种情况中的较大值。

⑵贪心算法:按物品的单位重量价值进行排序,然后依次选择单位重量价值最大的物品放入背包,直至放满或者无法再放入为止。

⒉0 背包问题的变体:⑴ 01背包问题:每个物品要么放入背包,要么不放入,无法进行分割。

⑵完全背包问题:每个物品可以无限次地放入背包,相当于01背包问题的物品数量为无穷。

⑶多重背包问题:每个物品有有限个数的可选择,相当于01背包问题的物品数量有限。

【算法复杂度】⒈0 背包问题:⑴动态规划法:时间复杂度为O(nW),空间复杂度为O(nW),其中n为物品数量,W为背包容量。

⑵贪心算法:时间复杂度为O(nlogn),空间复杂度为O(1)⒉0 背包问题的变体:⑴ 01背包问题:时间复杂度同⒈0。

⑵完全背包问题:时间复杂度同⒈0。

⑶多重背包问题:时间复杂度同⒈0。

【附件】:本文档不涉及附件。

【法律名词及注释】:本文档不涉及法律名词及注释。

01背包问题多种解法

01背包问题多种解法

一、问题描绘0/1 背包问题 :现有 n 种物件,对1<=i<=n,已知第i 种物件的重量为正整数W i,价值为正整数V i,背包能蒙受的最大载重量为正整数W ,现要求找出这n 种物件的一个子集,使得子集中物品的总重量不超出W 且总价值尽量大。

(注意:这里对每种物件或许全取或许一点都不取,不一样意只取一部分)二、算法剖析依据问题描绘,能够将其转变为以下的拘束条件和目标函数:nw i x i W(1)i1x i{ 0,1}( 1i n)nmax v i x i (2)i1于是,问题就归纳为找寻一个知足拘束条件( 1 ),并使目标函数式( 2 )达到最大的解向量 X(x1, x2 , x3 ,......, x n ) 。

第一说明一下0-1 背包问题拥有最优解。

假定 (x1, x2 , x3 ,......, x n ) 是所给的问题的一个最优解,则 (x2 , x3,......, x n ) 是下边问题的nw i x i W w1x1 maxn一个最优解:i 2v i x i。

假如不是的话,设( y2, y3 ,......, y n ) 是这x i{ 0,1}( 2i n)i 2n n n个问题的一个最优解,则v i y i v i x i,且 w1x1w i y i W 。

因此,i 2i 2i 2n n nv1x1v i y i v1 x1v i x i v i x i,这说明 (x1, y2 , y3 ,........, y n ) 是所给的0-1 背包问i 2i 2i 1题比 ( x1 , x2 , x3 ,........, x n ) 更优的解,进而与假定矛盾。

穷举法:用穷举法解决0-1 背包问题,需要考虑给定n 个物件会合的所有子集,找出所有可能的子集(总重量不超出背包重量的子集),计算每个子集的总重量,而后在他们中找到价值最大的子集。

因为程序过于简单,在这里就不再给出,用实例说明求解过程。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三01背包问题不同算法设计、分析与对比一.问题描述给定n种物品和一背包。

物品i的重量是wi ,其价值为vi,背包的容量为c。

问题:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大。

说明:在选择装入背包的物品时,对每种物品i只有两个选择,装入背包或不装入背包,也不能将物品装入背包多次。

二.实验内容与要求实验内容:1.分析该问题适合采用哪些算法求解(包括近似解)。

动态规划、贪心、回溯和分支限界算法。

2.分别给出不同算法求解该问题的思想与算法设计,并进行算法复杂性分析。

动态规划:递推方程:m(i,j) = max{m(i-1,j),m(i-1,j-wi)+vi} j >= wi;m(i-1,j) j < wi;时间复杂度为O(n).贪心法:算法思想:贪心原则为单位价值最大且重量最小,不超过背包最大承重量为约束条件。

也就是说,存在单位重量价值相等的两个包,则选取重量较小的那个背包。

但是,贪心法当在只有在解决物品可以分割的背包问题时是正确的。

贪心算法总是作出在当前看来最好的选择。

也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。

用贪心法设计算法的特点是一步一步地进行,根据某个优化测度(可能是目标函数,也可能不是目标函数),每一步上都要保证能获得局部最优解。

每一步只考虑一个数据,它的选取应满足局部优化条件。

若下一个数据与部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为止。

回溯法:回溯法:为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来处死那些实际上不可能产生所需解的活结点,以减少问题的计算量。

这种具有限界函数的深度优先生成法称为回溯法。

对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1向量组成,可用子集数表示。

在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入左子树。

当右子树中有可能包含最优解时就进入右子树搜索。

时间复杂度为:O(2n)空间复杂度为:O(n)分支限界算法:首先,要对输入数据进行预处理,将各物品依其单位重量价值从大到小进行排列。

在优先队列分支限界法中,节点的优先级由已装袋的物品价值加上剩下的最大单位重量价值的物品装满剩余容量的价值和。

算法首先检查当前扩展结点的左儿子结点的可行性。

如果该左儿子结点是可行结点,则将它加入到子集树和活结点优先队列中。

当前扩展结点的右儿子结点一定是可行结点,仅当右儿子结点满足上界约束时才将它加入子集树和活结点优先队列。

当扩展到叶节点时为问题的最优值。

3.设计并实现所设计的算法。

4.对比不同算法求解该问题的优劣。

这动态规划算法和贪心算法是用来分别解决不同类型的背包问题的,当一件背包物品可以分割的时候,使用贪心算法,按物品的单位体积的价值排序,从大到小取即可。

当一件背包物品不可分割的时候,(因为不可分割,所以就算按物品的单位体积的价值大的先取也不一定是最优解)此时使用贪心是不对的,应使用动态规划。

设计方法时间复杂度优点缺点速度慢动态规划Min{nc,2n} 可求得最优决策序列贪心方法O(2n)速度较快很难得到最优解回溯法O(n2n)能够得到最优解时间复杂度较高分支限界法O(2n)速度较快,易求解占用内存大,效率不高5.需要提交不同算法的实现代码和总结报告。

动态规划方法:public class Knapsack {public static void main(String[] args) {int[] value = { 0, 60, 100, 120 };int[] weigh = { 0, 10, 20, 30 };int weight = 50;Knapsack1(weight, value, weigh);}public static void Knapsack1(int weight, int[] value, int[] weigh) {int[] v = new int[value.length];int[] w = new int[weigh.length];int[][] c = new int[value.length][weight + 1];int d[] = new int [100];for (int i = 0; i < value.length; i++) {v[i] = value[i];w[i] = weigh[i];}for (int i = 1; i < value.length; i++) {for (int k = 1; k <= weight; k++) {if (w[i] <= k) {c[i][k] = max(c[i - 1][k], c[i - 1][k - w[i]] + v[i]);} else {c[i][k] = c[i - 1][k];}}}System.out.println(c[value.length - 1][weight]);}private static int max(int i, int j) {int k = i > j ? i : j;return k;}}贪心法:public class GreedyKnapSack {public static void main(String[] args) {int[] value = { 0, 60, 100, 120 };int[] weigh = { 0, 10, 20, 30 };int weight = 50;Knapsack1(weight, value, weigh);}private static void Knapsack1(int weight, int[] v, int[] w) { int n = v.length;double[] r = new double[n];int[] index = new int[n];for(int i = 0;i < n; i++) {r[i] = (double)v[i] / (double)w[i];index[i] = i;}//按单位重量价值r[i]=v[i]/w[i]降序排列double temp = 0;for(int i = 0;i < n-1;i++){for(int j = i+1;j < n;j++){if(r[i] < r[j]){temp = r[i];r[i] = r[j];r[j] = temp;int x = index[i];index[i] = index[j];index[j] = x;}}}//排序后的重量和价值分别存到w1[]和v1[]中int[] w1 = new int[n];int[] v1 = new int[n];for(int i = 0;i < n;i++){w1[i] = w[index[i]];v1[i] = v[index[i]];}System.out.println (Arrays.toString(w1));System.out.println (Arrays.toString(v1));int s=0;//包内现存货品的重量int value=0;//包内现存货品总价值for(int i = 0; i < n;i++){if(s + w1[i] < weight){value += v1[i];s += w1[i];}}System.out.println("背包中物品的最大总价值为" + value);}}回溯法:public class BacktrackKnapSack {public static void main(String[] args) {int[] value = { 0, 60, 100, 120 };int[] weigh = { 0, 10, 20, 30 };int weight = 50;Knapsack1(weight, value, weigh);}private static void Knapsack1(int weight, int[] v, int[] w) { int n = v.length;double[] r = new double[n];int[] index = new int[n];for(int i = 0;i < n; i++) {r[i] = (double)v[i] / (double)w[i];index[i] = i;}//按单位重量价值r[i]=v[i]/w[i]降序排列double temp = 0;for(int i = 0;i < n-1;i++){for(int j = i+1;j < n;j++){if(r[i] < r[j]){temp = r[i];r[i] = r[j];r[j] = temp;int x = index[i];index[i] = index[j];index[j] = x;}}}//排序后的重量和价值分别存到w1[]和v1[]中int[] w1 = new int[n];int[] v1 = new int[n];for(int i = 0;i < n;i++){w1[i] = w[index[i]];v1[i] = v[index[i]];}//调用函数KnapSackBackTrack(),输出打印装完物品以后的最大价值KnapSackBackTrack(w1,v1,w1.length,weight);}private static void KnapSackBackTrack(int[] w1, int[] v1, int length, int weight) {int CurrentWeight = 0;int CurrentValue = 0;int maxValue = 0;int i = 0;int n = v1.length;while(i >= 0){if(CurrentWeight + w1[i] < weight){CurrentWeight += w1[i];CurrentValue += v1[i];i++;}elsebreak;}if(i < n){maxValue = CurrentValue;System.out.println("1背包中物品的最大总价值为" + maxValue);}}}分支限界算法:package bag01b;import java.util.ArrayList;public class bag01do {public static void main(String[] args) {// TODO Auto-generated method stubArrayList<object> objects=new ArrayList<>();objects.add(new object(10,60));objects.add(new object(20,100));objects.add(new object(30,120));bag b=new bag(50,objects);b.findmaxvalue();b.show();}}----------------------------------------------------------------------- package bag01b;import java.util.ArrayList;import java.util.Collections;import java.util.PriorityQueue;public class bag {private int bagv;private ArrayList<object> objects;private int maxvalue;private ArrayList<object> result_objects;public bag(int v,ArrayList<object> o){super();this.bagv=v;this.objects=o;this.maxvalue=0;this.result_objects=null;Collections.sort(objects);}public void show(){System.out.println("maxvalue :"+ this.maxvalue);System.out.println("the object when maxvalue:"+this.result_objects);}public void findmaxvalue(){PriorityQueue<Node> enode=new PriorityQueue<>();Node node=new Node(0,null,bagv,this.objects);enode.offer(node);while(true){if(enode.isEmpty())break;node=enode.poll();if(node.isend()){this.maxvalue=node.get_bag_value();this.result_objects=newArrayList<>(node.get_in_bag_object());return;}int i=node.get_node_in();object iobject=this.objects.get(i);if(node.get_bag_weight()+iobject.getweight()<=this.bagv){ ArrayList<object> newnodeinbag=new ArrayList<object>(node.get_in_bag_object());newnodeinbag.add(iobject);int newnodebagv=node.get_bag_leftv()-iobject.getweight();Node newnode=new Node(i+1,newnodeinbag,newnodebagv,this.objects);enode.add(newnode);if(newnode.get_bag_value()>this.maxvalue){this.maxvalue=newnode.get_bag_value();this.result_objects=newArrayList<>(newnode.get_in_bag_object());}}Node newnode=new Node(i+1,node.get_in_bag_object(),node.get_bag_leftv(),this.objects);if(newnode.get_bag_prio()>this.maxvalue)enode.add(newnode);}}}----------------------------------------------------------------------- package bag01b;import java.util.ArrayList;public class Node implements Comparable<Node>{private int node_in;private ArrayList<object> inbag_object;private ArrayList<object> outbag_object;private int leftv;private int prio;public Node(int i,ArrayList<object> in,int l,ArrayList<object> out){ super();this.node_in=i;if(in==null)in=new ArrayList<>();this.inbag_object=in;this.leftv=l;this.outbag_object=out;this.prio=this.find_prio();}private int find_prio() {// TODO Auto-generated method stubint bag_left=this.leftv;int p=this.get_bag_value();int i=this.node_in;object iobject=null;while(true){if(i>=this.inbag_object.size())break;iobject=this.inbag_object.get(i);if(iobject.getweight()>bag_left)break;bag_left-=iobject.getweight();p+=iobject.getvalue();i++;}if(i<=this.inbag_object.size()-1)p+=iobject.getvw()*bag_left;return p;}public int get_bag_weight(){int w=0;for(object o:this.inbag_object){w+=o.getweight();}return w;}public int get_bag_value(){int w=0;for(object o:this.inbag_object){w+=o.getvalue();}return w;}@Overridepublic int compareTo(Node o) {// TODO Auto-generated method stubif(this.prio>o.prio) return -1;if(this.prio<o.prio) return 1;return 0;}public boolean isend(){if(this.node_in==this.outbag_object.size())return true;elsereturn false;}public ArrayList<object> get_in_bag_object(){return this.inbag_object;}public int get_node_in(){return this.node_in;}public int get_bag_leftv(){return this.leftv;}public int get_bag_prio(){return this.prio;}public String toString(){return"node in"+this.node_in+"node prio"+this.prio;}}-----------------------------------------------------------------------package bag01b;public class object implements Comparable<object>{private static int ids=1;private int id;private int weihgt;private int value;public object(int w,int v){super();this.weihgt=w;this.value=v;this.id=ids++;}public int getid(){return this.id;}public int getweight(){return this.weihgt;}public int getvalue(){return this.value;}public float getvw(){return (float)this.value/this.weihgt;} @Overridepublic int compareTo(object o) {// TODO Auto-generated method stubif(this.getvw()>o.getvw()) return -1;if(this.getvw()<o.getvw()) return 1;return 0;}public String toString(){return"object "+this.id+" ";}}。

相关文档
最新文档