首页 > 其他分享 >分支限界法解01背包问题

分支限界法解01背包问题

时间:2023-05-01 21:57:45浏览次数:41  
标签:01 PT level int double rightNode 限界 leftNode 法解

#include <iostream>
using namespace std;
#define MAX 100
struct Node {
    int isVisit;//记录节点是否被扩展
    double w;
    double v;
    int level; //记录节点所在的层次
    double ub; //上界
    Node* parent; //父节点
};

double maxValue = 0;
Node* PT[MAX];

Node* maxofPT(int count) { //count代表PT现在有的节点数量,PT数组最后一个节点的下标
    double max = 0; //找最大值
    int r = -1; //r记录找到的最大值对应的PT的下标
    for (int i = 0; i <= count; i++) {
        if (PT[i]->ub > max && PT[i]->isVisit == 0) {
            max = PT[i]->ub;
            r = i;
        }
    }
    PT[r]->isVisit = 1;//即将被扩展
    return PT[r];
}

Node* bestLeaf(int count, int n) {//叶子节点就是所求解的节点
    double max = 0;
    int r = -1;
    for (int i = 0; i <= count; i++) {
        if (PT[i]->ub>max&&PT[i]->level == n) {
            max = PT[i]->ub;
            r = i;
        }
    }
    return PT[r];
}

int* knapsack(double* w, double* v, int n, int capacity) {
    //int x[n]; 这样写会报错“表达式必须具有常量值”
    int* x = (int*)malloc(sizeof(int) * n);//申请一个数组存储最优解
    int count = 0;//PT中现在节点的下标是0
    double lb = 0;//下界值初始化为0
    double weight = 0;//背包中现在装的物品容量为0
    //初始化PT[0]
    Node* initN = (Node*)malloc(sizeof(Node) * 1);
    initN->isVisit = 0;
    initN->v = 0;
    initN->w = 0;
    initN->level = 0;
    initN->ub= capacity*(v[0]/w[0]); //初始上界值
    initN->parent = NULL;
    PT[count] = initN;
    //贪心法求下界
    for (int i = 0; i < n; i++) {
        if (weight + w[i] <= capacity) {
            weight += w[i];
            lb += v[i];
        }
    }
    // 选择扩展节点、剪枝、更新ub的过程如下
    Node* expandNode = (Node*)malloc(sizeof(Node) * 1);
    Node* bestNode = (Node*)malloc(sizeof(Node) * 1);
    while (1) {
        //从PT表中选择一个具有最大上界的节点作为扩展节点
        //cout << "进入循环1次" << endl;
        Node* leftNode = (Node*)malloc(sizeof(Node) * 1); //左边节点
        Node* rightNode = (Node*)malloc(sizeof(Node) * 1); //右边节点
        expandNode = maxofPT(count);
        if (expandNode->level != n) {//如果expandNode->level==n,说明已经是叶子节点,不用再算了
            //计算左节点
            leftNode->isVisit = 0;
            leftNode->v = expandNode->v + v[expandNode->level];
            leftNode->w = expandNode->w + w[expandNode->level];
            leftNode->level = expandNode->level + 1;
            if (leftNode->level != n) {
                leftNode->ub = leftNode->v +(capacity- leftNode->w)* v[leftNode->level] / w[leftNode->level];
            }
            else {
                leftNode->ub = leftNode->v;
            }
            leftNode->parent = expandNode;
            //加入PT表
            if (leftNode->w <= capacity) {
                PT[++count] = leftNode;
            }
            //计算右节点
            rightNode->isVisit = 0;
            rightNode->v = expandNode->v;
            rightNode->w = expandNode->w;
            rightNode->level = expandNode->level + 1;
            if (rightNode->level != n) {
                rightNode->ub = rightNode->v + (capacity - rightNode->w) * v[rightNode->level] / w[rightNode->level];
            }
            else {
                rightNode->ub = rightNode->v;
            }
            rightNode->parent = expandNode;
            //加入PT表
            if (rightNode->w <= capacity) {
                PT[++count] = rightNode;
            }
        }
        else {
            break;
        }
    }//while
    bestNode = bestLeaf(count, n);//找到解
    maxValue = bestNode->v;
    //回溯法找到物品选择情况
    for (int i = n-1; i >= 0; i--) {
        if (bestNode->v == bestNode->parent->v) {
            x[i] = 0; 
        }
        else {
            x[i] = 1;
        }
        bestNode = bestNode->parent;//向上一层回溯
    }
    return x;
}
int main() {
    double w[]={2,2,3,1,5,2};
    double v[]={2,3,1,5,4,3};
    int c = 10;
    int n = 6;
    int* ans = (int*)malloc(sizeof(int) * n);
    ans = knapsack(w, v, n, c);
    cout << "最大价值: " << maxValue << endl;
    cout << "最优解" << endl;
    for (int i = 0; i < n; i++) {
        cout << ans[i] << endl;
    }
    system("pause");
    return 0;
}

 

标签:01,PT,level,int,double,rightNode,限界,leftNode,法解
From: https://www.cnblogs.com/Jocelynn/p/17367052.html

相关文章

  • 分支限界法解TSP问题
    #include<iostream>#include<queue>#defineINF1e7#defineMAX100usingnamespacestd;intm[MAX][MAX];//存储城市间的代价intbestPath[MAX];//存储最优路径intbestCost=1e7;//存储最小代价intcityNumber;//城市数目//排列树的节点定义structNode{......
  • P5336 [THUSC2016]成绩单
    题意:期末考试结束了,班主任L老师要将成绩单分发到每位同学手中。L老师共有\(n\)份成绩单,按照编号从\(1\)到\(n\)的顺序叠放在桌子上,其中编号为\(i\)的的成绩单分数为\(W_i\)。成绩单是按照批次发放的。发放成绩单时,L老师会从当前的一叠成绩单中抽取连续的一段,让这......
  • 2023-05-01:给你一个整数 n , 请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1
    2023-05-01:给你一个整数n,请你在无限的整数序列[1,2,3,4,5,6,7,8,9,10,11,...]中找出并返回第n位上的数字。1<=n<=2^31-1。输入:n=11输出:0解释:第11位数字在序列1,2,3,4,5,6,7,8,9,10,11,...里是0,它是10的一部分。答案2023-05-01:......
  • 2017年计算机应用专业学术硕士毕业时的部分简历——“胡编内容版本”
      项目经验:硕士期间曾参与教育部人文社会科学研究青年基金,“轻量级数据集成环境下基于语义元数据的商务智能实现技术研究“。在该项目使用100台浪潮英信服务器对运行环境进行假设,采用Hadoop大数据处理框架对1TB的语言文本资料进行自然语言分析和处理,并采用yarn架构对资源......
  • 2018年-前端日记
    2018年4月份2018-04-25userAgent相关:判断微信内置浏览器的UserAgent2018-04-26前端相关:流程图制作工具:ProcessOnapi方法的浏览器兼容性问题,可以在这个网站上看:https://caniuse.com/CSS3的兼容性问题,不一定要使用-webkit-,-moz-,-o-,-ms-等私有前缀。可以使用Po......
  • 2019-推荐文章
    前言记录平时遇到的优质技术文章,按时间先后排序。内容2019-05-11《博客园美化教程大集合----极致个性化你的专属博客(超详细,看这篇就够了)》网上写图文教程的人,还真是贴心。2019-09-06https://www.yuque.com/sxc/front/kvokg4作者在语雀上的系列文章,都值得一看。2019-1......
  • 2019年-前端日记
    2019-04-02Vue屏幕宽度自适应:https://blog.csdn.net/qq_25386583/article/details/77161478https://blog.csdn.net/xuaner8786/article/details/815652192019-04-07控制iframe中的页面只显示一部分:https://blog.csdn.net/iteye_18722/article/details/819185632019-04-09......
  • 2018-推荐文章
    积累平时看到的一些好的前端文章。记录平时遇到的优质技术文章,按时间先后排序。2017-01-20阿里9年,我总结的前端架构演进3大阶段及团队管理心法伟明的推荐,说是对前端开发的价值观形成有良好的影响。2017-07-13前端开发面试题在逛公众号「前端大全」的时候发现的,然后顺......
  • P3592 [POI2015] MYJ
    题目描述有\(n\)家洗车店从左往右排成一排,每家店都有一个正整数价格\(p_i\)。有\(m\)个人要来消费,第\(i\)个人会驶过第\(a_i\)个开始一直到第\(b_i\)个洗车店,且会选择这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于\(c_i\),那么这个人就不洗车了。......
  • [oeasy]python0145_版本控制_git_备份还原
    git版本控制回忆上次内容上次我们了解了try的完全体try尝试运行 except发现异常时运行的代码块 else没有发现异常时运行的代码块 finally无论是否发现异常最终都要运行的代码块  ​ 添加图......