2019独角兽企业重金招聘Python工程师标准>>>

算法描述:

  活结点优先队列中结点元素N的优先级由该结点的上界函数Bound计算出的值uprofit给出。

  子集树中以结点N为根的子树中任一结点的价值不超过N.profit。

  可用一个最大堆来实现或节点优先队列。

  N.weight 是结点N所相应的重量,N.profit是N所相应的价值,N.uprofit是结点N的价值上界,最大堆以这个值作为优先级。

class Object{friend int Knapsack(int *,int *,int ,int ,int *);
public:int operator <= (Object a) const{return (d >= a.d);}
private:int ID;float d;
};template <class Typew,class Typep>
class Knap;
class bbnode{friend Knap<int,int>;friend int Knapsack(int *,int *,int,int,int *);
private:bbnode * parent;bool LChild;
};template <class Typew,class Typep>
class HeapNode{friend Knap<Typew,Typep>;
public:operator Typep() const {return uprofit;}
private:Typep uprofit,//结点价值上界
        profit;Typew weight;int level;//活结点所相应的重量bbnode * ptr;
};

上界计算函数:

template <class Typew,class Typep>
class Knap<Typew,Typep>::Bound(int i)
{Typew cleft = c- cw;//剩余容量Typep b = cp;//价值上界//以物品单位重量价值递减序装填剩余容量while(i<=n && w[i] <= cleft){cleft -= w[i];b += p[i];i++;}//装填剩余容量装满背包if(i<=n)b += p[i]/w[i] * cleft;return b;
}

分支限界搜索函数:

template <class Typew,class Typep>
Typep Knap<Typew,Typep>::MaxKnapsack()
{//优先队列式分支限界法,返回最大价值,bestx返回最优解//定义最大堆的容量为1000H = new MaxHeap< HeapNode<Typew,Typep> >(1000);//为bestx分配存储空间bestx = new int [n+1];//初始化int i=1;E= 0;cw = cp = 0;Typep bestp = 0;Typep up = Bound(1);//搜索子集空间树while(i!=n+1)//非叶节点
    {//检查当前扩展结点的左儿子结点Typew wt = cw + w[i];if(wt <= c){if(cp+p[i] > bestp)bestp = cp+p[i];AddLiveNode(up,cp+p[i],cw+w[i],true,i+1);}up = Bound(i+1);//检查扩展结点的右儿子结点if(up >= bestp)//右子树 可能含有最优解AddLiveNode(up,cp,cw,false,i+1);//取得下一扩展点HeapNode<Typep,Typew> N;H->DeleteMax(N);E = N.ptr;cw = N.weight;cp = N.profit;up = N.uprofit;i = N.level;}//构造当前最优解for(int j=n;j>0;j--){bestx[j] = E->LChild;E = E->parent;}return cp;
}

主要程序代码:

测试中.....(暂时不好使)

#include <iostream>
#include <algorithm>class Object{friend int Knapsack(int *,int *,int ,int ,int *);
public:int operator <= (Object a) const{return (d >= a.d);}
private:int ID;float d;
};template <class Typew,class Typep>
class Knap;
class bbnode{friend Knap<int,int>;friend int Knapsack(int *,int *,int,int,int *);
private:bbnode * parent;bool LChild;
};template <class Typew,class Typep>
class HeapNode{friend Knap<Typew,Typep>;
public:operator Typep() const {return uprofit;}
private:Typep uprofit,//结点价值上界
        profit;Typew weight;int level;//活结点所相应的重量bbnode * ptr;
};template <class Typew,class Typep>
class Knap{friend Typep Knapsack(Typep *,Typew *,Typew ,int ,int *);
public:Typep MaxKnapsack();
private:MaxHeap<HeapNode<Typep,Typew> > * H;Typep Bound(int i);void AddLiveNode(Typep up,Typep cp,Typew cw,bool ch,int level);bbnode * E;Typew c;int n;Typew * w;Typep *p;Typew cw;Typep cp;int *bestx;
};template <class Typew,class Typep>
class Knap<Typew,Typep>::Bound(int i)
{Typew cleft = c- cw;//剩余容量Typep b = cp;//价值上界//以物品单位重量价值递减序装填剩余容量while(i<=n && w[i] <= cleft){cleft -= w[i];b += p[i];i++;}//装填剩余容量装满背包if(i<=n)b += p[i]/w[i] * cleft;return b;
}template <class Typep,class Typew>
void Knap<Typep,Typew>::AddLiveNode(Typep up,Typep cp,Typew cw,bool ch,int lev)
{//将一个新的活结点插入到子集树 和 最大堆 H中bbnode *b = new bbnode;b->parent = E;b->LChild = ch;HeapNode<Typep,Typew> N;N.uprofit = up;N.profit = cp;N.weight = cw;N.level = lev;N.ptr = b;H->Insert(N);
}template <class Typew,class Typep>
Typep Knap<Typew,Typep>::MaxKnapsack()
{//优先队列式分支限界法,返回最大价值,bestx返回最优解//定义最大堆的容量为1000H = new MaxHeap< HeapNode<Typew,Typep> >(1000);//为bestx分配存储空间bestx = new int [n+1];//初始化int i=1;E= 0;cw = cp = 0;Typep bestp = 0;Typep up = Bound(1);//搜索子集空间树while(i!=n+1)//非叶节点
    {//检查当前扩展结点的左儿子结点Typew wt = cw + w[i];if(wt <= c){if(cp+p[i] > bestp)bestp = cp+p[i];AddLiveNode(up,cp+p[i],cw+w[i],true,i+1);}up = Bound(i+1);//检查扩展结点的右儿子结点if(up >= bestp)//右子树 可能含有最优解AddLiveNode(up,cp,cw,false,i+1);//取得下一扩展点HeapNode<Typep,Typew> N;H->DeleteMax(N);E = N.ptr;cw = N.weight;cp = N.profit;up = N.uprofit;i = N.level;}//构造当前最优解for(int j=n;j>0;j--){bestx[j] = E->LChild;E = E->parent;}return cp;
}template <class Typew,class Typep>
Typep Knapsack(Typep p[],Typew w[],Typew c,int n,int bestx[])
{Typew W = 0;Typep P = 0;//按 单位重量价值 排序Object * Q = new Object [n];for(int i=1;i<=n;i++){Q[i-1].ID = i;Q[i-1].d = 1.0*p[i]/w[i];P += p[i];W += w[i];}if(W<=c)return P;Sort(Q,n);Knap<Typew,Typep> K;K.p = new Typep[n+1];K.w = new Typew[n+1];for(int i=1;i<=n;i++){K.p[i] = p[Q[i-1].ID];K.w[i] = p[Q[i-1].ID];}K.cp = 0;K.cw = 0;K.c = c;K.n = n;Typep bestp = K.MaxKnapsack();for(int j=1;j<=n;j++){bestx[Q[i-1].ID] = K.bestx[j];cout<<bestx[Q[i-1.ID]]<<endl;}delete [] Q;delete [] K.w;delete [] K.p;delete [] K.bestx;cout<<"最大价值为"<<bestp<<endl;return bestp;
}
int main()
{int n,m;int w[100],p[100],best[100];cout<<"请输入想要输入的物品个数 及 背包重量:"<<endl;cin>>n>>m;cout<<"请依次输入想要输入的物品重量 及 价值"<<endl;for(int i=0;i<n;i++)cin>>w[i]>>p[i];Knapsack(w,p,m,n,best);return 0;
}

转载于:https://my.oschina.net/u/204616/blog/545446

0-1背包-分支限界相关推荐

  1. Python 0/1背包、动态规划

    参考:http://www.cnblogs.com/fcyworld/p/6243012.html Python 0/1背包.动态规划 0/1背包问题:在能承受一定重量的背包中,放入重量不同,价值不同 ...

  2. P1417 烹调方案 (0/1背包+贪心)

    题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...

  3. 算法分析与设计——蛮力法0/1背包

    蛮力法0/1背包 蛮力法 蛮力法是一种简单直接解决问题的方法,常常直接基于问题的描述,所以蛮力法也是最容易应用的方法. 蛮力法所依赖 的基本技术是遍历,即采用一定的策略依次处理待求解问题的所有元素,从 ...

  4. 数据结构与算法 / 回溯算法(八皇后、0 - 1 背包)

    回溯算法,顾名思义,就是在没有得到最优解的前提下,不断的返回至前面的岔路口位置,重新选择,直至遍历了所有的情况或者得到的预期最优解的情况下再结束. 与贪心算法不同的是,回溯算法理论上是可以得到最优解, ...

  5. 【例1】 0/1背包《信息学奥赛一本通》【解法一】 02

    /* [例1] 0/1背包<信息学奥赛一本通>[解法一] 02 http://ybt.ssoier.cn:8088/problem_show.php?pid=1267 */ #includ ...

  6. HDOJ 2602-Bone Collector(0/1背包模板、打印方案及滚动数组解法)

    0/1背包 一.Bone Collector 解法一:二维数组解法(0/1背包模板代码) 1.1 0/1背包打印方案代码 解法二:滚动数组(一维)解法 2.1 一维滚动数组例题 E-爱玩游戏的Tom ...

  7. 动态规划(五)——0/1背包

    0/1背包 一.0/1背包问题 1.实例讲解 2.DP求解0/1背包 3.输出0/1背包方案 二.0/1背包题目代码(持续更新) 一.0/1背包问题 给定n种物品和一个背包,物品i的重量为wi,价值为 ...

  8. HDU1248 寒冰王座【0/1背包+DP】

    寒冰王座 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. 动态规划算法初步(6)——0/1 背包

    动态规划算法初步(6) 例题五:0/1 背包(背包型) 题目: 一个旅行者有一个最多能装m公斤物品的背包,现在有n件物品,它们的重量分别是w1,w2,-,wn,它们的价值分别为c1,c2,-,cn.若 ...

  10. 【ICPC-283】hdu 2126 Buy the souvenirs(二维0/1背包)

    点击打开链接hdu2126 思路: 二维0/1背包 分析: 1 题目给定n个物品的价钱和m的钱,问最多能买到的物品数有几种方案. 2 很明显就可以写出状态转移方程dp[i][j][k]表示的是前i个物 ...

最新文章

  1. 反射 -- 通过字符串操作对象中的成员
  2. [正则表达式]文本框输入内容控制
  3. 四、数据仓库和Hive环境搭建
  4. Docker小白到实战之Docker Compose在手,一键足矣
  5. Java文件合并变得语义化
  6. 【转】WCF请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back)
  7. python数列求和程序_python实现有趣的数学逻辑程序
  8. 马斯克非常有信心:SpaceX将在2026年前让人类登陆火星
  9. 金三银四大厂面经总结,java模块化打包
  10. Windows python pip换源不生效(window11系统),以及pip下载库包报错 because normal site-packages is not writeable
  11. Linux:Linux下进程间通信方式的学习
  12. 在私有组中将项目可见性从私有更改为内部导致500错误
  13. TX2 外接硬盘,并随启动自动挂载
  14. 【leetcode刷题】[简单]441. 排列硬币(arranging coins)-java
  15. 【GDScript】保存/加载物品装备数据
  16. 数据中台各种架构图大全
  17. foreign 磁盘阵列_X3650M4 磁盘阵列
  18. 【C++】全局变量定义在哪里合适
  19. VerilogHDL二分频代码
  20. linux服务器查询java线程占用的资源

热门文章

  1. IBM Watson:用人工智能提升美国零售业消费体验
  2. Javascript事件集
  3. CrazePony飞行器--通信部分介绍【转】
  4. .NET 3.5 中WCF客户端代理性能改进以及最佳实践
  5. 微软ASP.NET MVC Beta版本发布
  6. 异构系统数据备份解决方案
  7. __init__()
  8. 【leetcode】654. Maximum Binary Tree
  9. 计算机图形学----基于3D图形开发技术 (韩正贤 著)
  10. Linux基础第一周