博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 实现整数线性规划:分枝定界法(Branch and Bound)
阅读量:7181 次
发布时间:2019-06-29

本文共 3847 字,大约阅读时间需要 12 分钟。

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

from scipy.optimize import linprogimport numpy as npimport mathimport sysfrom queue import Queueclass 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()

运行结果截图:

1331521-20190312220304002-1439582153.png

转载于:https://www.cnblogs.com/gscnblog/p/10520008.html

你可能感兴趣的文章
如何使用cocos2d制作基于tile地图的游戏教程:第一部分
查看>>
SVN的版本日期
查看>>
圆满完成性能测试诊断分析与优化周末班培训课程!
查看>>
C# 通过消息捕获处理窗体最大化/最小化
查看>>
metabase docker-compose 运行说明
查看>>
C# ToShortDateString() ToString() 设置日期格式的区别
查看>>
HDU-1016 Prime Ring Problem DFS
查看>>
MOSS 2007 入门 : 站点定义和站点模板
查看>>
网页性能优化{雅虎[转载]}
查看>>
CentOS6.2下搭建LVS(DR)+Keepalived实现高性能高可用负载均衡
查看>>
强制旋转iPhone界面
查看>>
最近琢磨出了个测试数据的小技巧
查看>>
vector-list-deque(转)
查看>>
linux 设置时间 date命令
查看>>
键盘设备三星在Android上的改进对Developer的影响
查看>>
分区视图(转载)
查看>>
高性能MySql进化论(一):数据类型的优化_上
查看>>
算法起步之Kruskal算法
查看>>
昨天帮同学的学校写了首校歌
查看>>
Oracle 监听器无法启动(TNS-12555,TNS-12560,TNS-00525)
查看>>