最近在看回溯,感觉就是深度优先遍历,思想差不多,不过对书上的上界函数不是很懂。
自己尝试用回溯写了下背包问题,感觉蛮好。
注释写的很详细了。
上代码。
#include<iostream>
#define Max 100
using namespace std;
//背包问题,尝试用回溯
int x[Max],n,wmax,w[Max],v[Max],cw=0,cv=0;
//cw当前背包重量,cv当前背包价值,x保存每个可行解的物品选择情况
int xmax[Max],maxv=0;//最优值时对应的每个物品的选择情况
void print()
{//打印x数组,测试函数的执行过程
for(int i=1;i<=n;i++)
cout<<x[i]<<" ";
cout<<endl;
}
void copy()
{//将当前状态的最优解的情况保存
for(int i=1;i<=n;i++)
xmax[i]=x[i];
}
void fun(int i)
{//回溯,i从1到n
if(i>n)
{//到达叶子节点,一个可行解已经出来
// print();//测试打印
if(maxv<cv)
{maxv=cv;copy();}//保存最优解
return;
}
if(cw+w[i]<=wmax)
{//选择此物品放进背包,进入左子树
cw+=w[i];
cv+=v[i];
x[i]=1;//标记当前第i个货物已放进背包
fun(i+1);
cw-=w[i];//回溯到之前的状态准备进入右子树
cv-=v[i];
x[i]=0;
}
fun(i+1);//不把第i个物品放进背包,进入右子树
}
int main()
{
freopen("data.txt","r",stdin);
cin>>n>>wmax;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
x[i]=0;
}
cw=cv=maxv=0;
fun(1);
cout<<"最优解的物品选择情况:"<<endl;
for(i=1;i<=n;i++)
cout<<xmax[i]<<" ";
cout<<endl<<"最大价值为:"<<maxv<<endl;
return 0;
}
数据和程序运行结果:
对于测试函数的打印,传几张,以后再看的话清楚点。
打印的是所有可行解的物品选择情况。
-----2013-12-27 中午14:45 快期末了,下周去抱佛脚,最近几天还是按计划进行。