分支限界

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

分支界定的关键问题:

(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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞