运筹学基础(二):求解整数规划的分支定界法(branch and bound)

算法思想

分支定界法是求解整数规划问题的“鼻祖型”算法了,其基本步骤是:

  1. 先将整数规划问题松弛成线性规划问题,并求出最优解;
  2. 慢慢砍掉那些非整数的搜索空间,将原问题分支成一个个子问题;
  3. 求解这些子问题最优解,并缩紧最优解的上下界,最终求得整数最优解。

上下界更新的原则:

  • 上界:子问题最优解的最大值作为新的上界;
  • 下界:子问题最优整数解的最大值作为新的下界。

一个例子

在这里插入图片描述
step 1: 松弛为线性规划问题B并求解,进行初始定界;

x 1 = 4.81 x_1 = 4.81 x1=4.81, x 2 = 1.82 x_2 = 1.82 x2=1.82, z 0 = 356 z_0 = 356 z0=356
因此,初始定界为 0 ≤ Z ∗ ≤ 356 0 \leq Z^* \leq 356 0Z356

step 2:基于非整数变量分支;
我们选择 x 1 = 4.81 x_1 = 4.81 x1=4.81进行分支(选择 x 2 x_2 x2也可以),如下图所示。
在这里插入图片描述
在图上看就是下面这个效果,切割了一部分非整数的可行域:
在这里插入图片描述
step 3: 分别求解子问题B1和B2的解(只是将问题B中 x 1 x_1 x1的约束范围改变一下求解),并重新定界;
在这里插入图片描述
step 4: 继续对问题 B 1 B_1 B1分支为 B 3 B_3 B3 B 4 B_4 B4,并且求解,定界
在这里插入图片描述

step 4: 继续对问题 B 2 B_2 B2分支为 B 5 B_5 B5 B 6 B_6 B6,并且求解,定界
在这里插入图片描述
step 4: 所有节点都已经搜索完,找到最优解340,停止计算。
在这里插入图片描述

参考文档

  1. 【运筹学】-整数线性规划(一)(分支定界法)
  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分枝定界法是一种求解整数线性规划问题的常用方法。该方法的基本思想是将整数线性规划问题不断分解成子问题,然后对每个子问题进行求解,直到得到最优解。 Python 实现整数线性规划的分枝定界法,可以基于 Python 的优化库 `PuLP`。以下是一个简单的示例代码: ```python from pulp import * # 定义整数线性规划问题 prob = LpProblem("Integer Linear Programming", LpMinimize) # 添加变量 x1 = LpVariable("x1", lowBound=0, cat='Integer') x2 = LpVariable("x2", lowBound=0, cat='Integer') # 添加目标函数 prob += 3*x1 + 4*x2 # 添加约束条件 prob += 2*x1 + x2 >= 3 prob += x1 + 2*x2 >= 3 # 求解 prob.solve() # 输出结果 print("Status:", LpStatus[prob.status]) print("Minimum value:", value(prob.objective)) print("Optimal solution:") for v in prob.variables(): print(v.name, "=", v.varValue) ``` 以上代码是一个简单的整数线性规划问题的求解示例,其中定义了两个变量 `x1` 和 `x2`,并添加了目标函数和两个约束条件。通过 `prob.solve()` 方法进行求解,并输出最优解及对应的变量取值。 分枝定界法的实现,可以通过递归地将当前问题分解成两个子问题,并对子问题进行求解,直到得到最优解。在每次分解时,需要对当前解的上下界进行计算,并通过 `prob +=` 方法添加上下界约束条件。具体实现可以参考以下示例代码: ```python from pulp import * # 定义整数线性规划问题 prob = LpProblem("Integer Linear Programming", LpMinimize) # 添加变量 x1 = LpVariable("x1", lowBound=0, cat='Integer') x2 = LpVariable("x2", lowBound=0, cat='Integer') # 添加目标函数 prob += 3*x1 + 4*x2 # 添加初始约束条件 prob += 2*x1 + x2 >= 3 prob += x1 + 2*x2 >= 3 def solve_branch_and_bound(prob): # 求解当前问题 prob.solve() # 获取当前解的上下界 upper_bound = value(prob.objective) lower_bound = upper_bound # 分解问题并求解 for v in prob.variables(): # 向上取整 upper_value = int(v.varValue) + 1 # 向下取整 lower_value = int(v.varValue) # 分解为两个子问题 prob1 = LpProblem("Integer Linear Programming", LpMinimize) prob2 = LpProblem("Integer Linear Programming", LpMinimize) # 添加变量 x1 = LpVariable("x1", lowBound=0, cat='Integer') x2 = LpVariable("x2", lowBound=0, cat='Integer') # 添加目标函数 prob1 += 3*x1 + 4*x2 prob2 += 3*x1 + 4*x2 # 添加约束条件 for c in prob.constraints: prob1 += c prob2 += c # 添加上下界约束条件 if v.name == 'x1': prob1 += x1 >= upper_value prob2 += x1 <= lower_value elif v.name == 'x2': prob1 += x2 >= upper_value prob2 += x2 <= lower_value # 求解子问题 prob1.solve() prob2.solve() # 计算上下界 if value(prob1.objective) < value(prob2.objective): upper_bound = min(upper_bound, value(prob1.objective)) else: upper_bound = min(upper_bound, value(prob2.objective)) lower_bound = max(lower_bound, value(prob1.objective), value(prob2.objective)) # 判断是否达到最优解 if upper_bound == lower_bound: return upper_bound # 分解子问题并求解 for v in prob.variables(): # 向上取整 upper_value = int(v.varValue) + 1 # 向下取整 lower_value = int(v.varValue) # 分解为两个子问题 prob1 = LpProblem("Integer Linear Programming", LpMinimize) prob2 = LpProblem("Integer Linear Programming", LpMinimize) # 添加变量 x1 = LpVariable("x1", lowBound=0, cat='Integer') x2 = LpVariable("x2", lowBound=0, cat='Integer') # 添加目标函数 prob1 += 3*x1 + 4*x2 prob2 += 3*x1 + 4*x2 # 添加约束条件 for c in prob.constraints: prob1 += c prob2 += c # 添加上下界约束条件 if v.name == 'x1': prob1 += x1 >= upper_value prob2 += x1 <= lower_value elif v.name == 'x2': prob1 += x2 >= upper_value prob2 += x2 <= lower_value # 判断是否需要继续分解 if min(value(prob1.objective), value(prob2.objective)) > upper_bound: continue # 递归求解子问题 if value(prob1.objective) <= value(prob2.objective): upper_bound = min(upper_bound, solve_branch_and_bound(prob1)) else: upper_bound = min(upper_bound, solve_branch_and_bound(prob2)) return upper_bound # 求解 optimal_value = solve_branch_and_bound(prob) # 输出结果 print("Minimum value:", optimal_value) print("Optimal solution:") for v in prob.variables(): print(v.name, "=", v.varValue) ``` 以上代码实现了整数线性规划的分枝定界法,其中 `solve_branch_and_bound` 方法用于递归地分解问题并求解。在每次分解时,都会计算当前解的上下界,并根据上下界约束条件进行分解。通过递归求解子问题,最终得到最优解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值