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

简介: 比上一篇问题02中,我们只考虑了一次性的采购和生产计划,实际中的排产排程问题要更加复杂和精细。例如,我们要考虑未来三个月内采购和排产排程计划。其中,原材料每个月的采买价格均有不同,并且原材料购买后的存储也需要成本开销。在本节中,我们将考虑这样一个相对复杂的排产排程的决策问题。

线性规划用于排产排程问题——03

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

上一篇问题02中,我们只考虑了一次性的采购和生产计划,实际中的排产排程问题要更加复杂和精细。例如,我们要考虑未来三个月内采购和排产排程计划。其中,原材料每个月的采买价格均有不同,并且原材料购买后的存储也需要成本开销。在本节中,我们将考虑这样一个相对复杂的排产排程的决策问题。

问题描述

某香皂制造厂要对未来半年内的香皂生产和原料采买制定计划。香皂是由不同的油脂制作而成。每种油脂可以在当月立刻采买使用,也可以在期货市场购买(也即,以约定好的价格预定未来某个月的油脂)并在下一个月运达。而如果储备的油脂当月用不完,则需要付出储存成本。此外,每个月每种类型的油脂有使用上限,而生产出的香皂无法储存,只能在当月卖掉。该制造厂要在这诸多约束下制定香皂生产和原料采买制定计划,以最大化其利润。

数学规划模型

集合

  • 月份集合image.png= {1, 2, 3, 4, 5, 6}
  • 制作香皂的油脂集合image.png
  • 油脂分为两种,我们定义植物油脂集合为image.png,动物油脂集合为image.png
  • 油脂的处理方式集合image.png= {"Buy", "Use", "Store"}

参数

  • 每吨油脂image.png在不同月份image.png的采购成本image.png
  • 油脂image.png的硬度image.png
  • 植物油脂每月的使用量上限image.png(单位: 吨)
  • 动物油脂每月的使用量上限image.png(单位: 吨)
  • 每卖出一吨香皂,盈利image.png
  • 香皂的硬度不得低于image.png,也不得高于image.png
  • 在1月初,每种油脂image.png的储存量为image.png吨。要求在6月末,每种油脂也需要剩余image.png
  • 每种油脂image.png每月的储存代价是image.png

变量

  • image.png表示在工厂在第image.png个月,对油脂image.png的购买(n="Buy"), 使用(n="Use")和储存(n="Store")计划(单位:吨)。
  • x[O * M * N] >= 0
  • image.png表示工厂在第image.png个月,对香皂的生产计划(单位:吨)
  • y[M] >= 0

目标

image.png其中,image.png= "Use", image.png="Store"

最大化工厂的利润,需计算工厂每月的盈利image.png、采购成本image.png、储存成本image.png

  • r * y[m]即销售单价与每月产成品的数量「盈利」
  • sum { in O} cost[j, m] * x[j, m, "Buy"]即油脂每月的采购单价与油脂每月的采购计划「采购成本」
  • d * sum{ in O} x[j, m, "Store"]油脂储存所付出的代价与每月油脂的储存计划「储存成本」

约束

  1. 考虑因素:为了例题更好的计算,假设制作香皂时,油脂转化过程中没有浪费
  • 公式:image.png
  • x[j, m, "Use"]油脂每个月的使用情况与y[m]生产计划相同

  1. 考虑因素:生产的产品有一定的质量要求,例如螺帽,有形状的限制或者大小限制,在此案例我们考虑的是香皂的硬度,
  • 公式:image.png
  • hardness[j] * x[j, m, "Use"]油脂的硬度与每月油脂的使用计划「生产场景」
  • y[m] * ly[m] * u香皂硬度的下限与上限

  1. 考虑因素:仓库有一定的空间,为了对仓库有效率的利用,通过规范油脂的使用数量,对每月储存量进行把控。
  • 公式:image.png        image.png
  • x[j, m, "Use"]每月油脂的使用计划,b1b2植物与动物油脂每月的使用上限

  1. 考虑因素:在生活实际上,每月油脂的采购、使用、储存存在等量关系,以及仓库可能有本次计划之前的油脂剩余情况,所以我们分为一月和其他月份两种情况
  • 上个月的储存量与本月购买量的总和要等于本月的使用量与该月储存量的总和
  • 一月公式:image.png
  • s + x[j,1,"Buy"]油脂的初始储存数量与油脂在一月的购买计划
  • x[j,1,"Use"] + x[j,1,"Store"]油脂在一月的使用计划与储存计划

  • 其他月份公式:image.png
  • x[j,m-1,"Store"] + x[j,m,"Buy"]2-6月份油脂的储存计划与每月的采购计划
  • x[j,m,"Use"] + x[j,m,"Store"]优质每月的使用计划与储存计划

  1. 考虑因素:本次生产计划完毕后,补充仓库,防止仓库空间空余
  • 公式:image.png,其中image.png
  • x[j,6,"Store"]六月每种油脂的储存计划

建模求解问题

此案例使用的关键命令如下:

set                       声明集合
parma                     声明参数
var                       声明变量
maxmaximize               声明目标,此为最大化
subto                     声明约束
option solver mindopt     指定求解的求解器(默认为mindopt)
solve                     求解
display                   打印求解变量值
forall                    快速声明约束的方法,主要用来循环定义的集合
with                      加布尔表达式,表示我们要遍历集合中所有使得布尔表达式为真的元素

案例排产排程03提供了完整的源代码:

clear model;#清除model,多次run的时候使用
option modelname model/manufacture_03_soap2;中间文件生成地址
#---------建模-----------------
# manufacture_03_soap2.mapl
set O1 := { "VEG1", "VEG2" };
set O2 := {"OIL1", "OIL2", "OIL3"};
set O :=  O1 + O2;  
set M := {1, 2, 3, 4, 5, 6};
set N := {"Buy", "Use", "Store"};
param cost[O * M] := 
       |    1,     2,     3,     4,     5,    6    |
|"VEG1"|  110,   130,   110,   120,   100,   90    |
|"VEG2"|  120,   130,   140,   110,   120,   100   |
|"OIL1"|  130,   110,   130,   120,   150,   140   |
|"OIL2"|  110,    90,   100,   120,   110,   80    |
|"OIL3"|  115,   115,    95,   125,   105,   135   |;
param hardness[O] := <"VEG1"> 8.0, <"VEG2"> 6.0, 
                     <"OIL1"> 2.0, <"OIL2"> 4.0, <"OIL3"> 5.0;
param r  := 150;
param b1 := 200;
param b2 := 250;
param l  := 3;
param u  := 6;
param s  := 500;
param d  := 5;
var x[O * M * N] >= 0;    
var y[M] >= 0;
maximize Reward:  sum {<m> in M}(
                            r * y[m] 
                                - sum {<j> in O} cost[j, m] * x[j, m, "Buy"]
                                - d * sum{<j> in O} x[j, m, "Store"]
                                );
subto Weight:     
    forall { <m> in M }
        sum {<j> in O} x[j, m, "Use"] == y[m];
subto Hardness1:  
    forall { <m> in M }
        sum {<j> in O} hardness[j] * x[j, m, "Use"] >= y[m] * l;
subto Hardness2:  
    forall {<m> in M }
        sum {<j> in O} hardness[j] * x[j, m, "Use"] <= y[m] * u;
subto VEGBound:   
    forall {<m> in M }
        sum {<j> in O1} x[j, m, "Use"] <= b1;
subto OILBound:   
    forall { <m> in M }
        sum {<j> in O2} x[j, m, "Use"] <= b2;
subto Link_1:
    forall {<j, 1> in O * M }
        s + x[j,1,"Buy"] == x[j,1,"Use"] + x[j,1,"Store"];
subto Link_2to6:
    forall {<j, m> in O * M with m > 1 }
        x[j,m-1,"Store"] + x[j,m,"Buy"] == x[j,m,"Use"] + x[j,m,"Store"];
subto Store_June:
    forall { <j> in O }
        x[j,6,"Store"] == s;
#------------------------------
print "-----------------用MindOpt求解---------------";
option solver mindopt;  
solve;               
#display; 
#将决策目标的输出格式化
print "-----------------结果---------------";
print "最大利润 = ", sum {<m> in M}(
                    r * y[m] 
                        - sum {<j> in O} cost[j, m] * x[j, m, "Buy"]
                        - d * sum{<j> in O} x[j, m, "Store"]
                    );

求解结果

-----------------用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:33).
License validation terminated. Time : 0.014s
Model summary.
 - Num. variables     : 96
 - Num. constraints   : 60
 - Num. nonzeros      : 253
 - Bound range        : [2.0e+02,5.0e+02]
 - Objective range    : [5.0e+00,1.5e+02]
 - Matrix range       : [1.0e+00,8.0e+00]
Presolver started.
Presolver terminated. Time : 0.000s
Simplex method started.
Model fingerprint: =Y2dgZWZ3ZWY35mY
    Iteration       Objective       Dual Inf.     Primal Inf.     Time
            0     1.23462e+06      0.0000e+00      1.0186e+03     0.01s    
           50     1.08250e+05      0.0000e+00      0.0000e+00     0.01s    
Postsolver started.
Simplex method terminated. Time : 0.002s
OPTIMAL; objective 108250.00
50 simplex iterations
Completed.
-----------------结果---------------
最大利润 = 108250

验证约束

约束条件的验证是优化问题求解过程中的重要环节,是验证求解结果是否准确的重要指标。因此我们进行一次验证,例如验证「六月末每种油脂的储存数量需要等于一月初的初始储存数量」

forall {<j> in O} print
 '六月末(',j,')的储存数量= ',
  x[j,6,"Store"];

运行上述代码结果:

六月末(VEG1)的储存数量= 500
六月末(VEG2)的储存数量= 500
六月末(OIL1)的储存数量= 500
六月末(OIL2)的储存数量= 500
六月末(OIL3)的储存数量= 500

结果解析

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


Primal Solution:
x@<VEG1,1,Buy> = 0.00000000
x@<VEG1,1,Use> = 100.000000
x@<VEG1,1,Store> = 400.000000
x@<VEG1,2,Buy> = 0.00000000
x@<VEG1,2,Use> = 200.000000
x@<VEG1,2,Store> = 200.000000
x@<VEG1,3,Buy> = 0.00000000
x@<VEG1,3,Use> = 0.00000000
x@<VEG1,3,Store> = 200.000000
x@<VEG1,4,Buy> = 0.00000000
x@<VEG1,4,Use> = 0.00000000
x@<VEG1,4,Store> = 200.000000
x@<VEG1,5,Buy> = 0.00000000
x@<VEG1,5,Use> = 200.000000
x@<VEG1,5,Store> = 0.00000000
x@<VEG1,6,Buy> = 700.000000
x@<VEG1,6,Use> = 200.000000
x@<VEG1,6,Store> = 500.000000
x@<VEG2,1,Buy> = 0.00000000
x@<VEG2,1,Use> = 100.000000
x@<VEG2,1,Store> = 400.000000
x@<VEG2,2,Buy> = 0.00000000
x@<VEG2,2,Use> = 0.00000000
x@<VEG2,2,Store> = 400.000000
x@<VEG2,3,Buy> = 0.00000000
x@<VEG2,3,Use> = 200.000000
x@<VEG2,3,Store> = 200.000000
x@<VEG2,4,Buy> = 0.00000000
x@<VEG2,4,Use> = 200.000000
x@<VEG2,4,Store> = 0.00000000
x@<VEG2,5,Buy> = 0.00000000
x@<VEG2,5,Use> = 0.00000000
x@<VEG2,5,Store> = 0.00000000
x@<VEG2,6,Buy> = 500.000000
x@<VEG2,6,Use> = 0.00000000
x@<VEG2,6,Store> = 500.000000
x@<OIL1,1,Buy> = 0.00000000
x@<OIL1,1,Use> = 0.00000000
x@<OIL1,1,Store> = 500.000000
x@<OIL1,2,Buy> = 0.00000000
x@<OIL1,2,Use> = 0.00000000
x@<OIL1,2,Store> = 500.000000
x@<OIL1,3,Buy> = 0.00000000
x@<OIL1,3,Use> = 0.00000000
x@<OIL1,3,Store> = 500.000000
x@<OIL1,4,Buy> = 0.00000000
x@<OIL1,4,Use> = 0.00000000
x@<OIL1,4,Store> = 500.000000
x@<OIL1,5,Buy> = 0.00000000
x@<OIL1,5,Use> = 0.00000000
x@<OIL1,5,Store> = 500.000000
x@<OIL1,6,Buy> = 0.00000000
x@<OIL1,6,Use> = 0.00000000
x@<OIL1,6,Store> = 500.000000
x@<OIL2,1,Buy> = 0.00000000
x@<OIL2,1,Use> = 0.00000000
x@<OIL2,1,Store> = 500.000000
x@<OIL2,2,Buy> = 150.000000
x@<OIL2,2,Use> = 250.000000
x@<OIL2,2,Store> = 400.000000
x@<OIL2,3,Buy> = 0.00000000
x@<OIL2,3,Use> = 0.00000000
x@<OIL2,3,Store> = 400.000000
x@<OIL2,4,Buy> = 0.00000000
x@<OIL2,4,Use> = 250.000000
x@<OIL2,4,Store> = 150.000000
x@<OIL2,5,Buy> = 0.00000000
x@<OIL2,5,Use> = 150.000000
x@<OIL2,5,Store> = 0.00000000
x@<OIL2,6,Buy> = 750.000000
x@<OIL2,6,Use> = 250.000000
x@<OIL2,6,Store> = 500.000000
x@<OIL3,1,Buy> = 0.00000000
x@<OIL3,1,Use> = 250.000000
x@<OIL3,1,Store> = 250.000000
x@<OIL3,2,Buy> = 0.00000000
x@<OIL3,2,Use> = 0.00000000
x@<OIL3,2,Store> = 250.000000
x@<OIL3,3,Buy> = 0.00000000
x@<OIL3,3,Use> = 250.000000
x@<OIL3,3,Store> = 0.00000000
x@<OIL3,4,Buy> = 0.00000000
x@<OIL3,4,Use> = 0.00000000
x@<OIL3,4,Store> = 0.00000000
x@<OIL3,5,Buy> = 600.000000
x@<OIL3,5,Use> = 100.000000
x@<OIL3,5,Store> = 500.000000
x@<OIL3,6,Buy> = 0.00000000
x@<OIL3,6,Use> = 0.00000000
x@<OIL3,6,Store> = 500.000000
     y@1 = 450.000000
     y@2 = 450.000000
     y@3 = 450.000000
     y@4 = 450.000000
     y@5 = 450.000000
     y@6 = 450.000000
-----------------结果---------------
最大利润 = 108250

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

从打印的结果,我们可以得到最大利润为108250元。

相关文章
|
3月前
|
达摩院 供应链 安全
光储荷经济性调度问题【数学规划的应用(含代码)】阿里达摩院MindOpt
本文介绍使用MindOpt工具优化光储荷经济性调度的数学规划问题。光储荷经济性调度技术旨在最大化能源利用率和经济效益,应用场景包括分布式光伏微网、家庭能源管理系统、商业及工业用电、电力市场参与者等。文章详细阐述了如何通过数学规划方法解决虚拟电厂中的不确定性与多目标优化难题,并借助MindOpt云建模平台、MindOpt APL建模语言及MindOpt优化求解器实现问题建模与求解。最终案例展示了如何通过合理充放电策略减少37%的电费支出,实现经济与环保双重效益。读者可通过提供的链接获取完整源代码。
|
3月前
|
达摩院 BI 索引
切割问题【数学规划的应用(含代码)】阿里达摩院MindOpt
本文主要讲述了使用MindOpt工具对切割问题进行优化的过程与实践。切割问题是指从一维原材料(如木材、钢材等)中切割出特定长度的零件以满足不同需求,同时尽可能减少浪费的成本。文章通过实例详细介绍了如何使用MindOpt云上建模求解平台及其配套的MindOpt APL建模语言来解决此类问题,包括数学建模、代码实现、求解过程及结果分析等内容。此外,还讨论了一维切割问题的应用场景,并对其进行了扩展,探讨了更复杂的二维和三维切割问题。通过本文的学习,读者能够掌握利用MindOpt工具解决实际切割问题的方法和技术。
|
3月前
|
达摩院 算法 安全
智慧楼宇多目标调度问题【数学规划的应用(含代码)】阿里达摩院MindOpt
本文探讨了使用MindOpt工具优化智慧楼宇的多目标调度问题,特别是在虚拟电厂场景下的应用。智慧楼宇通过智能化技术综合考虑能耗、舒适度等多目标,实现楼宇设备的有效管理和调度。虚拟电厂作为多能源聚合体,能够参与电力市场,提供调峰、调频等辅助服务。文章介绍了如何使用MindOpt云上建模求解平台及MindOpt APL建模语言对楼宇多目标调度问题进行数学建模和求解,旨在通过优化储能设备的充放电操作来最小化用电成本、碳排放成本和功率变化成本,从而实现经济、环保和电网稳定的综合目标。最终结果显示,在使用储能设备的情况下,相比不使用储能设备的情形,成本节约达到了约48%。
|
3月前
|
达摩院 供应链 JavaScript
网络流问题--仓储物流调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文通过使用MindOpt工具优化仓储物流调度问题,旨在提高物流效率并降低成本。首先,通过考虑供需匹配、运输时间与距离、车辆容量、仓库储存能力等因素构建案例场景。接着,利用数学规划方法,包括线性规划和网络流问题,来建立模型。在网络流问题中,通过定义节点(资源)和边(资源间的关系),确保流量守恒和容量限制条件下找到最优解。文中还详细介绍了MindOpt Studio云建模平台和MindOpt APL建模语言的应用,并通过实例展示了如何声明集合、参数、变量、目标函数及约束条件,并最终解析了求解结果。通过这些步骤,实现了在满足各仓库需求的同时最小化运输成本的目标。
|
4月前
|
达摩院 安全 调度
网络流问题--交通调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文探讨了如何利用数学规划工具MindOpt解决交通调度问题。交通调度涉及网络流分析,考虑道路容量、车辆限制、路径选择等因素,以实现高效运行。通过建立数学模型,利用MindOpt云平台和建模语言MAPL,设定流量最大化目标并确保流量守恒,解决实际的调度问题。案例展示了如何分配车辆从起点到终点,同时满足道路容量约束。MindOpt Studio提供在线开发环境,支持模型构建和求解,帮助优化大规模交通调度。
|
4月前
|
达摩院
人员排班【数学规划的应用(含代码)】阿里达摩院MindOpt
本文介绍了使用阿里巴巴达摩院的MindOpt工具解决人员排班的数学规划问题。人员排班在多个行业中至关重要,如制造业、医疗、餐饮和零售等。问题涉及多种约束,包括工作需求、员工能力、工作时间限制、连续工作天数及公平性。通过MindOpt云建模平台和建模语言MindOpt APL,建立数学模型并编写代码来解决最小化总上班班次的问题。案例中展示了如何声明集合、参数、变量和约束,并给出了部分代码示例。最后,通过MindOpt求解器得到最优解,并将结果输出到CSV文件中。
|
4月前
|
存储 达摩院 供应链
排产排程问题【数学规划的应用(含代码)】阿里达摩院MindOpt
**文章摘要:** 本文探讨了使用阿里巴巴达摩院的MindOpt优化求解器解决制造业中的排产排程问题。排产排程涉及物料流动、工序安排、设备调度等多个方面,通常通过数学规划方法建模。MindOpt支持线性规划、整数规划等,能有效处理大规模数据。案例以香皂制造工厂为例,考虑了多种油脂的购买、存储和生产计划,以及价格变化和存储成本。问题通过数学建模转化为MindOpt APL代码,求解器自动寻找最优解,以最大化利润。文章还提供了代码解析,展示了解决方案的细节,包括目标函数(利润最大化)、约束条件(如生产效率、库存管理)以及结果分析。
|
6月前
|
达摩院 开发者 容器
「达摩院MindOpt」优化形状切割问题(MILP)
在制造业,高效地利用材料不仅是节约成本的重要环节,也是可持续发展的关键因素。无论是在金属加工、家具制造还是纺织品生产中,原材料的有效利用都直接影响了整体效率和环境影响。
「达摩院MindOpt」优化形状切割问题(MILP)
|
6月前
|
人工智能 自然语言处理 达摩院
MindOpt 云上建模求解平台:多求解器协同优化
数学规划是一种数学优化方法,主要是寻找变量的取值在特定的约束情况下,使我们的决策目标得到一个最大或者最小值的决策。
|
1月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
26 1