数学建模 - 线性规划入门:Gurobi + python

在工程管理、经济管理、科学研究、军事作战训练及日常生产生活等众多领域中,人们常常会遇到各种优化问题。例如,在生产经营中,我们总是希望制定最优的生产计划,充分利用已有的人力、物力资源,获得最大的经济效益;在运输问题中,我们总是希望设计最优的运输方案,在完成运输任务的前提下,力求运输成本最小等。针对优化问题的数学建模也是数学建模竞赛中一类比较常见的问题,这样的问题常常可以使用数学规划模型进行研究。

数学规划是运筹学的一个重要分支,而线性规划又是数学规划中一部分主要内容。很多实际问题都可以归结为“线性规划”问题。线性规划(Linear Programming,LP)有比较完善的理论基础和有效的求解方法,在实际问题中有极其广泛的应用。

一句话:在什么限制(约束)下变量取什么值可以让的目标最优。

分析:

  1. 求什么?3种产品的产量 – 决策变量
  2. 考虑什么条件?原来料不能用光 and 总加工时间得够用 – 约束条件
  3. 达到什么目标?使得利润最大 – 目标函数

产品的产量应收到某些条件的限制。首先,两种原材料每天的实际消耗量不能超过其可用数量,因此有

步骤:

  1. 分析问题,找出决策变量
  2. 根据问题给出的条件,找出决策变量必须满足的一组线性等式或者不等式约束,即为约束条件。
  3. 根据问题的目标,构造关于决策变量的一个线性函数,即为目标函数。

有了决策变量、约束条件和目标函数这3个要素之后,一个线性规划模型就建立起来了。

求解:

使用Gurobi求解器, Why Gurobi? 还是那句话:专业的事情专业的干

# 1.Gurobi版本
profit = [70, 50, 60]  # 各产品恒单位利润
MatA = [2, 4, 3]    # 各产品单位消耗的A原材料
MatB = [3, 1, 5]   # 各产品单位消耗的B原材料
time = [7, 3, 5]   # 各产品单位生产时间

resA = 150  # A原材料每天可用量
resB = 160   # B原材料每天可用量
available_time = 200  # 每天可用生产时间

from gurobipy import *
m = Model("maximize_profit") # 给模型起个名字
# 变量
x = m.addVars(3, vtype=GRB.CONTINUOUS, name="x")
# 目标
m.setObjective(sum(profit[i]*x[i] for i in range(3)), GRB.MAXIMIZE)
# 约束
m.addConstr(sum(MatA[i]*x[i] for i in range(3)) <= resA, "c0")
m.addConstr(sum(MatB[i]*x[i] for i in range(3)) <= resB, "c1")
m.addConstr(sum(time[i]*x[i] for i in range(3)) <= available_time,  "c2")

m.optimize()
print("-----------------------------------------------------------------")
print("最大化利润为: ", m.objVal, "元")
# 检查模型是否存在最优解
if m.status == GRB.OPTIMAL:
    # 输出每种产品的生产数量
    for i in range(3):
        print(f'产品{i+1} 生产数量: {x[i].x} 公斤')

根据结果答:生产A产品15.90公斤,B产品29.54公斤,不生产C产品时利润最大2590.90元

注:如果大家安装Gurobi失败,可以先用python的pulp库做替代。

PuLP 是一个开源的 Python 语言线性规划建模库。它提供了构建线性规划(LP)、整数规划(IP)以及混合整数规划(MIP)模型的能力。PuLP 不自带求解器,而是作为一个接口层,可以与多个第三方求解器结合使用,包括但不限于 COIN-OR 的 CBC、GLPK、Gurobi、CPLEX 等。用户可以通过 PuLP 定义变量、约束条件和目标函数,并选择合适的求解器来解决问题。Pulp默认的求解器是CBC。

在全球最著名的专业优化器评比网站 Decision Tree for Optimization Software (plato.asu.edu/bench.html) 中,Gurobi 比其他大规模优化器有明显优势。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用GurobiPython求解双目标线性规划的示例代码: ```python import gurobipy as gp # 创建模型 model = gp.Model('bilevel_problem') # 创建变量 x1 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x1') x2 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x2') y1 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y1') y2 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y2') # 创建约束条件 constr1 = model.addConstr(2*x1 + x2 <= y1, name='constr1') constr2 = model.addConstr(x1 + 2*x2 <= y2, name='constr2') # 定义目标函数 model.setObjective(y1 + y2, gp.GRB.MINIMIZE) # 创建子问题 submodel1 = gp.Model('subproblem1') submodel2 = gp.Model('subproblem2') # 创建子问题变量 subx1 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby1 = submodel1.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby1') submodel1.update() subx1 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby2 = submodel2.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby2') submodel2.update() # 创建子问题约束条件 subconstr1 = submodel1.addConstr(2*subx1 + subx2 <= suby1, name='subconstr1') submodel1.setObjective(suby1, gp.GRB.MAXIMIZE) subconstr2 = submodel2.addConstr(subx1 + 2*subx2 <= suby2, name='subconstr2') submodel2.setObjective(suby2, gp.GRB.MAXIMIZE) # 添加双层问题约束条件 model.addConstr(suby1 <= y1, name='subconstr1') model.addConstr(suby2 <= y2, name='subconstr2') # 求解模型 model.optimize() # 输出结果 print('x1=', x1.x) print('x2=', x2.x) print('y1=', y1.x) print('y2=', y2.x) ``` 在上面的代码中,我们定义了四个变量和两个约束条件,然后为目标函数设置了两个目标。接下来,我们创建了两个子问题,并分别定义了它们的变量和约束条件。然后,我们将子问题的解添加到双层问题的约束条件中,并使用 `optimize()` 方法求解模型。最后,我们输出了模型的解。 需要注意的是,双目标线性规划具有较高的计算复杂度和较多的局限性,需要根据具体问题进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Terry_trans

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值