算法大作业 0-1背包问题求解六种方法综述(实验报告+运行结果截图+源码)

《算法分析与设计》大作业报告

0-1背包问题求解方法综述

院 系:

专 业:

班 级:

学 号:

指导教师:

报告日期:

算法分析与设计大作业报告

0-1背包问题求解方法综述

总计:论文设计 26页

图片: 11 个

0-1背包问题求解方法综述

软件工程 宋帅

【摘要】

0-1背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想。0-1背包问题说的是,背包只能容得下一定重量b的物品,物品有m种,每种物品有自己的重量w(i)和价值v(i)(0<i<=m),从这些物品中选择装入背包,使背包不超过重量b,但价值又要最大。本实验主要使用了解决01背包问题中的蛮力算法;贪心算法;动态规划算法;遗传算法;分支限界法;回溯解法六种方法对01背包问题进行求解.分析了 0-1 背包问题的数学模型 , 刻划了最优解的结构特征, 建立了求最优值的递归关系式。本文通过六个算法求解01背包问题的效果及时间复杂度等的对比找寻求解最优解的方法

【关键词】

0-1 背包问题;价值;容量;单位价值;蛮力算法;贪心算法;动态规划算法;遗传算法;分支限界法;回溯解法;最优解。

目录

一.前言1

二.技术说明1

三.原理描述1

四.算法实现4

五.测试与运行22

六.小结26

参考文献26

致谢26

一.前言

0-1背包问题说的是,背包只能容得下一定重量b的物品,物品有m种,每种物品有自己的重量w(i)和价值v(i)(0<i<=m),从这些物品中选择装入背包,使背包不超过重量b,但价值又要最大。很多问题都可以抽象成该问题模型如配载问题、物资调运问题等,因此研究该问题具有较高的实际应用价值。目前,解决0-1 背包问题的方法有很多,主要有动态规划法、回溯法、分支限界法、遗传算法、粒子群算法、人工鱼群算法、蚁群算法、模拟退火算法、蜂群算法、禁忌搜索算法等。其中动态规划、回溯法、分支限界法时间复杂性比较高,计算智能算法可能出现局部收敛,不一定能找出问题的最优解。本文通过六个算法求解01背包问题的效果及时间复杂度等的对比找寻求解最优解的方法

二.技术说明

本实验主要用了解决01背包问题中的蛮力算法;贪心算法;动态规划算法;遗传算法;分支限界法;回溯解法六种方法对01背包问题进行求解.以及通过时间复杂度等的对比寻求最优解的方法

三.原理描述

1,蛮力算法:

给定n个重量为{w1,w2,w3,....,wn}、价值为{v1,v2,v3,...,vn}的物品和一个容量为C的背包,0/1背包问题是求解这些物品中的一个最有价值的子集,并且要能够装到背包中。

使用蛮力法解决0/1背包问题,就是将所有的物品装入背包的可能全部列举出来(背包问题的蛮力解法是穷举这些物品的所有子集,找出能够装到背包中的所有子集,并在这些子集中找出价值最大的子集)。这个可以通过递归的方式实现。递归的过程可以看成是对一棵树的深度优先遍历:

例如上图,假设从背包中的1号物品开始列举所有的可能。如果每一层仅仅简单的在循环中使用递归,则该程序就不会结束。需要使用一个一维向量用于标记当前哪些编号已经装入了。例如,当前1号物品已经装入背包,首先标记1号物品已经装入。之后,在循环中首先选择2号物品,如果没有超出背包的最大承重的话,标记2号物品已经装入。当前还有3、4号物品没有装入,所以继续递归尝试装入3、4号物品。在装入2号物品之后的所有可能的递归全部完成后,修改当前标记,并将2号物品从背包中拿出,之后就可以递归遍历放入3号物品之后的可能的情况了。

蛮力法求解0/1背包问题的时间复杂度为:O(2^n)。

2,贪心算法

对于0-1背包问题,贪心算法之所以不能得到最优解是因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使每千克背包空间的价值降低了。事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再做出最好的选择。由此可导出许多互相重叠的子问题。

用贪心算法求解0-1背包问题的步骤是,首先计算每种物品单位重量的价值vi/wi;然后,将物品的vi/wi的大小进行降序进行排列,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总量未超过c,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直进行下去,直到背包装满为止。

3,动态规划算法:

关于动态规划最经典的问题当属背包问题。动态规划(Dynamic programming)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多 子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个 子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

算法步骤:

1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。

2. 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。 动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是 在表格中简单地查看一下结果,从而获得较高的效率。

动态规划法求解0/1背包问题的时间复杂度为:O(min{nc,2^n})。

4,回溯算法:

为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来处死那些实际上不可能产生所需解的活结点,以减少问题的计算量。这种具有限界函数的深度优先生成法称为回溯法。对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1向量组成,可用子集数表示。在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入左子树。当右子树中有可能包含最优解时就进入右子树搜索。

回溯法求解0/1背包问题的时间复杂度为:O(n*2^n)。

上面两棵解空间树是用回溯法解题时常遇到的两类经典的解空间树。n个物品的0-1背包问题所对应的解空间树就是一棵子集树。这类子集树通常有2^n个叶结点,其结点总个数为2^(n+1)-1.遍历子集树的任何算法均需要Ω(2^n)的计算时间。当所给的问题是确定n个元素满足某种性质的排列时,相应的解空间树成为排列树。排列树通常有n!个叶结点。因此遍历排列树需要Ω(n!)的计算时间。

5,分支限界算法:

首先,要对输入数据进行预处理,将各物品依其单位重量价值从大到小进行排列。在下面描述的优先队列分支限界法中,节点的优先级由已装袋的物品价值加上剩下的最大单位重量价值的物品装满剩余容量的价值和。算法首先检查当前扩展结点的左儿子结点的可行性。如果该左儿子结点是可行结点,则将它加入到子集树和活结点优先队列中。当前扩展结点的右儿子结点一定是可行结点,仅当右儿子结点满足上界约束时才将它加入子集树和活结点优先队列。当扩展到叶节点时为问题的最优值。

分支限界法求解0/1背包问题的时间复杂度为:O(2^n)。

6,遗传算法:

遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。

遗传算法主要有以下几个步骤

初始化种群

种群适应度计算

种群选择

种群交配

种群变异

第五步完成又又跳转到第二部迭代计算,直到达到收敛条件

四.算法实现

蛮力算法:

#include <iostream>

#include<cstdio>

using namespace std;

#define N 100

struct goods

{

int wight;//物品重量

int value;//物品价值

};

int n,bestValue,cv,cw,C;//物品数量,价值最大,当前价值,当前重量,背包容量

int X[N],cx[N];//最终存储状态,当前存储状态

struct goods goods[N];

int Force(int i){

if(i>n-1)

{

if(bestValue < cv && cw <= C)

{

for(int k=0;k<n;k++)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值