0-1背包问题回溯法
来源:互联网 发布:排课系统算法 编辑:程序博客网 时间:2024/05/01 06:02
■回溯法
0-1背包问题是回溯法中的子集选取问题,0-1背包问题的解空间可以用子集树来表示。
设cw为当前重量,w[]为每个物品的重量。在搜索解空间树时,只要其左儿子结点是一个可行结点,即当前重量加该结点的重量小于等于背包容量(cw+w[i]<=c),搜索就进入其左子树。
设上界函数为Bound(int i),当前最优值为bestp。当右子树中有可能包含最优解时才进入右子树搜索。否则将右子树剪去。右子树中有可能包含最优解的条件是右子树的上界大于当前最优值(Bound(i+1)
>bestp)。
计算右子树上界的方法是将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下去时,再装入该物品的一部分而装满背包。由此得到的价值是右子树中解的上界。排序用到的算法是哨兵算法。
本程序将可选物品定义为一个表来进行运算,比定义数组简洁。
typedef struct{
double p;//物品价值
double w;//物品重量
double v;//物品单位价值
int flag;//物品排序前的位置
}RedType;
typedef struct{
int length;
RedType r[5001];
}SqList;
伪代码如下:
int n;//物品数量
double c;//背包容量
int x[5001]={0};//物品是否放入标志
double bestp=0;//当前最优价值
double cp=0;//当前价值
double cw=0;//当前重量
void sort()
{
.../*利用哨兵法,将物品按单位价值L.r[i].v排序*/
}
int Bound(int i)/*上界函数*/
{
int cleft=c-cw;/*剩余容量*/
while(i<=n&&L.r[i].w<=cleft)/*以物品单位价值递减序装入物品*/
{
cleft-=L.r[i].w;
i++;
}
.../*将背包完全满*/
return;/*返回上界*/
}
void Backtrack(int i)//回溯函数
{
if(i>n)/*到达叶子结点*/
{
bestp=cp;
return;
}
if(cw+L.r[i].w<=c)/*进入左子树*/
{
cw+=L.r[i].w;
cp+=L.r[i].p;
x[i]=1;/*将标记x记为1*/
Backtrack(i+1);
cw-=L.r[i].w;
cp-=L.r[i].p;
}
if(Bound(i+1)>bestp)/*进入右子树*/
Backtrack(i+1);
}
int main()
{
... /*输入数据*/
sort();/*对输入的数据按物品单位价值排序*/
Backtrack(1);/*从第一层开始搜索*/
for(i=1;i<=n;i++) /*输出结果*/
for(j=1;j<=n;j++)
if(L.r[j].flag == i)
{
printf("%d %d\n",i,x[j]);
break;
}
printf("%g\n",bestp);
}
主程序在输入数据后,调用sort()函数对输入的数据按物品单位价值排序,再调用Backtrack(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背包问题
- 0-1背包问题回溯法
- 0-1背包问题---回溯法
- 回溯法解决0-1背包问题
- 0-1背包问题(回溯法)
- 回溯法解0-1背包问题
- 回溯法解0-1背包问题
- spss Clementine12 破解方法
- POJ 2186 Popular Cows -- tarjan 缩点
- 使用jquery.upload.js实现异步上传
- api文件名
- crontab详解
- 0-1背包问题回溯法
- c++操作sqllite
- ActiveX控件注册问题
- 算法之dijkstra算法
- gdb
- 第二讲:使用HTML5绘制简单的图形
- Git 教程 - Git 基本用法
- XP 系统开机自动登录
- Spring事务配置的五种方式