优化求解器是求解优化问题的专业设计软件。MindOpt是阿里达摩院自主研发的求解器套件,可用于求解线性规划、混合整数线性规划、半定规划、凸二次规划问题,目前广泛工业制造、交通物流、云计算等领域,每年都有帮助阿里降低成本,提高利率,本系列将带大家了解多个MindOpt的使用场景。
本篇我们要讲述的案例是工厂生产相关,一个好的管理者会合理安排生产计划,让生产机器在固定的时间,不同的产品,生产效率的差异中尽可能的让工厂的利益最大化。那么面对这一问题,如果计算量比较大,该如何是好呢?MindOpt优化求解器可以为您提供计算能力,让工厂利益最大化。下面我将使用MindOpt来优化一个排产排程的问题。
问题描述和数学规划模型
问题描述
考虑如下决策问题,某钢铁厂在下一周将要生产Bands,Coils,和Plate三种产品。
- 已知该工厂每小时能生产200吨Bands、或140吨Coils、或160吨Plate。
- 每吨Bands获利25元,每吨Coils获利30元,每吨Plate获利29元。
- 已知每周最多能够生产最多6000吨的Bands,4000吨的Coils 和3500吨Plate,且工厂每周最多工作40小时。
- 现规定每周Bands生产数量不得少于1000吨,Coils的生产数量不得少于500吨,Plate的生产数量不得少于750吨。
问下周生产多少吨的Bands和Coils能让工厂利润最大化?
数学规划模型
以上问题,我们可以建立线性规划的数学模型如下。
集合
产品集合 𝑃
混合集合 𝐷
(由生产效率 rate,每小时获利 profit,最低生产量 commit和最大生产量 profit四个元素组成)
参数
- 工厂每周最大工作时间 avail
- 工厂生产产品 𝑝∈𝑃 的效率 𝑟𝑝
- 每吨产品 𝑝∈𝑃 获利 𝑝𝑝
- 产品 𝑝∈𝑃 每天最低生产量 𝑐𝑝
- 产品 𝑝∈𝑝 每天最大生产量 𝑚𝑝
决策变量
工厂一周生产产品 𝑝∈𝑃 的数量
目标函数
工厂要最大化利润
约束
工厂每周工作不得超过最大工作时间
汇总的数学公式如下:
使用MindOpt APL进行建模和求解
MindOpt建模语言(MindOpt Algebra Programming Language, MindOpt APL,简称为MAPL)是一种高效且通用的代数建模语言。当前主要用于数学规划问题的建模,并支持调用多种求解器求解。下面将演示如何使用MAPL将上面的数学模型公式和数据输入,生成一个求解器可求解的问题,再调用求解器去进行求解。
方法:cell中直接输入建模代码运行
改写上面的数据图和数学模型,如下代码,在Notebook的cell中运行它:
clear model;#清除model,多次run的时候使用 option modelname model/manufacture_01_steel;#方便与方法2的中间文件生成在同一个目录 #---------建模----------------- # manufacture_01_steel.mapl set PROD := { "bands", "coils", "plate" }; set D := { "rate", "profit", "commit", "market" }; param data[PROD * D] := | "rate", "profit", "commit", "market"| |"bands" | 200, 25, 1000, 6000 | |"coils" | 140, 30, 500, 4000 | |"plate" | 160, 29, 750, 3500 |; param avail := 40; var Make[<p> in PROD] >= data[p, "commit"] <= data[p, "market"]; maximize Total_Profit: sum {<p> in PROD } data[p, "profit"] * Make[p]; subto Time: sum {<p> in PROD} 1/data[p, "rate"] * Make[p] <= avail; #------------------------------ print "-----------------用MindOpt求解---------------"; option solver mindopt; # 指定求解用MindOpt求解器 solve; # 求解 display; print "-----------------结果---------------"; print "最大利润 = "; print sum { <p> in PROD } data[p, "profit"] * Make[p];
运行上述代码结果如下:
-----------------用MindOpt求解--------------- Running mindoptampl wantsol=1 MindOpt Version 0.25.1 (Build date: 20230816) Copyright (c) 2020-2023 Alibaba Cloud. Start license validation (current time : 18-AUG-2023 16:04:09). License validation terminated. Time : 0.006s Model summary. - Num. variables : 3 - Num. constraints : 1 - Num. nonzeros : 3 - Bound range : [4.0e+01,6.0e+03] - Objective range : [2.5e+01,3.0e+01] - Matrix range : [5.0e-03,7.1e-03] Presolver started. Presolver terminated. Time : 0.002s Simplex method started. Model fingerprint: =E2blNmZul3Z3R2dkdnZ Iteration Objective Dual Inf. Primal Inf. Time 0 3.71500e+05 0.0000e+00 1.6179e+01 0.01s 1 1.94829e+05 0.0000e+00 0.0000e+00 0.02s Postsolver started. Simplex method terminated. Time : 0.008s OPTIMAL; objective 194828.57 1 simplex iterations Completed. Primal Solution: Make@bands = 6000.00000 Make@coils = 500.000000 Make@plate = 1028.57143 -----------------结果--------------- 最大利润 = 194828.5714285714
3. 结果解析
display指令运行时,会打印求解的结果,Make@name 是决策变量的取值,后面的dual solution是对偶解的值。示意如下:
Primal Solution: Make@bands = 6.000000000000000E+03 Make@coils = 5.000000000000000E+02 Make@plate = 1.028571428571429E+03 Dual Solution: Time_1 = 4.640000000000000E+03
同时,在最近建模的文件所在目录或option modelname指定的位置,会生成对应的文件.nl
和.sol
。其中.nl
文件是建模的问题模型文件,可被多数求解器识别,.sol
文件中存储了求解结果solution。
从打印的结果,我们可以得到采用如下的生产方案时,利润最大,为194828.57元:
Make@bands = 6.000000000000000E+03 Make@coils = 5.000000000000000E+02 Make@plate = 1.028571428571429E+03