分支限界

分支界定是一种在问题的解空间树上搜索问题的解的方法,其实就是剪枝广搜,它始终维护一个上下界用来剪枝,一个限界函数计算对解的最有期望。主要用于解决离散问题的优化。

分支界定的关键问题:

(1)如何确定合适的限界函数

(2)如何组织待处理节点表

(3)如何记录最优解路径

限界函数应该是经过该节点所有搜索路径的最佳期望

最大问题:本质还是广搜,复杂度肯定不低,2^n的节点空间也受不了,试着解决01背包超时又超存,肯定不如DP,也可以解决TSP,排线问题等,

下边自己写的一个01背包,问题一堆,哎,菜鸟一个….

http://acm.hdu.edu.cn/showproblem.php?pid=2602

#include<stdio.h>
#include<queue>
#include<algorithm>

using namespace std;

#define MAXN 1005

struct ITEM
{
	int w,v;
}b[MAXN];

struct NODE
{
	int w,v,ve,pos;

	bool operator < (const NODE & other)const
	{
		return ve < other.ve;
	}
};

int search(ITEM * b,int num,int vol);
int cmp(const void * a,const void * b);
int expect(NODE a,ITEM * b,int num);

int main()
{
	//freopen("Sample Input.txt","r",stdin);
	int caseNum;
	scanf("%d",&caseNum);

	while(caseNum--)
	{
		int vol,num;
		scanf("%d%d",&num,&vol);

		for(int i = 0;i < num;i++)
		{
			scanf("%d",&b[i].v);
		}
		for(int i = 0;i < num;i++)
		{
			scanf("%d",&b[i].w);
		}

		printf("%d\n",search(b,num,vol));
	}
}

int search(ITEM * b,int num,int vol)
{
	qsort(b,num,sizeof(b[0]),cmp);

	/*for(int i = 0;i < num;i++)
	{
		printf("%d %d\n",b[i].w,b[i].v);
	}*/

	int min = 0;						//贪心的一个最小界
	int t = vol;
	for(int i = 0;i < num;i++)
	{
		if(t >= b[i].w)
		{
			min += b[i].v;
			t -= b[i].w;
		}
	}
	/*printf("%d %d\n",vol,min);*/
	priority_queue<NODE> que;
	
	NODE fir;
	fir.v = 0;
	fir.w = vol;
	fir.pos = 0;
	fir.ve = expect(fir,b,num);
	que.push(fir);

	while(!que.empty())
	{
		NODE cur = que.top();
		que.pop();

		if(cur.pos == num)
		{
			return cur.v;
		}

		for(int i = 0;i <= 1;i++)
		{
			NODE next = cur;
			if(i == 1 && next.w < b[cur.pos].w)
			{
				continue;
			}
			next.w -= (i * b[cur.pos].w);
			next.v += (i * b[cur.pos].v);
			next.pos++;
			next.ve = expect(next,b,num);

			if(next.pos == num && next.v > min)
			{
				min = next.v;
			}
			if(next.ve >= min)
			{
				que.push(next);
			}
		}
	}
}

int cmp(const void * a,const void * b)
{
	double rate_a = double(((ITEM *) a) -> v) / ((ITEM *) a) -> w;
	double rate_b = double(((ITEM *) b) -> v) / ((ITEM *) b) -> w;
	return rate_b - rate_a;
}

int expect(NODE a,ITEM * b,int num)						//限界函数
{
	if(a.pos == num)
	{
		return a.v;
	}
	else
	{
		return a.v + a.w * b[a.pos].v / b[a.pos].w;
	}
}

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/super_tramp/article/details/9230897
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞