0-1背包问题之分支限界法

    有n个物体,重量和价值已知,要放入容量为c的背包里,放入的时间,要求放入的总重量不能超过包的容量,同时保证价值最大。


    前面分别用回溯法、暴力搜索法进行了求解,这里利用分支限界法进行求解。参考代码如下:

#include <stdio.h>
#include <stdlib.h>

typedef struct QNode{
	int value;	//当前结点的总价值
	int weight; //当前的总重量
	struct QNode *next;
}QNode, *QueuePtr;

typedef struct{
	QueuePtr front;
	QueuePtr rear;
}Queue;

int initQueue(Queue &Q)
{
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)
		return -1;
	Q.front->next=NULL;

	return 1;
}

int emptyQueue(Queue Q)
{
	if (Q.front==Q.rear)
		return 1;
	else
		return 0;
}

int destroyQueue(Queue &Q)
{
	while(Q.front){
		Q.rear=Q.front->next;
		free(Q.front);
		Q.front=Q.rear;
	}
	return 1;
}

int enQueue(Queue &Q, int value, int weight)
{
	QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
	if(!p)
		return -1;
	p->value=value; 
	p->weight=weight; 
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
	
	return 1;
}

int deQueue(Queue &Q, int &value, int &weight)
{
	QueuePtr p;
	if(Q.front==Q.rear)
		return -1;
	p=Q.front->next;
	value=p->value;
	weight=p->weight;
	Q.front->next=p->next;

	if(Q.rear==p) Q.rear=Q.front;
	
	free(p);

	return 1;
}

Queue loadingQueue;
int bestvalue, n;

void inQueue(int value, int weight, int i)
{
	if(i==n-1)
	{
		if(value>bestvalue)
			bestvalue=value;
	}
	else
		enQueue(loadingQueue,value,weight);
}



int main()
{
	
	int i,j,k;
	int *w, *v, ew, ev;
	int c;

	printf("input the number of things and the volume of ships:");
	scanf("%d%d",&n,&c);

	w=new int[n];
	v=new int[n];
	printf("input the weights:");
	
	for(i=0;i<n;i++)
		scanf("%d",&w[i]);

	printf("input the values:");

	for(i=0;i<n;i++)
		scanf("%d",&v[i]);

	
	initQueue(loadingQueue);
	enQueue(loadingQueue,-1,0);		
	//int deQueue(Queue &Q, int &value, int &weight)	
	//void inQueue(int value, int weight, int i)
	//int enQueue(Queue &Q, int value, int weight)


	i=0;	//层数
	ew=0;	//扩展结点对应的载重量
	ev=0;	

	while(true)
	{
		if(ew+w[i]<=c)
			inQueue(ev+v[i],ew+w[i],i);
		inQueue(ev,ew,i);

		deQueue(loadingQueue, ev,ew);

		if(ev==-1) //同层结点尾部
		{
			if(emptyQueue(loadingQueue))
			{
				printf("the result is %d.\n",bestvalue);
			}

			enQueue(loadingQueue,-1,0);
			deQueue(loadingQueue, ev,ew);
			i++;
		}
	}		
	
	return 0;
}









评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值