干货 | 10分钟搞懂branch and bound(分支定界)算法的代码实现附带java代码

Outline

  • 前言
  • Example-1
  • Example-2
  • 运行说明

00 前言

前面一篇文章我们讲了branch and bound算法的相关概念。可能大家对精确算法实现的印象大概只有一个,调用求解器进行求解,当然这只是一部分。其实精确算法也好,启发式算法也好,都是独立的算法,可以不依赖求解器进行代码实现的,只要过程符合算法框架即可。

只不过平常看到的大部分是精确算法在各种整数规划模型上的应用,为此难免脱离不了cplex等求解器。这里简单提一下。今天给大家带来的依然是branch and bound算法在整数规划中的应用的代码实现,所以还是会用到部分求解器的。

注:本文代码下载请关注公众号【程序猿声】,后台回复【bbcode】,不包括【】即可下载!

1240

01 Example-1

首先来看第一个代码实例,该代码求解的是整数优化的模型,关于branch and bound求解整数规划的具体原理就不再概述了,和上一篇文章差不多但是有所区别。代码文件层次如下:

1240

其中branch and bound算法主要部分在BnB_Guide.java这个文件。ExampleProblem.java内置了三个整数规划模型的实例。调用的是scpsolver这个求解器的wrapper,实际调用的还是lpsolver这个求解器用以求解线性松弛模型。下面着重讲讲BnB_Guide.java这个文件。

    public BnB_Guide(int demoProblem){
        
        example = new ExampleProblem(demoProblem);
        LinearProgram lp = new LinearProgram();
        lp = example.getProblem().getLP();
        solver = SolverFactory.newDefault();
        
        double[] solution = solver.solve(lp); // Solution of the initial relaxation problem
        int maxElement =  getMax(solution); // Index of the maximum non-integer decision variable's value
        if(maxElement == -1 ) // We only got integers as values, hence we have an optimal solution
            verifyOptimalSolution(solution,lp);
        else
            this.solveChildProblems(lp, solution, maxElement); // create 2 child problems and solve them
        
        printSolution();
        
    }

该过程是算法主调用过程:

  1. 首先变量lp保存了整数规划的松弛问题。
  2. 在调用求解器求解松弛模型以后,判断是否所有决策变量都是整数了,如果是,已经找到最优解。
  3. 如果不是,根据找出最大的非整数的决策变量,对该变量进行分支,solveChildProblems。

接着是分支子问题的求解过程solveChildProblems如下:

    public void solveChildProblems(LinearProgram lp, double[] solution ,int maxElement){

        searchDepth++;
        
        LinearProgram lp1 = new LinearProgram(lp);
        LinearProgram lp2 = new LinearProgram(lp);
        
        String constr_name = "c" + (lp.getConstraints().size() + 1); // Name of the new constr
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
分支定界算法是一种求解优化问题的算法,它通过将问题空间划分为多个子空间,并对每个子空间进行搜索,以找到最优解。 算法步骤如下: 1. 初始化最优解的上界,通常为一个较大的值,记为UB。 2. 初始化当前解为一个空解,记为X,当前解的下界为负无穷大,记为LB。 3. 选择一个子空间进行搜索。 4. 在当前子空间中生成一个候选解,记为Y。 5. 判断候选解Y是否可行,如果可行,则计算其目标函数值。 6. 如果Y的目标函数值小于UB,则更新UB为Y的目标函数值,并更新当前解X为Y。 7. 根据问题的特点和限制条件,计算候选解Y的下界LB。 8. 如果LB大于等于UB,则剪枝,结束当前子空间的搜索。 9. 如果LB小于UB,则继续划分当前子空间,重复步骤3-8。 10. 当所有子空间都被搜索完毕时,返回当前解X作为最优解。 下面是一个示例代码,用于求解0/1背包问题的分支定界算法: ```python def branch_and_bound_knapsack(values, weights, capacity): n = len(values) best_solution = [0] * n best_value = 0 def backtrack(i, current_value, current_weight, current_solution): nonlocal best_value, best_solution if i == n: if current_value > best_value: best_value = current_value best_solution = current_solution else: if current_weight + weights[i] <= capacity: current_solution[i] = 1 backtrack(i + 1, current_value + values[i], current_weight + weights[i], current_solution) current_solution[i] = 0 backtrack(i + 1, current_value, current_weight, current_solution) backtrack(0, 0, 0, [0] * n) return best_solution, best_value ``` 这段代码实现了一个递归的回溯函数`backtrack`,它会遍历所有可能的解空间。在每一步中,我们可以选择将第`i`个物品放入背包中或不放入背包中,根据当前的价值和重量进行更新。最终,函数返回最优解和最优值。 请注意,这只是一个简化的示例代码,实际应用中可能需要根据具体问题进行一些调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值