写在前面
邻近期末,惰性上升,有点懒,除了做算法实验,就没怎么干其他的事,偶然又想起以前胡适之的日记lmao,言归正传,这次算法实验要求用优先队列式分支限界法解决0-1背包问题,但在调试过程中除了一些问题,一开始以为是Dev抽风(尤记得以前常说:编译器从不会骗你lmao),开始有些浮躁,因为出现了数据规模越大,反而运行时间变小的情况,而又冷静分析,方得其要领。
算法过程
言简意赅,直接上我的算法过程(能力有限,如有不好的地方,望不吝赐教)
1.将所有物品按性价比排序(降序)——优先选择条件
2.依次搜寻,并对当前路径的可行性进行判断(按贪心算法求出当前路径的最大解,与当前可行解比较,若更小的话, 这条路径可以废了————剪枝)
3.重复2直到结束
关键函数
判断上界(用贪心法求)
int judge(int num,int tmp,int w)
{
int k=0,i;
//按贪心法求上界
for(i=num;i<n;i++)
{
if(w>b[i].w)
tmp=tmp+b[i].v,w=w-b[i].w;
else if(w==0)
break;
else
tmp=tmp+b[i].v*w,w=0;
}
//上界与当前可行解ans进行比较,若比当前还小,则剪枝
if(tmp>ans)
k=1;
return k;
}
主递归函数
//tmp表示当前路径可行解 w表示当前剩余重量 now表示当前搜索位置
//y表示出队元素个数(也就是此路径放入背包的物品数)n表示总的物品数(物品已排序)
void find(int tmp,int w,int now,int y)
{
int i,k,w0,j,l;
j=now+1;
//若遍历完成,则讨论
if(now==n)
{
//若此路径下求出的可行解大于当前最优解,则交换
if(ans<tmp)
{
ans=tmp;
memset(u, 0, sizeof(u));
//解向量赋值
for(i=0;i<y;i++)
{
u[a[i]]=1