用贪心法求解0-1背包问题
贪心算法-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 2 3 4 5 6 7 8 9 10
000000000000
x1=1
w1=2 v1=6 1 0 0 6 6 6 6 6 6 6 6 6
x2=1
w2=2 v2=3 2 0 0 6 6 9 9 9 9 9 9 9
x3=0
w3=6 v3=5 3 0 0 6 6 9 9 9 9 11 11 14
可用动态规划算法求解。
3
其他类型背包问题
完全背包问题(0/1):
有N种物品和一个容量为V的背包,每种物品都有 无限件可用。第i种物品的费用是c[i],价值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和 不超过背包容量,且价值总和最大。
多重背包问题
有N种物品和一个容量为V的背包。第i种物品最多 有n[i]件可用,每件费用是c[i],价值是w[i]。求解 将哪些物品装入背包可使这些物品的费用总和不超 过背包容量,且价值总和最大。
{// 计算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;
}
11
算法改进
由m(i,j)的递归式容易证明,在一般情况下,对每一个确定的 i(1≤i≤n),函数m(i,j)是关于变量j的阶梯状单调不减函数。跳跃 点是这一类函数的描述特征。在一般情况下,函数m(i,j)由其 全部跳跃点唯一确定。如图所示。
(7,7)
(6,6) (4,5)
(4,5)(6,6)
(0,
0)
(2,
(3,2) 1)
求解多维0-1背包问题的一种改进的遗传算法
计算机科学 2 0 Vo. 3 o 7 0 6 1 N. 3
求解 多 维 0 1 包 问题 的一 种 改进 的遗 传 算 法 ) —背
曾 智 杨小 帆 陈 静 陈 文斌 唐 荣旺 ( 重庆 大 学计算 机 学院 重庆 4 0 4 ) 0 0 4
d a ft eg e y ag rt m n h 一d v so e r h a g rt , n i tt e mu t i n i n l - n p a k p o — e so h r e lo i d h a d t e 2 i iin s a c lo i m h a d ams a h l d me so a 1 k a s c r b i 0
lm e .
B s n t i d in c s v ro e ao ,h a e lo p e e t n i r v d g n t lo i o li h a e o hs me a r s e p r tr t ep p ras rs ns a mp o e e ei ag rt d o o c m h fr s vn t e o g
证 了其 有 效 性 。 关 键 词 多 维 O1背 包 问题 , 传 算 法 , 一 遗 中值 杂 交 算 子
An I r v d Ge e i g rt m o h u t i n i n l0 1Kn p a k Pr b e mp o e n t Al o ih f r t e M l d me s o a — a s c o lm c i
mu tdm e so a - n p a k p b e li i n i n l0 1 k a s c r lm. Fu t e mo e t e e fce c ft e p e e t d me h d i i v s i a e y c mp — o rh r r , h f iin y o h r s n e t o n e t t b o a s g d
0_1背包问题的多种解法
一、 问题描述0/1背包问题:现有n 种物品,对1<=i<=n ,已知第i 种物品的重量为正整数W i ,价值为正整数V i ,背包能承受的最大载重量为正整数W ,现要求找出这n 种物品的一个子集,使得子集中物品的总重量不超过W 且总价值尽量大。
(注意:这里对每种物品或者全取或者一点都不取,不允许只取一部分)二、 算法分析根据问题描述,可以将其转化为如下的约束条件和目标函数:)2(max )1()1}(1,0{11∑∑==⎪⎩⎪⎨⎧≤≤∈≤ni i i ini i i x v n i x Wx w 于是,问题就归结为寻找一个满足约束条件(1),并使目标函数式(2)达到最大的解向量),......,,,(321n x x x x X =。
首先说明一下0-1背包问题拥有最优解。
假设),......,,,(321n x x x x 是所给的问题的一个最优解,则),......,,(32n x x x 是下面问题的一个最优解:∑∑==⎪⎩⎪⎨⎧≤≤∈-≤ni i i ini i i x v n i x x w W x w 2211max )2}(1,0{。
如果不是的话,设),......,,(32n y y y 是这个问题的一个最优解,则∑∑==>n i ni ii ii xv y v 22,且∑=≤+ni iiW yw x w 211。
因此,∑∑∑====+>+ni i i n i n i i i i i x v x v x v y v x v 1221111,这说明),........,,,(321n y y y x 是所给的0-1背包问题比),........,,,(321n x x x x 更优的解,从而与假设矛盾。
穷举法:用穷举法解决0-1背包问题,需要考虑给定n 个物品集合的所有子集,找出所有可能的子集(总重量不超过背包重量的子集),计算每个子集的总重量,然后在他们中找到价值最大的子集。
浅谈0-1背包问题的常用算法
2 0 1 3年 1 0月下 C o n s u me r E l e c t r o n i c s Ma g a z i n e 技 术 交 流
浅谈 0 - 1 背包问题的常用算法
汤赫 男
( 吉林工商学院信息工程学院,长春 1 3 0 0 6 2) 摘 要 :0 -1 背 包问题是典型的 NP ~完全问题 ,无论从 理论 上还是 实践上都有一定的研究意义。本文综述 了几 种0 — 1背包问题的 常用算法 ,分析算法的优劣 ,预 测 0 - 1背包问题的发展方向。 关键 词 :0 — 1背包问题 ;动 态规划法 ;贪心法 ;分支界限法
一
、
∑w ,
l {
㈠ { “ } m a x ∑
{ j
二 、常用 的 0 - 1 背 包问题算法 ( 一) 蛮力法。 蛮 力法又称穷举法或枚举法,是一种简单、 直接、有效的方法,是初学者入 门的方法 。蛮力法要求遍历所 有可能情 况一次且仅一次 ,筛选 出符合要求 的解。应用蛮力法 求解 0 - 1 背包 问题, 需要考虑给定的 n 个物品集合的所有子集, 找出所有总重量不超过背包容量的子集 ,计算每个可能子集的 总价值,然后找 出价值最大的子集 。对于一个具有 n个元素的 集合 ,其子集数量是 2 “,所 以,不论生成子集 的算法效率有 多高 ,蛮力法求解 0 - 1 背包 问题都会导致一个 Q ( 2 n )的算法 。 ( 二 )动 态规划法。动态规划 法是一种通用 的算 法设计 技术用来求解 多阶段决策最优 化问题。这类 问题都满 足最优 性原理,即原 问题 的最优 性包含着子 问题 的最优性 。 应用 动态规划法 求解 0 - 1 背包 问题 ,可 以将 0 — 1背包 问 题看 作一个 多阶段决策最 优化 问题 。n个物 品集合 的所 有子 集可 以看 作该 问题 的所有 可行解;这些可行解 都是满足约束 条件 的,可行解可能不止一个,通过 目标 函数找到最优解 。 动态 规划 法求解 0 - 1 背包 问题 的算法描述 : 设V ( n , C )表 示将 n个 物 品装入 容量 为 C的背 包获 得 的 最大价值 。 初 始 状 态 :V ( i , 0 ) = V ( 0 , j ) = 0 , 0≤ i ≤n , 0≤ j≤ C 则V ( i , j )表示 将前 i 个 物 品装入 容量 为 j的背 包获 得
贪心算法背包问题
题目:贪心算法
背包问题
专业:JAVA 技术 09——02 班 学号:540913100201 姓名:柏顺顺 指导老师:宋胜利
实验三:贪心算法
一、实验目的与要求
1、掌握背包问题的算法 2、初步掌握贪心算法
背包问题
二、实验题:
问题描述:与 0-1 背包问题相似,给定 n 种物品和一个背包。物品 i 的重量是 wi,其价 值为 vi,背包的容量为 c。与 0-1 背包问题不同的是,在选择物品 i 装入背包时,背包问题 的解决可以选择物品 i 的一部分,而不一定要全部装入背包,1< i < n。
JOptionPane.showMessageDialog(null, "重量不能为空!"); return; } else{ if (s1.equals("")){ JOptionPane.showMessageDialog(null, "效益值不能为空!"); return; }else { if (s3.equals("")) JOptionPane.showMessageDialog(null, "总重量不能为空!"); return; } } } catch (Exception e3) { // TODO: handle exception }
}
//可以执行贪心算法了 int [] wCopy = new int [w.length]; int [] pCopy = new int [w.length]; float temp2; int temp1; float totalx=0; float [] x = new float [w.length];//效益和重量的比值 float [] n =new float[w.length];//记录个数 float [] nCopy = new float[w.length]; for(int i=0;i<w.length;i++) { wCopy [i] = w[i]; pCopy [i] = p[i]; } for (int i=0;i<w.length;i++) x[i] = (float) ((p[i]*1.0)/w[i]); for(int i= 0;i<w.length;i++) for(int j=i+1;j<w.length;j++)
背包问题的贪心算法20页PPT文档
则用j比i好,∵装入A, V i 2 ;而装入B,Vi=3
对例。4.3的数据使用按效益值的非增次序的选择策略.
V 125,X 11 ,W 118 背包剩:C-18=2;物品2有次大效益值
(V2=24 )但w2=15,背包装不下物品2。使用 x2=2/15,刚好装满背
包
6
,且物品2的24/15 = v2/w2 较物品3的15/10= v3/w3效益值高。按 此选择策略,得②即(1, 2/15, 0),∑vixi=28.2 .此解是一个次优解。 显然,按物品效益值的非增次序装包不能得最优解。
背包问题:
与0-1背包问题类似,所不同的是在选择物品i装入背包时 ,可以选择物品i的一部分,而不一定要全部装入背包, 1≤i≤n。
这2类问题都具有最优子结构性质,极为相似,但背 包问题可以用贪心算法求解,而0-1背包问题却不能用 贪心算法求解。
2
例4.3 贪心算法不能求得0-1背包问题得最优解。
考虑背包问题: n=3,c=50kg,(v1,v2,v3)=(60,100,120), (w1,w2,w3)=(10,20,30). vi/wi=(6,5,4).贪心算法解是(1,1,0), ∑vixi=60+100 , ∑wixi=30;最优解是(0,1,1), ∑vixi=100+120, ∑wixi=50,
实际上,动态规划算法的确可以有效地解0-1背包问题。
3
4.2 背包问题
已知有n种物品和一个可容纳c重量的背包,每种物品i的
重量为wi。假定物品i的一部分放入背包会得到vixi的效益。其
中0≤xi≤1,vi>0 . 采用怎样的装包方法才会使装入背包物品的总
效益最大呢?即求解 n
0_1背包问题及贪心算法应用
fr = ; n h + ) o( 1 < — + j j ic 】 c + ] f D< b 1) ( ( t= D;D= 1; + ]t; 1a ] ]a + 】 U 1=1 a a
t= 吣 b 】b + ] D 1 t;,物 品 按 单 位 价 值 排 序 2 b D= D 1I + ] 2 / b =
fr = ; = ; + o ( l < ni ) i i + i> v n > 嘲;
c u << n ; o t e dl
cu< ” ot< 请依次输入物 品的重量 :< ed; ” <n l
fr= ; = ; + o( l< ni ) i i + cn > i i> w[; ]
c=i i 1 lm t w;
fr= ; = ; + o( l < ni ) i i +
空间 , 价值为 v i 。中奖顾客该如何选 择奖 品, 使得 车中奖品的总价值最 大且不超过车的容量 , 这是本文需要解 决 的问题 。首先 介绍背包问题 , 然后提出贪心算法[ 最后使用这种算法解决 奖品选择 问题 。 3 1 ,
科技信息
计 算机 与 网络
0
—
1背 包 问 题 及 贪 心 算 法 应 用
兰州交 通 大学数 理 与软件 工程 学 院 同 甲佳
[ 摘
要 ] 文 结 合 生 活 中顾 客 中 奖 后 奖 品 的 选 择 问题 , 出背 包 问题 的 数 学 模 型 , 绍 基 于 O 1背 包 问题 的 贪 心 算 法 , 用 这 种 算 本 给 介 使
2背 包 问题 . 0 背包问题l1 j 】5 i] 4是指给定 n件物 品和一个背包 , 物品的重量为 w, i 其价值为 v背包 的容量 为 c i , , 这 n件物品 中选取一部 分物品且对每 求从 件物品 , 么选 , 么不选 , 要 要 要求 满足被 放入背包 的物品不超过 背包 的 容量。 所有 物品的重量之和小于背包的容量 。 如果所有物品的重量之和 小于背包的容量 , 显然此时的利益 为所 有物品 的价值之 和 , 但在实际 问 题一般是背包的容量小于物品 的重 量和 ,这就要求选取适 当的背包放 人使得利益最大化且物品的总重量不超过背包容量 。 3解决 背包 问题 的贪 心算 法 . 31通 常 的 贪 心 准 则 . 贪心算法并 不是从 整体上加 以考 虑 ,它所作 出的选择 是从 某种意 义上的局部最优解 ,而许多问题 自身的特性决定 了该 问题运用贪心算 法可以得到最优解或较优解。通常有三种贪心准则 : () 1 从剩下的物品中选择可装入 背包的重量最小 的物品 , 重复此过 程直至不满足条件为止。 ( ) 剩下的物品中选择可装入 背包的价格最大 的物品 , 复此过 2从 重 程直至不满足条件为至。 () 3 从剩下的物品中选择可装人背包 的单位价格最大 的物 品。 本文采取此种贪心策略。 32算 法 描 述 . () 1 输人 物品个数 n背包 的容量 l t, , i i v每个物 品 的重 量 w 和价 mn i 值 v。 i
贪心算法之背包问题
贪⼼算法之背包问题贪⼼算法之背包问题1.与动态规划的区别通过研究解决经典的组合优化问题,来说明⼆者的差别。
即0-1背包问题与背包问题0-1背包问题:给定n中物品和⼀个背包。
物品i的重量为W i,其价值为V i,背包的容量为C。
应如何选择装⼊背包的物品,使得装⼊背包中物品的总价值最⼤?对于每种物品i只有俩种选择,即装⼊背包或不装⼊背包背包问题:与0-1背包问题类似,不同在于选择物品i装⼊背包时,可以选择物品i的⼀部分,⽽不⼀定要全部装⼊背包,1≤i≤n。
这2类问题都具有最优⼦结构性质,极为相似。
背包问题可以⽤贪⼼算法求最优解,0-1背包不能使⽤贪⼼求解。
2.贪⼼解决背包问题步骤贪⼼策略:每次选择单位重量价值最⾼的物品装⼊背包计算每种物品单位重量的价值V iW i,按单位重量的价值从⼤到⼩将n中物品排序。
以排序后的次序依次将物品装⼊背包。
直⾄全部物品都装⼊或者因背包容量不⾜不能装⼊为⽌如果背包尚有容量,将最后不能完全装⼊物品切割⼀部分装满背包算法结束3.代码实现/*** n 物品数* M 背包容量* v[] 物品价值数组* w[] 物品重量数组* x[] 保存最优解路径数组,为1则表⽰该物品完全装⼊,否则装⼊该物品的⼀部分**/void Knapsack(int n, float M, float v[], float w[], float x[]) {// 按照物品单位重量的价值递减排序Sort(n, v, w);int i;for (i = 1; i <= n; i++)x[i] = 0;float c = M;for (i = 1; i <= n; i++) {if (w[i] > c)break;x[i] = 1;c -= w[i];}if (i <= n)x[i] = c / w[i];}Processing math: 100%。
0-1背包问题-贪心法和动态规划法求解
实验四“0-1”背包问题一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对贪心算法、动态规划算法的理解。
二、实验内容:掌握贪心算法、动态规划算法的概念和基本思想,分析并掌握“0-1”背包问题的求解方法,并分析其优缺点。
三、实验题1.“0-1”背包问题的贪心算法2.“0-1”背包问题的动态规划算法说明:背包实例采用教材P132习题六的6-1中的描述。
要求每种的算法都给出最大收益和最优解。
设有背包问题实例n=7,M=15,,(w0,w1,。
w6)=(2,3,5,7,1,4,1),物品装入背包的收益为:(p0,p1,。
,p6)=(10,5,15,7,6,18,3)。
求这一实例的最优解和最大收益。
四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。
五、实验程序// 贪心法求解#include<iostream>#include"iomanip"using namespace std;//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ); //获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u);int main(){float w[7]={2,3,5,7,1,4,1}; //物品重量数组float p[7]={10,5,15,7,6,18,3}; //物品收益数组float avgp[7]={0}; //单位毒品的收益数组float x[7]={0}; //最后装载物品的最优解数组const float M=15; //背包所能的载重float ben=0; //最后的收益AvgBenefitsSort(avgp,p,w);ben=GetBestBenifit(p,w,x,M);cout<<endl<<ben<<endl; //输出最后的收益system("pause");return 0;}//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ) {//求出物品的单位收益for(int i=0;i<7;i++){arry_avgp[i]=arry_p[i]/arry_w[i];}cout<<endl;//把求出的单位收益排序,冒泡排序法int exchange=7;int bound=0;float temp=0;while(exchange){bound=exchange;exchange=0;for(int i=0;i<bound;i++){if(arry_avgp[i]<arry_avgp[i+1]){//交换单位收益数组temp=arry_avgp[i];arry_avgp[i]=arry_avgp[i+1];arry_avgp[i+1]=temp;//交换收益数组temp=arry_p[i];arry_p[i]=arry_p[i+1];arry_p[i+1]=temp;//交换重量数组temp=arry_w[i];arry_w[i]=arry_w[i+1];arry_w[i+1]=temp;exchange=i;}}}}//获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u) {int i=0; //循环变量ifloat benifit=0; //最后收益while(i<7){if(u-arry_w[i]>0){arry_x[i]=arry_w[i]; //把当前物品重量缴入最优解数组benifit+=arry_p[i]; //收益增加当前物品收益u-=arry_w[i]; //背包还能载重量减去当前物品重量cout<<arry_x[i]<<" "; //输出最优解}i++;}return benifit; //返回最后收益}//动态规划法求解#include<stdio.h>#include<math.h>#define n 6void DKNAP(int p[],int w[],int M,const int m); void main(){int p[n+1],w[n+1];int M,i,j;int m=1;for(i=1;i<=n;i++){m=m*2;printf("\nin put the weight and the p:");scanf("%d %d",&w[i],&p[i]);}printf("%d",m);printf("\n in put the max weight M:");scanf("%d",&M);DKNAP(p,w,M,m);}void DKNAP(int p[],int w[],int M,const int m) {int p2[m],w2[m],pp,ww,px;int F[n+1],pk,q,k,l,h,u,i,j,next,max,s[n+1];F[0]=1;p2[1]=w2[1]=0;l=h=1;F[1]=next=2;for(i=1;i<n;i++){k=l;max=0;u=l;for(q=l;q<=h;q++)if((w2[q]+w[i]<=M)&&max<=w2[q]+w[i]){u=q;max=w2[q]+w[i];}for(j=l;j<=u;j++){pp=p2[j]+p[i];ww=w2[j]+w[i];while(k<=h&&w2[k]<ww){p2[next]=p2[k];w2[next]=w2[k];next++;k++;}if(k<=h&&w2[k]==ww){if(pp<=p2[k])pp=p2[k];k++;}else if(pp>p2[next-1]){p2[next]=pp;w2[next]=ww;next++;}while(k<=h&&p2[k]<=p2[next-1])k++;}while(k<=h){p2[next]=p2[k];w2[next]=w2[k];next=next+1;k++;}l=h+1;h=next-1;F[i+1]=next;}for(i=1;i<next;i++)printf("%2d%2d ",p2[i],w2[i]);for(i=n;i>0;i--){next=F[i];next--;pp=pk=p2[next];ww=w2[next];while(ww+w[i]>M&&next>F[i-1]){next=next-1;pp=p2[next];ww=w2[next];}if(ww+w[i]<=M&&next>F[i-1])px=pp+p[i];if(px>pk&&ww+w[i]<=M){s[i]=1;M=M-w[i];printf("M=%d ",M);}else s[i]=0;}for(i=1;i<=n;i++)printf("%2d ",s[i]);}六、实验结果1、贪心法截图:七、实验分析。
用贪心法求解0-1背包问题
算法设计与分析期末论文题目用贪心法求解“0-1背包问题”专业计算机科学与技术班级09计算机一班学号0936021姓名黄帅日期2011年12月28日一、0-1背包问题的算法设计策略分析1.引言对于计算机科学来说,算法的概念是至关重要的,例如,在一个大型软件系统的开发中,设计出有效的算法将起决定性的作用。
算法是解决问题的一种方法或一个过程。
程序是算法用某种设计语言具体实现描。
计算机的普及极大的改变了人们的生活。
目前,各行业、各领域都广泛采用了计算机信息技术,并由此产生出开发各种应用软件的需求。
为了以最小的成本、最快的速度、最好的质量开发出适合各种应用需求的软件,必须遵循软件工程的原则。
设计一个高效的程序不仅需要编程小技巧,更需要合理的数据组织和清晰高效的素算法,这正是计算机科学领域数据结构与算法设计所研究的主要内容。
2. 算法复杂性分析的方法介绍算法复杂性是算法运行所需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要的空间资源的量称为空间复杂性。
这个量应该只依赖于算法要解的问题的规模、算法的输入和算法本身的函数。
如果分别用N 、I 和A 表示算法要解问题的规模、算法的输入和算法本身,而且用C 表示复杂性,那么,应该有C=F(N,I,A)。
一般把时间复杂性和空间复杂性分开,并分别用T 和S 来表示,则有: T=T(N,I)和S=S(N,I) 。
(通常,让A 隐含在复杂性函数名当中最坏情况下的时间复杂性:最好情况下的时间复杂性:平均情况下的时间复杂性:其中DN 是规模为N 的合法输入的集合;I*是DN 中使T(N, I*)达到Tmax(N)的合法输入; 是中使T(N, )达到Tmin(N)的合法输入;而P(I)是在算法的应用中出现输入I 的概率。
算法复杂性在渐近意义下的阶:渐近意义下的记号:O 、Ω、θ、o 设f(N)和g(N)是定义在正数集上的正函数。
O 的定义:如果存在正的常数C 和自然数N0,使得当N ≥N0时有f(N)≤Cg(N),则称函数f(N)当N 充分大时上有界,且g(N)是它的一个上界,记为f(N)=O(g(N))。
背包问题
(0-1)背包问题的解法小结1.动态规划法递推关系:– 考虑一个由前i 个物品(1≤i ≤n )定义的实例,物品的重量分别为w 1,…,w i ,价值分别为v 1,…,v i ,背包的承重量为j (1≤j ≤W )。
设V [I,j]为该实例的最优解的物品总价值– 分成两类子集:• 根据定义,在不包括第i 个物品的子集中,最优子集的价值是V [i -1,j ]• 在包括第i 个物品的子集中(因此,j -w ≥0),最优子集是由该物品和前i -1个物品中能够放进承重量为i -w j 的背包的最优子集组成。
这种最忧子集的总价值等于v i +V [i -1,j -w i ].0]0,[时,0 当0;][0,时,0初始条件:当],1[}],1[],,1[max{],[=≥=≥<≥⎩⎨⎧-+---=i V i j V j w j w j j i V v w j i V j i V j i V i i i i以记忆功能为基础的算法:用自顶向下的方式对给定的问题求解,另外维护一个类似自底向上动态规划算法使用的表格。
一开始的时候,用一种“null”符号创始化表中所有的单元,用来表明它们还没有被计算过。
然后,一旦需要计算一个新的值,该方法先检查表中相应的单元:如果该单元不是“null ”,它就简单地从表中取值;否则,就使用递归调用进行计算,然后把返回的结果记录在表中。
算法 MFKnapsack(I,j)//对背包问题实现记忆功能方法//输入:一个非负整数i 指出先考虑的物品数量,一个非负整数j 指出了背包的承重量 //输出:前i 个物品的最伏可行子集的价值//注意:我们把输入数组Weights[1..n],Values[1..n]和表格V[0..n,0..W]作为全局变量,除了行0和列0用0初始化以外,V 的所有单元都用-1做初始化。
if V[I,j]<01if j<Weights[i]value ←MFKnapsack(i-1,j)elsevalue ←max(MFKnapsack(i-1),j), Value[i]+MFKnapsack(i-1,j-eights[i]))V[I,j]←valuereturn V[I,j]2.贪心算法1) 背包问题基本步骤:首先计算每种物品单位重量的价值Vi/Wi ,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
背包问题的贪心算法
Wi Xi
16.5 20 20 20
Vi X i
24.25 28.2 31 31.5
先检验这四个为可行解*,即满足约束条件(4.2.2),(4.2.3).再比 较目标函数值,∑vixi .知④组解效益值最大.该组解是背包问题的最 优解。(见定理4.2)
6
例4.4 n=3,c=20, (V1,V2,V3) (25, 24,15) (W1,W2,W3) (18,15,10)
7
,且物品2的24/15 = v2/w2 较物品3的15/10= v3/w3效益值高。按 此选择策略,得②即(1, 2/15, 0),∑vixi=28.2 .此解是一个次优解。 显然,按物品效益值的非增次序装包不能得最优解。
原因:背包可用容量消耗过快。
(2)以容量作为量度。即按物品重量的非降次序将物
—选取最优的量度标准实为用贪心方法求解问题的核心.
16
4.3 贪心算法的基本要素
1.贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来达到。这 是贪心算法可行的第一个基本要素,也是贪心算法与 动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问 题,而贪心算法则通常以自顶向下的方式进行,以迭 代的方式作出相继的贪心选择,每作一次贪心选择就 将所求问题简化为规模更小的子问题。
品装包。如例4.4中的解③(让背包尽可能慢被消耗)
排序 : (w3,w2,w1)= (10,15,18)
(V3,V2,V1) (15, 24, 25)
V3=15,x3=1,w3=10,背包剩余C-10=10;物品2有次大重量(w2=15), 但包装不下。使用x2=2/3,刚好装满背包且物品2装入2/3与物品1 装入5/9的容量均为10个单位。但前者的效益值24×2/3=16 >后者
贪心算法与背包问题的求解策略
贪心算法与背包问题的求解策略贪心算法是一种常用的优化算法,特别适用于一些具有最优子结构性质的问题。
而背包问题是一个经典的组合优化问题,它涉及到在限定容量下如何选择物品,使得总价值最大化。
本文将探讨贪心算法在背包问题求解中的应用策略。
一、背包问题的定义与分类背包问题是在给定容量的背包和一组物品的情况下,如何选择物品放入背包中,使得物品的总价值最大化。
背包问题可以分为0-1背包问题、分数背包问题和多重背包问题三种。
1. 0-1背包问题:每种物品只能选择放入背包一次或者不放入。
目标是使得背包中物品价值最大化。
2. 分数背包问题:物品可以分割成较小的部分放入背包,即可以选择部分物品放入。
目标是使得背包中物品价值最大化。
3. 多重背包问题:物品有多个可选的数量限制,每种物品可以选择放入多次但不能超过其数量限制。
目标是使得背包中物品价值最大化。
二、贪心算法在背包问题求解中的应用策略在求解背包问题时,贪心算法通常采取以下两种策略:1. 价值密度优先策略:对于0-1背包问题和分数背包问题,贪心算法可以根据物品的单位价值(价值与重量的比率)进行排序,然后按照价值密度从大到小的顺序选择物品放入背包。
这样可以保证每次选择的物品是当前局部最优解,进而得到全局最优解。
算法步骤如下:a) 计算每种物品的单位价值。
b) 对物品按照单位价值进行排序。
c) 从价值最大的物品开始,依次尝试放入背包直至放满或无法继续放入。
2. 数量优先策略:对于多重背包问题,贪心算法可以根据物品的剩余数量进行排序,优先选择剩余数量最多的物品。
这样可以尽可能多地选择该物品,以使总价值最大化。
算法步骤如下:a) 对物品按照剩余数量进行排序。
b) 从剩余数量最多的物品开始,依次尝试放入背包直至放满或无法继续放入。
值得注意的是,贪心算法在某些情况下可能无法得到最优解。
对于一些特殊的背包问题,如存在约束条件或物品具有特殊属性时,贪心算法可能会得出次优解或错误解。
部分背包问题的贪心算法正确性证明
部分背包问题的贪⼼算法正确性证明⼀,部分背包问题介绍⾸先介绍下0-1背包问题。
假设⼀共有N件物品,第 i 件物品的价值为 V i,重量为W i,⼀个⼩偷有⼀个最多只能装下重量为W的背包,他希望带⾛的物品越有价值越好,请问:他应该选择哪些物品?0-1背包问题的特点是:对于某件(更适合的说法是:某类)物品,要么被带⾛(选择了它),要么不被带⾛(没有选择它),不存在只带⾛⼀部分的情况。
⽽部分背包问题则是:可以带⾛⼀部分。
即,部分背包问题可带⾛的物品是可以⽆限细分的。
(连续与离散的区别)可以把0-1背包问题中的物品想象的⼀个⾦⼦,你要么把它带⾛,要么不带⾛它;⽽部分背包问题中的物品则是⼀堆⾦粉末,可以取任意部分的⾦粉末⼆,部分背包问题的贪⼼算法部分背包问题可以⽤贪⼼算法求解,且能够得到最优解。
贪⼼策略是什么呢?将物品按单位重量所具有的价值排序。
总是优先选择单位重量下价值最⼤的物品。
单位重量所具有的价值:V i / W i举个例⼦:假设背包可容纳50Kg的重量,物品信息如下:物品 i 重量(Kg) 价值单位重量的价值1 10 60 62 20 100 53 30 120 4按照我们的贪⼼策略,单位重量的价值排序:物品1 > 物品2 > 物品3因此,我们尽可能地多拿物品1,直到将物品1拿完之后,才去拿物品2.....最终贪⼼选择的结果是这样的:物品1全部拿完,物品2也全部拿完,物品3拿⾛10Kg(只拿⾛了物品3的⼀部分)这种选择获得的价值是最⼤的。
在(三)会给出证明。
⽽对于0-1背包问题,如果也按“优先选择单位重量下价值最⼤的物品”这个贪⼼策略,那么,在拿了物品1和物品2之后,就不能在拿物品3了。
因为,在拿了物品1和物品2之后,背包中已经装了10+20=30Kg的物品了,已经装不下物品3了(50-30 < 30)(0-1背包:⼀件物品要么拿,要么不拿,否能只拿⼀部分),此时得到的总价值是 160。
0-1背包问题求解方法综述
0-1背包问题求解方法综述算法分析与设计大作业实验题目:0-1背包问题求解方法综述组员:班级:指导老师:0-1背包问题求解方法综述【摘要】:0-1背包问题是一个经典的NP-hard组合优化问题,现实生活中的很多问题都可以以它为模型。
本文首先对背包问题做了阐述,然后用蛮力解法、动态规划算法、贪心算法和回溯解法对背包问题进行求解,分析了0-1背包问题的数学模型,刻划了最优解的结构特征,建立了求最优值的递归关系式。
最后对四种算法从不同角度进行了对比和总结。
【关键词】:0-1背包问题;蛮力解法;动态规划算法;贪心算法;回溯解法。
0.引言0-1背包问题是指给定n个物品,每个物品均有自己的价值vi和重量wi(i=1,2,…,n),再给定一个背包,其容量为W。
要求从n个物品中选出一部分物品装入背包,这部分物品的重量之和不超过背包的容量,且价值之和最大。
单个物品要么装入,要么不装入。
很多问题都可以抽象成该问题模型,如配载问题、物资调运[1]问题等,因此研究该问题具有较高的实际应用价值。
目前,解决0-1背包问题的方法有很多,主要有动态规划法、回溯法、分支限界法、遗传算法、粒子群算法、人工鱼群算法、蚁群算法、模拟退火算法、蜂群算法、禁忌搜索算法等。
其中动态规划、回溯法、分支限界法时间复杂性比较高,计算智能算法可能出现局部收敛,不一定能找出问题的最优解。
文中在动态规划法的基础上进行了改进,提出一种求解0-1背包问题的算法,该算法每一次执行总能得到问题的最优解,是确定性算法,算法的时间复杂性最坏可能为O(2n)。
1.0-1背包问题描述0-1背包问题(KP01)是一个著名的组合优化问题。
它应用在许多实际领域,如项目选择、资源分布、投资决策等。
背包问题得名于如何选择最合适的物品放置于给定背包中。
本文主要研究背包问题中最基础的0/1背包问题的一些解决方法。
为解决背包问题,大量学者在过去的几十年中提出了很多解决方法。
解决背包问题的算法有最优算法和启发式算法[2],最优算法包括穷举法、动态规划法、分支定界法、图论法等,启发式算法包括贪心算法、遗传算法、蚁群算法、粒子算法等一些智能算法。
运筹学背包问题例题
运筹学背包问题例题
运筹学中的背包问题是一个经典的组合优化问题,通常分为0-1背包问题和分数背包问题。
这个问题可以用来描述一个背包有限的容量,以及一系列物品,每个物品都有自己的重量和价值。
问题的目标是找到一个组合,使得放入背包的物品总重量不超过背包容量,同时使得这些物品的总价值最大化。
举一个例子来说明背包问题:假设有一个背包容量为10kg,现有以下物品:
物品A,重量3kg,价值150元。
物品B,重量4kg,价值300元。
物品C,重量5kg,价值200元。
针对这个例子,我们可以用动态规划或者贪心算法来解决背包问题。
在0-1背包问题中,每个物品只能选择放或者不放,不能进行分割。
而在分数背包问题中,物品可以进行分割放入背包。
解决背包问题的关键是建立递推关系和状态转移方程,以确定
如何选择物品放入背包以达到最优解。
动态规划是解决背包问题的
常用方法,通过填写一个二维的状态转移表格来逐步求解最优解。
贪心算法则是通过每一步选择当前最优的策略,不断迭代直至达到
最优解。
除了动态规划和贪心算法,还有其他方法可以解决背包问题,
比如分支限界法、回溯法等。
每种方法都有其适用的场景和局限性。
总的来说,背包问题是运筹学中的一个经典问题,有着广泛的
应用。
通过合适的算法和方法,我们可以有效地解决背包问题,找
到最优的放置方案,这对于资源分配、生产调度等实际问题有着重
要的意义。
基于朴素贪心算法的背包问题解决方案
基于朴素贪心算法的背包问题解决方案背包问题是一类经典的组合优化问题,它的一般形式描述为:有一个固定大小的背包,和一些物品,每个物品都有自己的价值和大小,需要选出一些物品装入背包中,使得装进去的物品价值最大化,同时又不能超出背包容量的限制。
这个问题在实际生活中有很多应用,比如在货物的装载和运输、在零售商的库存管理、在网页推荐系统等等。
解决背包问题的方法有很多,其中比较经典的是基于动态规划的解法,但是这种解法需要使用大量的存储空间,如果物品数量很大的话,计算复杂度也会很高。
因此本文将介绍一种基于朴素贪心算法的背包问题解决方案。
一、背包问题的数学模型在介绍具体的解决方案之前,我们需要先来看一下背包问题的数学模型。
假设我们有n个物品,第i个物品的重量为wi,价值为vi,背包的容量为W。
那么背包问题可以用下面的数学模型来描述:$$\begin{aligned}&\max\sum_{i=1}^{n}v_ix_i\\&s.t.\sum_{i=1}^ {n}w_ix_i\leq W\\&x_i\in \{0,1\}\end{aligned}$$其中,$x_i$表示第$i$个物品是否被选中,$v_i$和$w_i$分别表示第$i$个物品的价值和重量。
第一个约束条件表示所有选中的物品的总重量不能超过背包的容量$W$,第二个约束条件表示每个物品最多只能选一次。
二、基于朴素贪心算法的解法朴素贪心算法的思路很简单:每次选择可行的物品中价值最大的那一个,直到不能再选为止。
对于背包问题来说,我们可以按照物品的单位价值(即价值与重量比值)从大到小排序,然后依次选择可行的物品加入背包中。
具体步骤如下:1. 计算每个物品的单位价值,按照单位价值从大到小排序。
2. 依次加入可行的物品,直到不能再加入为止。
3. 最后得到的物品组合就是背包问题的最优解。
该算法的时间复杂度为$O(nlogn)$,其中$n$为物品的数量。
解决0-1背包问题的启发式算法
0 引言
0 — 1 背包 问题 ( 0 — 1 k n a p s a c k p r o b l e m ) 是一个经典 的 N P 一 完 全问
2 . 2 . 1 问 题 的 上 界
定理 1 : 用 贪心算法求解 , 如果 W i ≤c , 将所有 物品全部装 包就
i t
题. 在现实生活中具有广泛的应用 . 如物流公 司的货物发配 . 集装箱 的 是最优解 . 这个最优解是它的上界 否则设第一个不 能人 包的物品为 装运 。 资金运算 。 存储 分配等问题 , 并且还常常作为其他 问题 的子 问题
2 . 2 . 2 问题求解 设 已经找到的可行解 的最大值为 c E .所有子问题的上界 的最 大 背包 问题 的数学模型实际上是一个 O - 1 规划问题。 假设有 n 个物 M, 计算误差为( c M —c E ) / c M。计算结束 时 , 近似最优解就是 c E , 件, 其 重量用 w i 表示, 价值为 p ; ( i =1 , 2 , …, n ) , 背包的最大容 纳重量为 值为 c c , 当物件 i 被选人背包时 , 定义变 量 X i = 1 , 否则 x I _ 0 。现在考虑 n 个 显然 近似最优解与全局最优解 的实际误差不大于计算 误差 当一个 子问题的上界小于 c E .则 可以知道这个子问题的可行解 物 件 的 选 择与 否, 则 背 包 内n 个 物 件 总 重 量 为∑ , 物 件的 总 价 值 不包含原始 问题 的最优解 , 因此可以排除这部分可行 解。 i; l 当计算误差 小于或等于 问题 所要求 的误差 时 . 计算停止 . 即 已经 找到符合要求的近似最优解 为∑p 舷, 如 何决 定 变 量】 c i ( i = 1 , 2 , …, n ) 的 值( 即 确 定 一个 物 件 组 合 ) i= 1 算法求解步骤如下 : 使背包内物件总价值 为最大。哄 数学模 型表示如下 : ( 1 ) 求原始 问题的 2 个直系子问题 , 加人原始 问题 的子问题队列 . 用贪心算法求每个子问题的可行解和上界。 M a x i m i z e ∑肼 i= I ( 2 ) 判断是否找到满足要求的近似最优解 , 如果找 到, 停止计算 。 ( 3 ) 取 出子问题 队列 中上界最大 的子问题 h . 求 h的 2 个 直系子 S u b j e c t t o ∑% ≤ c 问题的上界和可行解 . 如果某个直系子问题 的上界小 于当前最大可行 x i = 1 或o ( i =1 , 2 , …, n ) 解. 排除这个直 系子问题 . 用剩 下的直系子 问题取 代 h 加入 子问题队 列. 转到 ( 2 ) 。 2 基于贪心算法的启发式算法 2 _ 3 算法的最坏性能 比 算法执 行完 ( 1 ) 之后 , 考 察原始 问题 的 2个 直 系子问题 , 其 可行 2 . 1 贪心算法 标 函数值分别 为 f 2 , £ , 选择较大 的可 行解 作为近似最 优解 。 f 2 贪心算法是求解 O - 1 背包 问题最快速 的方法之一 . 其时 间复杂度 解的 目
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析期末论文题目用贪心法求解“0-1背包问题”专业计算机科学与技术班级09计算机一班学号0936021姓名黄帅日期2011年12月28日一、0-1背包问题的算法设计策略分析1.引言对于计算机科学来说,算法的概念是至关重要的,例如,在一个大型软件系统的开发中,设计出有效的算法将起决定性的作用。
算法是解决问题的一种方法或一个过程。
程序是算法用某种设计语言具体实现描。
计算机的普及极大的改变了人们的生活。
目前,各行业、各领域都广泛采用了计算机信息技术,并由此产生出开发各种应用软件的需求。
为了以最小的成本、最快的速度、最好的质量开发出适合各种应用需求的软件,必须遵循软件工程的原则。
设计一个高效的程序不仅需要编程小技巧,更需要合理的数据组织和清晰高效的素算法,这正是计算机科学领域数据结构与算法设计所研究的主要内容。
2. 算法复杂性分析的方法介绍算法复杂性是算法运行所需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要的空间资源的量称为空间复杂性。
这个量应该只依赖于算法要解的问题的规模、算法的输入和算法本身的函数。
如果分别用N 、I 和A 表示算法要解问题的规模、算法的输入和算法本身,而且用C 表示复杂性,那么,应该有C=F(N,I,A)。
一般把时间复杂性和空间复杂性分开,并分别用T 和S 来表示,则有: T=T(N,I)和S=S(N,I) 。
(通常,让A 隐含在复杂性函数名当中最坏情况下的时间复杂性:最好情况下的时间复杂性:平均情况下的时间复杂性:其中DN 是规模为N 的合法输入的集合;I*是DN 中使T(N, I*)达到Tmax(N)的合法输入; 是中使T(N, )达到Tmin(N)的合法输入;而P(I)是在算法的应用中出现输入I 的概率。
算法复杂性在渐近意义下的阶:渐近意义下的记号:O 、Ω、θ、o 设f(N)和g(N)是定义在正数集上的正函数。
O 的定义:如果存在正的常数C 和自然数N0,使得当N ≥N0时有f(N)≤Cg(N),则称函数f(N)当N 充分大时上有界,且g(N)是它的一个上界,记为f(N)=O(g(N))。
即f(N)的阶不高于g(N)的阶。
根据O 的定义,容易证明它有如下运算规则:(1)O(f)+O(g)=O(max(f,g));(2)O(f)+O(g)=O(f+g);(3)O(f)O(g)=O(fg);(4)如果g(N)=O(f(N)),则O(f)+O(g)=O(f);(5)O(Cf(N))=O(f(N)),其中C 是一个正的常数;∑∈=N D I I N T I P (N)T ),()(avg ∑∑∈==N D I k i i i I N e t I P ),()(1),(min min I N T (N)T N D I ∈=),(min 1I N e t k i i i D I N ∑=∈=)~,(1I N e t k i i i ∑==)~,(I N T =),(max max I N T (N)T N D I ∈=),(max 1I N e t k i i i D I N ∑=∈=),(*1I N e t k i i i ∑==),(*I N T =(6)f=O(f)。
Ω的定义:如果存在正的常数C和自然数N0,使得当N≥N0时有f(N)≥Cg(N),则称函数f(N)当N充分大时下有界,且g(N)是它的一个下界,记为f(N)=Ω(g(N))。
即f(N)的阶不低于g(N)的阶。
θ的定义:定义f(N)= θ(g(N))当且仅当f(N)=O(g(N))且f(N)= Ω(g(N))。
此时称f(N)与g(N)同阶。
o的定义:对于任意给定的ε>0,都存在正整数N0,使得当N≥N0时有f(N)/Cg(N)≤ε,则称函数f(N)当N充分大时的阶比g(N)低,记为f(N)=o(g(N))。
例如,4NlogN+7=o(3N2+4NlogN+7)。
二、贪心算法分析设计策略介绍贪心算法:顾名思义,贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
具有最优子结构性质的问题,用贪心算法更简单、更直接且解题效率更高。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
三、结合0-1背包问题详述贪心算法解决问题的过程0-1背包问题:给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量是c。
问应如何选择装入背包中的物品,使得装入背包中的物品总价值最大。
在选择装入背包的物品时,对每种物品i只能有两种选择,装入包或者不装入。
不能物品i装入包多次,也不能之装入部分的物品i。
问题描述:假定有n个物体和一个背包,物体i 有质量wi,价值为pi,而背包的载荷能力为M。
若将物体i的一部分xi(1<=i<=n,0<=xi<=1)装入背包中,则有价值pi*xi。
在约束条件(w1*x1+w2*x2+…………+wn*xn)<=M下使目标(p1*x1+p2*x2+……+pn*xn)达到极大,此处0<=xi<=1,pi>0,1<=i<=n.这个问题称为背包问题(Knapsack problem)。
算法描述 :首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。
依此策略一直地进行下去,直到背包装满为止。
程序代码:#include <iostream.h>structgoodinfo{float p; //物品效益float w; //物品重量float X; //物品该放的数量int flag; //物品编号}; //物品信息结构体voidInsertionsort(goodinfo goods[],int n){intj,i;for(j=2;j<=n;j++){goods[0]=goods[j];i=j-1;while (goods[0].p>goods[i].p){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}} //按物品效益,重量比值做升序排列void bag(goodinfo goods[],float M,int n){float cu;inti,j;for(i=1;i<=n;i++)goods[i].X=0;cu=M; //背包剩余容量for(i=1;i<n;i++){if(goods[i].w>cu)//当该物品重量大与剩余容量跳出break;goods[i].X=1;cu=cu-goods[i].w;//确定背包新的剩余容量}if(i<=n)goods[i].X=cu/goods[i].w;//该物品所要放的量for(j=2;j<=n;j++) /*按物品编号做降序排列*/{goods[0]=goods[j];i=j-1;while (goods[0].flag<goods[i].flag){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}///////////////////////////////////////////cout<<"最优解为:"<<endl;for(i=1;i<=n;i++){cout<<"第"<<i<<"件物品要放:";cout<<goods[i].X<<endl;}}void main(){cout<<"|--------运用贪心法解背包问题---------|"<<endl; cout<<"|---power by zhanjiantao(028054115)---|"<<endl; cout<<"|-------------------------------------|"<<endl;int j;int n;float M;goodinfo *goods;//定义一个指针while(j){cout<<"请输入物品的总数量:";cin>>n;goods=new structgoodinfo [n+1];//cout<<"请输入背包的最大容量:";cin>>M;cout<<endl;inti;for(i=1;i<=n;i++){ goods[i].flag=i;cout<<"请输入第"<<i<<"件物品的重量:";cin>>goods[i].w;cout<<"请输入第"<<i<<"件物品的效益:";cin>>goods[i].p;goods[i].p=goods[i].p/goods[i].w;//得出物品的效益,重量比cout<<endl;}Insertionsort(goods,n);bag(goods,M,n);cout<<"press <1> to run agian"<<endl;cout<<"press <0> to exit"<<endl;cin>>j;}}四、贪心算法策略小结贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留。
由前面中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解。
五、结合自身情况谈谈本课程学习体会及其影响算法是编程最终的部分,想要把程序写的好,就要用好的算法。
不同的问题有不同的算法模型,同一个问题也可能有不同的算法描述。
每种算是都有自己的时间复杂度和空间复杂度。