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

//Author: FF-W
//Date: 29, Oct, 2018
//Purpose: 0-1背包问题(分支限界-优先队列)

#include <iostream>
#include<queue>
using namespace std;

class itemNode
{
public:

    int cw;
    int cp;
    bool isleft;
    int level;
    int up;
    itemNode* parentNode;
    itemNode(int w,int p,bool is_left,int lev,int upp,itemNode*node)
    {
        cw=w;
        cp=p;
        isleft=is_left;
        level=lev;
        up=upp;
        parentNode=node;
    }
    itemNode()
    {

    }

    /*itemNode(itemNode* node)
    {
        cw=node->cw;
        cp=node->cp;
        isleft=node->isleft;
        level=node->level;
       // parentNode=node->parentNode;
    }*/

    itemNode& operator=(const itemNode& node)
    {
        cp=node.cp;
        cw=node.cw;
        isleft=node.isleft;
        up=node.up;
        level=node.level;
        parentNode=node.parentNode;
        return *this;

    }

    itemNode* clone()
    {
        return this;
    }

};
struct cmp{
    bool operator ()(itemNode*a,itemNode* b)
    {
        return a->up<b->up;
    }
};
priority_queue<itemNode*,vector<itemNode*>,cmp>itemQueue;

bool check(int t,int cp,int V[],int nItem,int bestcp)
{

    int vSum=0;
    for(int i=t; i<nItem; i++)
    {
        vSum+=V[i];
    }
    if(vSum+cp>bestcp)
        return true;
    return false;
}

itemNode* branch_bounding(int nItem,int W[],int V[],int wAll)
{
    int i=0;
    int cp=0;
    int cw=0;
    int bestcp=0;
    itemNode *node=NULL;
    itemNode *retNode=NULL;

    while(true)
    {

        if(i+1>nItem&&node->cp>bestcp)
        {
            retNode=node->clone();
            return retNode;
        }

        else
        {
            int rp=0;
            for(int t=i; t<nItem; t++)
            {
                rp+=V[t];
            }
            if(cw+W[i]<=wAll)
            {
                itemQueue.push(new itemNode(cw+W[i],cp+V[i],true,i+1,cp+rp,node));
            }
            if(rp+cp>bestcp)
            {
                itemQueue.push(new itemNode(cw,cp,false,i+1,cp+rp,node));

            }
        }

        if (itemQueue.empty())
        {
            break;
        }
        node=itemQueue.top();
        itemQueue.pop();
        i=node->level;
        cw=node->cw;
        cp=node->cp;
    }
    return retNode;
}

void show(itemNode*node)
{
    while(node!=NULL)
    {
        if(node->isleft!=0)
        {
            cout<<"第"<<node->level<<"个物品 ";
        }

        node=node->parentNode;
    }
}


int main()
{
    itemNode *resNode=NULL;
    cout<<"背包问题"<<endl;
    cout<<"请输入背包总容量:"<<endl;
    int wAll;
    cin>>wAll;
    cout<<"请输入物品个数:"<<endl;
    int nItem;
    cin>>nItem;
    int W[nItem];
    int V[nItem];
    cout<<"请输入物品价值和质量:"<<endl;

    for(int i=0; i<nItem; i++)
    {
        cin>>V[i]>>W[i];
    }
    resNode=branch_bounding(nItem,W,V,wAll);
    cout<<"为使得背包中物品价值最大,选择如下序列:"<<endl;
    show(resNode);

    return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
完全0-1背包问题是指每个物品可以无限次地选择放入背包中,而分支限界法是一种解决背包问题算法。下面是完全0-1背包问题分支限界法的实现步骤: 1.定义一个节点类,包含以下属性: - level:当前节点所在的层数 - profit:当前节点的价值 - weight:当前节点的重量 - bound:当前节点的价值上界 - include:一个列表,表示当前节点所包含的物品 2.定义一个优先队列,用于存储节点。将根节点加入队列中。 3.进入循环,直到队列为空: - 取出队列中价值最大的节点。 - 如果该节点的价值上界小于当前最优解,则剪枝。 - 否则,分别生成两个子节点: - 包含当前层的下一个物品。 - 不包含当前层的下一个物品。 - 将两个子节点加入队列中。 4.返回最优解。 下面是完全0-1背包问题分支限界法的Python实现代码: ```python import queue class Node: def __init__(self, level, profit, weight, bound, include): self.level = level self.profit = profit self.weight = weight self.bound = bound self.include = include def knapsack(n, W, wt, val): q = queue.PriorityQueue() v = [0] * n u = [0] * n u[n-1] = val[n-1] * (W // wt[n-1]) bound = u[n-1] q.put((-bound, Node(0, 0, 0, bound, v))) max_profit = 0 while not q.empty(): _, node = q.get() if node.bound < max_profit: continue if node.level == n: max_profit = node.profit continue i = node.level if node.weight + wt[i] <= W: v1 = node.include[:] v1[i] += 1 u1 = u[:] u1[i] = (W - node.weight) // wt[i] * val[i] + node.profit q.put((-u1[i], Node(i+1, node.profit+val[i], node.weight+wt[i], u1[i], v1))) u2 = u[:] u2[i] = node.profit + (W - node.weight) // wt[i] * val[i] q.put((-u2[i], Node(i+1, node.profit, node.weight, u2[i], node.include))) return max_profit # 示例输入 n = 10 W = 50 wt = [12, 3, 11, 5, 6, 8, 9, 4, 7, 10] val = [6, 2, 7, 3, 2, 9, 8, 10, 4, 5] # 输出最大价值 print(knapsack(n, W, wt, val)) # 输出:94 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值