Python 实现整数线性规划:分枝定界法(Branch and Bound)

时间:2022-12-11 19:08:35

今天做作业,要实现整数线性规划的分枝定界法算法。找了一些网上的博客,发现都很屎,感觉自己写的这个比较清楚、规范,所以在此记录。如有错误,请指正。

from scipy.optimize import linprog
import numpy as np
import math
import sys
from queue import Queue class ILP():
def __init__(self, c, A_ub, b_ub, A_eq, b_eq, bounds):
# 全局参数
self.LOWER_BOUND = -sys.maxsize
self.UPPER_BOUND = sys.maxsize
self.opt_val = None
self.opt_x = None
self.Q = Queue() # 这些参数在每轮计算中都不会改变
self.c = -c
self.A_eq = A_eq
self.b_eq = b_eq
self.bounds = bounds # 首先计算一下初始问题
r = linprog(-c, A_ub, b_ub, A_eq, b_eq, bounds) # 若最初问题线性不可解
if not r.success:
raise ValueError('Not a feasible problem!') # 将解和约束参数放入队列
self.Q.put((r, A_ub, b_ub)) def solve(self):
while not self.Q.empty():
# 取出当前问题
res, A_ub, b_ub = self.Q.get(block=False) # 当前最优值小于总下界,则排除此区域
if -res.fun < self.LOWER_BOUND:
continue # 若结果 x 中全为整数,则尝试更新全局下界、全局最优值和最优解
if all(list(map(lambda f: f.is_integer(), res.x))):
if self.LOWER_BOUND < -res.fun:
self.LOWER_BOUND = -res.fun if self.opt_val is None or self.opt_val < -res.fun:
self.opt_val = -res.fun
self.opt_x = res.x continue # 进行分枝
else:
# 寻找 x 中第一个不是整数的,取其下标 idx
idx = 0
for i, x in enumerate(res.x):
if not x.is_integer():
break
idx += 1 # 构建新的约束条件(分割
new_con1 = np.zeros(A_ub.shape[1])
new_con1[idx] = -1
new_con2 = np.zeros(A_ub.shape[1])
new_con2[idx] = 1
new_A_ub1 = np.insert(A_ub, A_ub.shape[0], new_con1, axis=0)
new_A_ub2 = np.insert(A_ub, A_ub.shape[0], new_con2, axis=0)
new_b_ub1 = np.insert(
b_ub, b_ub.shape[0], -math.ceil(res.x[idx]), axis=0)
new_b_ub2 = np.insert(
b_ub, b_ub.shape[0], math.floor(res.x[idx]), axis=0) # 将新约束条件加入队列,先加最优值大的那一支
r1 = linprog(self.c, new_A_ub1, new_b_ub1, self.A_eq,
self.b_eq, self.bounds)
r2 = linprog(self.c, new_A_ub2, new_b_ub2, self.A_eq,
self.b_eq, self.bounds)
if not r1.success and r2.success:
self.Q.put((r2, new_A_ub2, new_b_ub2))
elif not r2.success and r1.success:
self.Q.put((r1, new_A_ub1, new_b_ub1))
elif r1.success and r2.success:
if -r1.fun > -r2.fun:
self.Q.put((r1, new_A_ub1, new_b_ub1))
self.Q.put((r2, new_A_ub2, new_b_ub2))
else:
self.Q.put((r2, new_A_ub2, new_b_ub2))
self.Q.put((r1, new_A_ub1, new_b_ub1)) def test1():
""" 此测试的真实最优解为 [4, 2] """
c = np.array([40, 90])
A = np.array([[9, 7], [7, 20]])
b = np.array([56, 70])
Aeq = None
beq = None
bounds = [(0, None), (0, None)] solver = ILP(c, A, b, Aeq, beq, bounds)
solver.solve() print("Test 1's result:", solver.opt_val, solver.opt_x)
print("Test 1's true optimal x: [4, 2]\n") def test2():
""" 此测试的真实最优解为 [2, 4] """
c = np.array([3, 13])
A = np.array([[2, 9], [11, -8]])
b = np.array([40, 82])
Aeq = None
beq = None
bounds = [(0, None), (0, None)] solver = ILP(c, A, b, Aeq, beq, bounds)
solver.solve() print("Test 2's result:", solver.opt_val, solver.opt_x)
print("Test 2's true optimal x: [2, 4]\n") if __name__ == '__main__':
test1()
test2()

运行结果截图:

Python 实现整数线性规划:分枝定界法(Branch and Bound)

Python 实现整数线性规划:分枝定界法(Branch and Bound)的更多相关文章

  1. 分枝定界的matlab实现

    function [optSolution,optValue,exists]=BranchBound(c,A,b) % 分支定界法 % 整数规划问题标准型 % min c'*x % s.t. % A* ...

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

    Outline 前言 Example-1 Example-2 运行说明 00 前言 前面一篇文章我们讲了branch and bound算法的相关概念.可能大家对精确算法实现的印象大概只有一个,调用求 ...

  3. yalmip &plus; lpsolve &plus; matlab 求解混合整数线性规划问题(MIP&sol;MILP)

    最近建立了一个网络流模型,是一个混合整数线性规划问题(模型中既有连续变量,又有整型变量).当要求解此模型的时候,发现matlab优化工具箱竟没有自带的可以求解这类问题的算法(只有bintprog求解器 ...

  4. Python 的整数与 Numpy 的数据溢出

    某位 A 同学发了我一张截图,问为何结果中出现了负数? 看了图,我第一感觉就是数据溢出了.数据超出能表示的最大值,就会出现奇奇怪怪的结果. 然后,他继续发了张图,内容是 print(100000*20 ...

  5. 统计学习方法与Python实现(二)——k近邻法

    统计学习方法与Python实现(二)——k近邻法 iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 1.定义 k近邻法假设给定一个训练数据集,其中的实例类别已定 ...

  6. Python中整数和浮点数

    Python支持对整数和浮点数直接进行四则混合运算,运算规则和数学上的四则运算规则完全一致. 基本的运算: 1 + 2 + 3 # ==> 6 4 * 5 - 6 # ==> 14 7.5 ...

  7. Python源代码--整数对象&lpar;PyIntObject&rpar;的内存池

    [背景] 原文链接:http://blog.csdn.net/ordeder/article/details/25343633 Python整数对象是不可变对象,什么意思呢?比如运行例如以下pytho ...

  8. Matlab 整数线性规划问题模型代码

    整数线性规划问题的基本内容 整数线性规划解决的是自变量在一定的线性约束条件下,使得线性目标函数求得最大值或者最小值的问题.其中自变量只能取整数.特别地,当自变量只能取0或者1时,称之为 0-1 整数规 ...

  9. 干货 &vert; 10分钟带你全面掌握branch and bound(分支定界)算法-概念篇

    00 前言 之前一直做启发式算法,最近突然对精确算法感兴趣了.但是这玩意儿说实话是真的难,刚好boss又叫我学学column generation求解VRP相关的内容.一看里面有好多知识需要重新把握, ...

随机推荐

  1. 解决OracleConnection ORA-1017 和 HRESULT&colon;0x8007000B 错误

    试图加载格式不正确的程序. (异常来自HRESULT:0x8007000B) 解决方案: IIS下 winform下: ORA-1017 错误

  2. 部署服务--NLB

    通过服务部署NLB,是对某一层(一层下面可以自定义VM实例数量)服务下的多台VM进行NLB,而不是对多个层进行NLB.需要先进行如下准备: 1.VM需要使用静态IP和静态MAC,所以需要先在进行NLB ...

  3. &lbrack;POJ 3635&rsqb; Full Tank&quest;

    题目 Description 已知每个点的加油站的油价单价(即点权),每条路的长度(边权). 有q个询问,每个询问包括起点s.终点e和油箱容量c. 问从起点走到终点的最小花费.如果不可达输出impos ...

  4. BZOJ4503 两个串 多项式 FFT

    题目传送门 - BZOJ4503 题意概括 给定两个字符串S和T,回答T在S中出现了几次,在哪些位置出现.注意T中可能有?字符,可以匹配任何字符. 题解 首先,假装你已经知道了这是一道$FFT$题. ...

  5. Js — CommonUtil

    一些js脚本的公用方法: 1:字符串根据给定的每行长度换行 2:比较两个时间的大小3:计算两个日期间相差的天数 1.字符串根据给定的每行长度换行 /** *words:原始字符串 *avg:每行字数 ...

  6. &lbrack;CentOS&lowbar;7&period;4&rsqb;Linux编译安装mono环境

    一 安装mono 安装过程: 下载mono安装源,配置,编译,安装,设置环境变量. # wget http://download.mono-project.com/sources/mono/mono- ...

  7. 吴裕雄 数据挖掘与分析案例实战(10)——KNN模型的应用

    # 导入第三方包import pandas as pd # 导入数据Knowledge = pd.read_excel(r'F:\\python_Data_analysis_and_mining\\1 ...

  8. iOS-----多线程之NSThread

    多线程 iOS平台提供了非常优秀的多线程支持,程序可以通过非常简单的方式来启动多线程,iOS平台不仅提供了NSThread类来创建多线程,还提供了GCD方式来简化多线程编程,提供了NSOperatio ...

  9. 用MVC5&plus;EF6&plus;WebApi 做一个小功能&lpar;三&rpar; 项目搭建

    一般一个项目开始之前都会有启动会,需求交底等等,其中会有一个环节,大讲特讲项目的意义,然后取一个高大上的项目名字,咱这是一个小功能谈不上项目,但是名字不能太小气了.好吧,就叫Trump吧.没有任何含义 ...

  10. python初步学习-python数据类型之strings&lpar;字符串&rpar;

    数据类型-字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号(''或者"")来创建字符串 var1 = 'Hello World!' var2 = "P ...