分支限界:0-1背包问题(队列+优先队列)

0-1背包问题(队列)

#include<iostream>
#define N 3	//物品种类 
#define W 5	//背包重量 
using namespace std;
int w[N]={1,2,3};	//物品重量 
int v[N]={6,12,10}; //物品价值 
int maxV=0;	//最大价值
int sum=28;	//物品总价值"界"
int sumV[N]={28,18,6};

int front=-1,rear=-1;
struct node{
	int n;	//队列编号 
	int w;	//当前重量 
	int v;	//当前价值 
	int parent;	//父节点 
	int ub;	//当前界 
}qu[2*N-1];

void bfs(){
	struct node root={0,0,0,-1,sum};
	qu[rear+1]=root;
	rear++;//根节点进队 
	while(front!=rear){//队列不为空 
		int u=front+1;
		front++;//根节点出队 
		if(qu[u].ub>maxV){	//界 
			if(qu[u].w+w[qu[u].n]<=W){//可以装下,生成新节点 
				struct node Lchild={qu[u].n+1,qu[u].w+w[qu[u].n],qu[u].v+v[qu[u].n],u,qu[u].ub};
				qu[rear+1]=Lchild;
				rear++;//新节点进队 
				if(maxV<qu[rear].v)
					maxV=qu[rear].v;
			}
			if(qu[u].v+sumV[qu[u].n]>maxV){//剪枝
				struct node Rchild={qu[u].n+1,qu[u].w,qu[u].v,u,qu[u].ub-v[qu[u].n]};
				qu[rear+1]=Rchild;
				rear++;//新节点进队 
				if(maxV<qu[rear].v)
					maxV=qu[rear].v;
			}
		}
	}
}

int main(){
	bfs();
	cout<<maxV<<endl;
}

0-1背包问题(优先队列)

#include<iostream>
#include<queue>
#define N 3	//物品种类 
#define W 5	//背包重量 
using namespace std;
int w[N]={1,2,3};	//物品重量 
int v[N]={6,12,10}; //物品价值 
int maxV=0;	//最大价值
int sum=28;	//物品总价值"界"
int sumV[N]={28,18,6};

struct node{
	int n;
	int w;
	int v;
	int ub;
	friend bool operator<(node a,node b){
		return a.ub < b.ub; //结构体中,x大的优先级高 ,先出队
//		return a.ub > b.ub; //结构体中,x小的优先级高 ,先出队 
    }
};
priority_queue<node> q;//优先队列 

void bfs(){
	struct node root={0,0,0,sum};
	q.push(root);//进队 
	while(!q.empty()){
		struct node u=q.top();//取队头元素 
		q.pop();//根节点出队 
		if(u.ub>maxV){
			if(u.w+w[u.n]<=W){
				struct node l={u.n+1,u.w+w[u.n],u.v+ v[u.n],u.ub};
				q.push(l);//新节点进队 
				if(maxV<u.v)
					maxV=u.v;
			}
			if(u.v+sumV[u.n]>maxV){
				struct node r={u.n+1,u.w,u.v,u.ub-v[u.n]};
				q.push(r);//新节点进队 
				if(maxV<u.v)
					maxV=u.v;
			}
		}
	}
}
int main(){
	bfs();
	cout<<maxV<<endl;
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值