python的pulp库解决线性规划问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python的pulp库解决线性规划问题相关的知识,希望对你有一定的参考价值。

参考技术A 战术决策问题,某战略轰炸机队指挥官得到了摧毁敌方坦克生产能力的命令. 根据情报, 敌方有四个生产坦克部件的工厂, 位于不同的地方. 只要破坏其中任一工厂的生产设施就可以有效地停止敌方坦克的生产. 根据分析, 执行该任务的最大因素是汽油短缺, 为此项任务只能提供48000加仑汽油.而对于任何一种轰炸机来说, 不论去轰炸哪一个工厂都必须有足够往返的燃料和100加仑备余燃料.该轰炸机队现有重型和中型两种轰炸机, 其燃油消耗量及数量见下表
编号 飞机类型 每千米耗油量 飞机驾数
1 重型 1/2 48
2 中型 1/3 32
各工厂距离空军基地的距离和摧毁目标的概率见下表
工厂 距离/千米 摧毁目标概率(重型/中型)
1 450 0.10 0.08
2 480 0.20 0.16
3 540 0.15 0.12
4 600 0.25 0.20

所以应该去2号工厂1驾重型和1驾中型机,去4号工厂45驾重型机和31驾中型机。

Python数学建模系列:规划问题之整数规划

前言

Hello!小伙伴!
非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~
 
自我介绍 ଘ(੭ˊᵕˋ)੭
昵称:海轰
标签:程序猿|C++选手|学生
简介:因C语言结识编程,随后转入计算机专业,有幸拿过一些国奖、省奖…已保研。目前正在学习C++/Linux/Python
学习经验:扎实基础 + 多做笔记 + 多敲代码 + 多思考 + 学好英语!
 
初学Python 小白阶段
文章仅作为自己的学习笔记 用于知识体系建立以及复习
题不在多 学一题 懂一题
知其然 知其所以然!
 
本文仅从Pyhton如何解决建模问题出发
未对建模思路等进行深一步探索

整数规划

整数规划的模型与线性规划基本相同,只是额外增加了部分变量为整数的约束

整数规划求解的基本框架是分支定界法,首先去除整数约束得到"松弛模型"。使用线性规划的方法求解。

若有某个变量不是整数,在松弛模型.上分别添加约束:x≤floor(A)和x≥ceil(A),然后再分别求解,这个过程叫做分支。当节点求解结果中所有变量都是整数时。停止分支。这样不断迭代,形成了一颗树。

所谓定界,指的是叶子节点产生后,相当于给问题定了一个下界。之后在求解过程中一旦某个节点的目标函数值小于这个下界,那就直接pass,不再进行分支了;每次新产生叶子节点,则更新下界。

例题

m i n z = 3 x 1 + 4 x 2 + x 3 min \\quad z = 3x_1 + 4x_2 + x_3 minz=3x1+4x2+x3 的最小值
m i n z = 3 x 1 + 4 x 2 + x 3 s . t . = { x 1 + 6 x 2 + 2 x 3 > = 5 2 x 1 > = 3 x 1 , x 2 , x 3 > = 0 ( 且 都 为 整 数 ) min \\quad z = 3x_1 + 4x_2 + x_3\\\\ s.t. = \\begin{cases} x_1 + 6x_2 + 2x_3 >= 5 \\\\ 2x_1 >= 3\\\\ x_1,x_2,x_3 >=0(且都为整数) \\end{cases} minz=3x1+4x2+x3s.t.=x1+6x2+2x3>=52x1>=3x1,x2,x3>=0()

方法一:分支定界法(使用scipy库)

Demo代码

# 运行环境:Vs Code
import math
from scipy.optimize import linprog
import sys

def integerPro(c, A, b, Aeq, beq,t=1.0E-8):
    res = linprog(c, A_ub=A, b_ub=b, A_eq=Aeq, b_eq=beq)
    bestVal = sys.maxsize
    bestX = res.x
    if not(type(res.x) is float or res.status != 0): 
        bestVal = sum([x*y for x,y in zip(c, bestX)])
    if all(((x-math.floor(x))<=t or (math.ceil(x)-x)<=t) for x in bestX):
        return (bestVal,bestX)
    else:
        ind = [i for i, x in enumerate(bestX) if (x-math.floor(x))>t and (math.ceil(x)-x)>t][0]
        newCon1 = [0]*len(A[0])
        newCon2 = [0]*len(A[0])
        newCon1[ind] = -1
        newCon2[ind] = 1
        newA1 = A.copy()
        newA2 = A.copy()
        newA1.append(newCon1)
        newA2.append(newCon2)
        newB1 = b.copy()
        newB2 = b.copy()
        newB1.append(-math.ceil(bestX[ind]))
        newB2.append(math.floor(bestX[ind]))
        r1 = integerPro(c, newA1, newB1, Aeq, beq)
        r2 = integerPro(c, newA2, newB2, Aeq, beq)
        if r1[0] < r2[0]:
            return r1
        else:
            return r2
c = [3,4,1]
A = [[-1,-6,-2],[-2,0,0]]
b = [-5,-3]
Aeq = [[0,0,0]]
beq = [0]
print(integerPro(c, A, b, Aeq, beq))

运行结果

(8.000000000001586, array([2., 0., 2.]))
# 或者
(8.000000000001586, array([2.00000000e+00, 1.83247535e-13, 2.00000000e+00]))

方法二:使用pulp库进行求解

只需要在设置变量的时候

设置参数cat='Integer' 即可

  • Continuous:连续
  • Binary:0 或 1
  • Integer:整数

Demo代码

import pulp as pp

# 参数设置
c = [3,4,1]        #目标函数未知数前的系数

A_gq = [[1,6,2],[2,0,0]]   # 大于等于式子 未知数前的系数集合 二维数组 
b_gq = [5,3]         # 大于等于式子右边的数值 一维数组


# 确定最大最小化问题,当前确定的是最小化问题
m = pp.LpProblem(sense=pp.LpMinimize)

# 定义三个变量放到列表中 生成x1 x2 x3
x = [pp.LpVariable(f'x{i}',lowBound=0,cat='Integer') for i in [1,2,3]]

# 定义目标函数,并将目标函数加入求解的问题中 
m += pp.lpDot(c,x) # lpDot 用于计算点积 

# 设置比较条件
for i in range(len(A_gq)):# 大于等于
    m += (pp.lpDot(A_gq[i],x) >= b_gq[i])

# 求解
m.solve()

# 输出结果
print(f'优化结果:{pp.value(m.objective)}')
print(f'参数取值:{[pp.value(var) for var in x]}')

运行结果

优化结果:8.0
参数取值:[2.0, 0.0, 2.0]

结语

学习来源:B站及其课堂PPT,对其中代码进行了复现

链接:https://www.bilibili.com/video/BV12h411d7Dm?from=search&seid=5685064698782810720

文章仅作为学习笔记,记录从0到1的一个过程

希望对您有所帮助,如有错误欢迎小伙伴指正~

我是 海轰ଘ(੭ˊᵕˋ)੭

如果您觉得写得可以的话,请点个赞吧

谢谢支持 ❤️

以上是关于python的pulp库解决线性规划问题的主要内容,如果未能解决你的问题,请参考以下文章

Python数模笔记-PuLP库线性规划进阶

Python数模笔记-PuLP库线性规划实例

pulp求解简单线性规划问题

如何使用Pulp Gekko和Scipy软件包修复具有不同结果的代码以解决线性优化问题?

python 之pulp 线性规划介绍及举例

最优解问题——PuLP解决线性规划问题