2018-2019年01背包分支限界.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
01背包分支限界 思想: 借助大顶堆来实现优先队列,构造大顶堆(按优先队列中所能达到的最大价值来构造这个大顶堆),实现对堆中元素的插入和删除;在回溯法的基础上改进,首先对物品按单位权重非递减排序,堆中存放的是每一个当前物品所能达到的情况: 1. 将第一个单位权重最大的物品插入大顶堆中,并用回溯法中计算边界条件的函数计算出该物品放入背包时所能达到的最大价值,用这一队列最后一个结点记录下当前得到的队列的情况,它可以得到的最大值(double型),用它该取的下一层次号,所达到的最大价值,所占用背包的体积; 2.如果物品层次号(从0开始)小于总个数,取出堆顶元素,对将要遍历到的这一层次上的物品判断选择取与不取的情况.若已经占用的体积+该物品的体积不超过背包体积,则该物品可以放入,即可以是左儿子结点,isLchild=true,将这一结点加入优先队列并放入大顶堆中;若右子树可能存在最优解,isLchild=false,即不放该物品时可能达到的最大价值(double型变量)=放入该物品时当前背包达到的最优解,则也将这一结点加入优先队列中并放入大顶堆中; 3. 重复步骤2. 感觉算法比较费力,对于01背包来说,由于不满足贪心的性质,所以分支限界在构造好了堆的前提下,它要比回溯法好. 代码: 头文件: 主要为大顶堆的构造,大顶堆中元素的插入,删除; 插入时:先将要插入的结点放入堆中最后一个元素的位置,然后自下向上调整. 删除时:因为当取出了堆顶元素后,需要对堆中剩余元素调整(堆从标号1开始).将堆中最后一个元素放在堆顶的位置,然后自上向下调整成为一个新的大顶堆. #define header #includeiostream using namespace std; const int MAXN=0x0fffff; typedef struct Node { Node * par; bool isLchild; }; typedef struct HeapNode { Node * par;//指向此优先队列中所包涵的所有结点 double cp,cw;//当前达到的价值,重量 double up;//此优先队列所能达到的最大价值 int level;//它所处的层次 }*HP; typedef struct Heap { int hsize;//堆中元素个数 HeapNode * heapnodes;//堆中存放可能的解 }*BigHeap;//用大顶堆来实现的优先队列 BigHeap bigHeap; HeapNode GetMax(int i)//取出一个最大结点,并向下调整 { HeapNode tempNode, maxNode=bigHeap-heapnodes[i];//堆从1开始 tempNode=bigHeap-heapnodes[i]=bigHeap-heapnodes[bigHeap-hsize--];//将最后一个结点提升,并使hsize-1 int j; for(j=i1;j=bigHeap-hsize;j=1)//开始向下调整 { if(jbigHeap-hsizebigHeap-heapnodes[j].upbigHeap-heapnodes[j+1].up) ++j;//j为最大的那个结点 if(tempNode.up=bigHeap-heapnodes[j].up) break; bigHeap-heapnodes[i]=bigHeap-heapnodes[j];//子结点上移 i=j; } bigHeap-heapnodes[i]=tempNode; return maxNode; } void InsertNode(HeapNode node) //插入一个新结点,并自下向上调整 { int i; for(i=++bigHeap-hsize;bigHeap-heapnodes[i/2].upnode.up;i=1) bigHeap-heapnodes[i]=bigHeap-heapnodes[i/2];//父结点下移 bigHeap-heapnodes[i]=node; } BigHeap init(int n) { bigHeap=(BigHeap)malloc(sizeof Heap); bigHeap-hsize=0; bigHeap-heapnodes=(HeapNode *)malloc((n+1)*sizeof HeapNode); bigHeap-heapnodes[0].up=MAXN; return bigHeap; } Main函数: 基本上和回溯法中的大部分代码相同,不同的是用堆来实现优先队列.

文档评论(0)

文库创作者 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档