「达摩院MindOpt」线性规划用于排程排程问题(02)

1. 问题描述和数学规划模型

排产排程、原料采购、仓储存放等是制造业降本增效的关键问题。本节以香皂的制造为例,不同于上一篇问题01-生产多少,本例主要考虑原料采购的问题。以下数据只是用来示意如何使用MAPL建模和求解,实际的制造规划问题规模更大,建模更复杂。

集合

  • 制作香皂的油脂集合 O O O
  • 油脂分为两种,我们定义植物油脂集合为 O 1 O_1 O1,动物油脂集合为 O 2 O_2 O2

参数

  • 油脂 j ∈ O j \in O jO每吨的成本 c j c_j cj
  • 油脂 j ∈ O j \in O jO的硬度 h j h_j hj
  • 植物油脂的购买量上限 b 1 b_1 b1(单位: 吨)
  • 动物油脂的购买上限 b 2 b_2 b2(单位: 吨)
  • 每卖出一吨香皂,盈利 r r r
  • 香皂的硬度不得低于 ℓ \ell ,也不得高于 u u u

变量

  • x j x_j xj是某工厂要购买油脂 j ∈ O j\in O jO的重量(单位: 吨)
  • y y y是生产的香皂量(单位: 吨)

目标

  • 工厂要最大化其利润: max ⁡ r y − ∑ j ∈ O c j x j \max\quad r y - \sum_{j\in O} c_j x_j maxryjOcjxj

约束

  • 假设从油脂到香皂的转化过程中,油脂没有任何浪费,生产过程中重量守恒: ∑ j ∈ O x j = y \sum_{j\in O} x_j = y jOxj=y
  • 植物油脂的购买总量不得超过 b 1 b_1 b1 ∑ j ∈ O 1 x j ≤ b 1 \sum_{j\in O_1} x_j \le b_1 jO1xjb1
  • 动物油脂的购买总量不得超过 b 2 b_2 b2: ∑ j ∈ O 2 x j ≤ b 2 \sum_{j\in O_2} x_j \le b_2 jO2xjb2
  • 假设从油脂到香皂的制造过程中,硬度的转化满足线性关系: ℓ y ≤ ∑ j ∈ O h j x j ≤ u y \ell y \le \sum_{j\in O} h_j x_j \le u y yjOhjxjuy

2. 使用MindOpt APL进行建模和求解

MindOpt建模语言(MindOpt Algebra Programming Language, MindOpt APL,简称为MAPL)是一种高效且通用的代数建模语言。当前主要用于数学规划问题的建模,并支持调用多种求解器求解。下面将演示如何使用MAPL将上面的数学模型公式和数据输入,生成一个求解器可求解的问题,再调用求解器去进行求解。

方法1:cell中直接输入建模代码运行

我们可以将 MindOpt APL 建模代码直接在MindOpt云上平台Notebook中的cell里运行。请注意内核(kernel)需要选MAPL。代码如下:

clear model;#清除model,多次run的时候使用
option modelname model/manufacture_02_soap1;#方便与方法2的中间文件生成在同一个目录

#---------建模-----------------
# manufacture_02_soap1.mapl

# 声明集合
set O1 := { "VEG1", "VEG2" };
set O2 := {"OIL1", "OIL2", "OIL3"};
set O :=  O1 + O2;  
set F := {"cost", "hardness"};

# 声明参数
param data[O * F] := 
        | "cost" , "hardness" |
|"VEG1" |  100   ,  2.0       |
|"VEG2" |  90    ,  4.5       |
|"OIL1" |  110   ,  5.3       |
|"OIL2" |  105   ,  7.8       |
|"OIL3" |  95    ,  5.0       |;

param r  := 180;
param b1 := 200;
param b2 := 150;
param l  := 4;
param u  := 6;

# 声明变量
var x[O] >= 0;    # 括号内室字母O, 并非数字0
var y >= 0;

# 声明目标
maximize Reward:  r * y - sum {<j> in O} (data[j, "cost"] * x[j]);

# 声明约束
subto Weight:     sum {<j> in O} x[j] == y;
subto Hardness1:  sum {<j> in O} (data[j, "hardness"] * x[j]) >= y * l;
subto Hardness2:  sum {<j> in O} (data[j, "hardness"] * x[j]) <= y * u;
subto VEGBound:   sum {<j> in O1} x[j] <= b1;
subto OILBound:   sum {<j> in O2} x[j] <= b2;
   
#------------------------------

print "-----------------用MindOpt求解---------------";
option solver mindopt;   # 指定求解用MindOpt求解器
solve;               # 求解
display;

print "-----------------结果---------------";
print "最大利润 = ",r * y - sum {<j> in O} data[j, "cost"] * x[j];

方法2:导入.mapl文件运行建模然后求解

上面时直接在cell中运行所有的脚本,我们也可以建立个新文档,将中间建模的代码保存为manufacture_02_soap1.mapl文件。然后运行如下code,结果同方法1。

clear model;#清除model,多次run的时候使用

#------------------------------

model model/manufacture_02_soap1.mapl;  #通过导入建模脚本.mapl文件进行建模

#------------------------------
print "-----------------用MindOpt求解---------------";
option solver mindopt;   # 指定求解用MindOpt求解器
solve;               # 求解
display;

print "-----------------结果---------------";
print "最大利润 = ", r * y - sum {<j> in O} data[j, "cost"] * x[j];

3. 结果

运行方法一、方法二代码结果一致,如下:

-----------------用MindOpt求解---------------
Running mindoptampl
wantsol=1
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 24-AUG-2023 19:46:39).
License validation terminated. Time : 0.006s

Model summary.
 - Num. variables     : 6
 - Num. constraints   : 5
 - Num. nonzeros      : 23
 - Bound range        : [1.5e+02,2.0e+02]
 - Objective range    : [9.0e+01,1.8e+02]
 - Matrix range       : [1.0e+00,7.8e+00]

Presolver started.
Presolver terminated. Time : 0.000s

Simplex method started.
Model fingerprint: =Y2dkV2dhdnY

    Iteration       Objective       Dual Inf.     Primal Inf.     Time
            0     1.54802e+05      0.0000e+00      8.6001e+00     0.01s  
            4     3.07500e+04      0.0000e+00      0.0000e+00     0.01s  
Postsolver started.
Simplex method terminated. Time : 0.001s


OPTIMAL; objective 30750.00
4 simplex iterations

Completed.
Primal Solution:
  x@VEG1 = 0.00000000
  x@VEG2 = 200.000000
  x@OIL1 = 0.00000000
  x@OIL2 = 0.00000000
  x@OIL3 = 150.000000
       y = 350.000000
-----------------结果---------------
最大利润 = 30750

display指令运行时,会打印出很多求解的结果,x@name 和 y 是决策变量的取值,后面的dual solution是对偶解的值。示意如下:


Primal Solution:
  x@VEG1 = 0.00000000
  x@VEG2 = 200.000000
  x@OIL1 = 0.00000000
  x@OIL2 = 0.00000000
  x@OIL3 = 150.000000
       y = 350.000000
-----------------结果---------------
最大利润 = 30750

同时,在最近建模的文件所在目录或option modelname指定的位置,会生成对应的文件 .nl.sol。其中 .nl文件是建模的问题模型文件,可被多数求解器识别,.sol文件中存储了求解结果solution。

从打印的结果,们可以得到采用如下的采购方案时,利润最大,为30750元,生产了350吨的香皂:

  x@VEG2 = 200.000000
  x@OIL3 = 150.000000
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值