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

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)的更多相关文章

  1. 分枝定界的matlab实现

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

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

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

  3. yalmip + lpsolve + matlab 求解混合整数线性规划问题(MIP/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源代码--整数对象(PyIntObject)的内存池

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

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

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

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

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

随机推荐

  1. 一道简单的CTF登录题题解

    一.解题感受 这道题50分,在实验吧练习场算比较高分,而且通过率只有14%,比较低的水平. 看到这两个数据,一开始就心生惬意,实在不应该呀! 也是因为心态原因,在发现test.php之后,自以为在SQ ...

  2. cenos7上部署python3环境以及mysqlconnector2.1.5

    本机的python2不要管他,因为可能有程序依赖目前的python2环境,比如yum!!!!! 一.安装python3依赖环境: yum -y install zlib-devel bzip2-dev ...

  3. js+jquery创建元素

    例:创建如下标签: <a id="baidu" class="link" name="baidu">这是一个链接</a&g ...

  4. 1x1的卷积核有什么作用

    信道压缩~跨~信~减 一.1 X 1的卷积核作用 所谓信道压缩,Network in Network是怎么做到的? 对于如下的二维矩阵,做卷积,相当于直接乘以2,貌似看上去没什么意义: 但是,对于下面 ...

  5. Maven 学习总结 (七) 之 灵活构建

    一个优秀的构建系统必须足够灵活,他应该能够让项目在不同的环境下都能成功地构建.Maven为支持项目的灵活性,内置了三大特性,即属性.Profile和资源过滤. Maven属性 通过<proper ...

  6. 轻量Pythonweb - flask+jinja2

    后台代码 MVC from flask import Flask,request,render_template app = Flask(__name__) @app.route('/',method ...

  7. python常用的内置函数哈哈

    python常用的内置函数集合做一个归类用的时候可以查找 abs 返回数字x的绝对值或者x的摸 all (iterable)对于可迭代的对象iterable中所有元素x都有bool(x)为true,就 ...

  8. Makefile模板(C++)

    Makefile的C++的一个模板,可用于根据不同源文件,生成多个可执行文件 . CC = g++ DIR_INC = ./include DIR_SRC = ./src DIR_OBJ = ./ob ...

  9. MySQL命令行查询乱码解决方法

    转自Agoly的博客,原文链接https://www.cnblogs.com/qmfsun/p/4846467.html 感谢博主Agoly这篇文章说的很详细很透彻. MySQL会出现中文乱码的原因不 ...

  10. vue 前端框架

    什么是vue.js 1.vue是目前最火的一个前端框架,react 是最流行的前端框架(react除了开发网站,还可以开发手机APP,vue语法也是可以进行手机app开发的,需要借助于weex) 2. ...