面对Flow-shop调度问题如何优化?可用MindOpt来决策

简介: mindopt案例——Flow shop-流线型调度问题

生产调度

生产调度是组织执行生产进度计划的工作。现代工业企业,生产环节、协助关系复杂,情况变化快,如果某一措施没有按期实现,常常会波及整个生产系统的运行。因此,加强生产调度工作,对于及时了解、掌握生产进度,研究分析影响生产的各种因素,根据不同情况采取相应对策,使差距缩小或恢复正常是非常重要的。

流线型调度问题- Flow shop

Flow-shop的调度问题可以描述为:已知条件为有一批k个需要n道工序进行加工的工件,分别在n台不同的机器上进行加工,并且加工的顺序是一致的并且给定的,任一工件j(1<=j<=m)的l工序(1<=l<=n)的生产时间是已知的,要求合理地调度各工件的各生产工序在每台机器上的顺序。

Flow-shop特征:


1. 各工件均需在所有机器(集)上加工;

2. 每个工件的各操作仅能在某一台机器(集)上加工;

3. 所有工件预先给定工艺路线,且工艺路线相同;

4. 工件不可重入。


Flow Shop 是调度领域中的经典模型:


  • 给定一组机器和一批工件,所有工件都按相同顺序依次流过这些机器;
  • 工件在各台机器上的加工时长为给定值,一旦工件进入机器的时长已达相应加工时长,工件立即离开该机器;
  • 在任何时刻,一台机器仅能加工最多一个工件;
  • 优化的目标为最小化makespan,即最后完成所有加工的时间;
  • 决策为确定工件之间的先后顺序。

image.png


该问题可以通过黑盒方法或混合整数规划的方法进行求解,在求解过程中,对某个候选解与理论最优解的距离进行估计,可以帮助我们评估解的质量。为获得下界的估计,我们可以松弛混合整数规划模型中的整数约束,得到一个线性规划,求解该松弛问题,即可得到原问题的一个下界。


Flow Shop 调度的MIP模型及其LP松弛


变量


  • image.png, 工件 image.png 比工件 image.png 先加工时取 1;否则取 0;(image.png)
  • image.png, 工件 image.png比在机器 image.png 上开始加工的时间;(image.png)
  • image.png,最大完工时间,即 makespan


目标

  • image.png



约束


  • 工件 image.png比工件 image.png先加工,则工件 image.png必然比工件 image.png后加工,即 image.png 时,image.png,反之亦然,因此,我们有:image.png
  • 当工件 image.png比工件 image.png先加工,在任何机器上工件image.png的开始时间都不早于工件image.png的结束时间(即 image.png),用 Z 表示某一“足够大”的正实数,我们有:image.png
  • 工件在后续机器上的开始时间不得早于当前机器上的结束时间,即: image.png
  • 据最大完工时间的定义,有: image.png
  • 变量的取值范围:对任意image.pngimage.png

MIP模型


image.png


LP松弛模型


将上述MIP模型中的整数要求(image.png)化成区间约束: image.png,即得到相应的LP松弛:


image.png


数据


假设有如下的数据(实际业务数据会更多)。下面我们将用如下数据,会在代码中体现。


# the flow shop scheduling instance ta001 from the Taillard Flow Shop Scheduling Benchmarks
#number of machines
M = 5 
#number of jobs
J = 20   
TA001_Proc_Times = [54,83,15,71,77,36,53,38,27,87,76,91,14,29,12,77,32,87,68,94, \
              79,3,11,99,56,70,99,60,5,56,3,61,73,75,47,14,21,86,5,77, \
              16,89,49,15,89,45,60,23,57,64,7,1,63,41,63,47,26,75,77,40, \
              66,58,31,68,78,91,13,59,49,85,85,9,39,41,56,40,54,77,51,31, \
              58,56,20,85,53,35,53,41,69,13,86,72,8,49,47,87,58,18,68,28]


2.使用MindOpt求解器的API


直接采用求解器的API,需要查阅API文档来理解API的意思,没有建模语言可读性高。请参阅https://solver.damo.alibaba.com/doc/html/API%20reference/API-python/index.html来查看PythonAPI的使用说明。


关于Python的例子,在使用文档的5.建模与优化求解章节有Python的示例。这里是个LP的问题,我们可以参考:https://solver.damo.alibaba.com/doc/html/model/lp/linear%20optimization-python.html


下面我们分两种方式描述在本平台环境中的运行方法:


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


请运行下面cell中的代码,点击本窗口上面的播放△运行,或者摁shift+enter键运行:

# LP_3_flowshop.py
'''
Lower Bound Calculation for Flow Shop Scheduling Optimization
with MindOpt LP Solver
This program builds linear program relaxation (LPR) for the flow shop scheduling
instance ta001 from the Taillard Flow Shop Scheduling Benchmarks, and solve
the LPR with the LP Solver of the MindOpt Optimization Suite.
'''
from mindoptpy import *
##############################
#model data
##############################
#number of machines
M = 5 
#number of jobs
J = 20   
#processing time data from the benchmark:
TA001_Proc_Times = [54,83,15,71,77,36,53,38,27,87,76,91,14,29,12,77,32,87,68,94, \
              79,3,11,99,56,70,99,60,5,56,3,61,73,75,47,14,21,86,5,77, \
              16,89,49,15,89,45,60,23,57,64,7,1,63,41,63,47,26,75,77,40, \
              66,58,31,68,78,91,13,59,49,85,85,9,39,41,56,40,54,77,51,31, \
              58,56,20,85,53,35,53,41,69,13,86,72,8,49,47,87,58,18,68,28]
#data utility function
def processTimeOf(m, j):
    '''
    m: int, index of a machine
    j: int, index of a job
    retrieve the processing time of job j on machine m
    '''
    i = m*J+j                    #the index in the data array
    return TA001_Proc_Times[i]   #the processing of job j at machine m
# the large enough number Z (usually referred to as bigM)
Z = 1.0e7
##############################
#setup and solve the model 
##############################
if __name__ == "__main__":
    '''
    call MindOpt to build and solve the LPR
    '''
    try:
        ###################################
        #step1: initialize MindOpt model 
        model = MdoModel()
        ###########################################
        #step2: build the linear programming model
        #2.1 setup the optimization direction/sense to 'min'
        model.set_int_attr('MinSense', 1)
        #2.2 setup variables
        INF = MdoModel.get_infinity()
        #lowerbound, upperbound, coefficient in objective
        cmax = model.add_var(0.0, INF, 1.0, None, 'Cmax', False)
        s = {}
        for m in range(M):
            for i in range(J):
                sname = 's_%d_%d'%(m,i)
                s[sname] = model.add_var(0.0, INF, 0.0,None,sname,False)
        x = {}
        for i in range(J):
            for j in range(J):
                if i != j:
                    xname = 'x_%d_%d'%(i,j)
                    x[xname] = model.add_var(0.0, 1.0, 0.0, None, xname, False)
        #2.3 setup constraints
        # x_ij + x_ji = 1
        for i in range(J):
            for j in range(J):
                if i<j:
                    cname = 'ExclusiveOrder_%d_%d'%(i,j)
                    expr = MdoExprLinear()
                    expr += x['x_%d_%d'%(i,j)]+ x['x_%d_%d'%(j,i)]
                    model.add_cons(1.0, 1.0, expr, cname)
        # s_mj >= s_mi + P_im + (x_ij -1) Z
        # => s_mi + Z x_ij - s_mj <= Z - P_im
        for m in range(M):
            for i in range(J):
                for j in range(J):
                    if i != j:
                        cname = 'Following_%d_%d_%d'%(m,i,j)
                        expr = MdoExprLinear()
                        expr += s['s_%d_%d'%(m,i)] + Z*x['x_%d_%d'%(i,j)] - s['s_%d_%d'%(m,j)]
                        rub = Z - processTimeOf(m,i) # Z - P_im
                        model.add_cons(-INF, rub, expr, cname)
        #s_(m+1),i >= s_mi + P_mi
        # => s_(m+1)i - s_mi >= P_mi
        for m in range(M-1):
            for i in range(J):
                cname='NextStart_%d_%d'%(m,i)
                proctm = processTimeOf(m,i)
                expr = MdoExprLinear()
                expr += s['s_%d_%d'%(m+1,i)] - s['s_%d_%d'%(m,i)]
                model.add_cons(proctm, INF, expr, cname)
        #cmax >= s_Mi + P_iM
        # => cmax - s_Mi >= P_iM
        for i in range(J):
            m = M-1
            cname = 'Cmax_%d'%(i)
            expr = MdoExprLinear()
            expr += cmax - s['s_%d_%d'%(m,i)]
            proctm = processTimeOf(m,i)
            model.add_cons(proctm, INF, expr, cname)
        #optional step: write to LP file for further use
        model.write_prob('model/LP_3_flowshop_ta001.lp')
        ###########################################
        #step 3: Serialize the model and settings for further submission
        model.set_int_param('NumThreads', 4)
        model.set_real_param('MaxTime', 3600.0)
        # Step 3. Solve the problem and populate the result.
        model.solve_prob()
        model.display_results()
        time.sleep(1) #for print
        status_code, status_msg = model.get_status()
        if status_msg == "OPTIMAL":
            print("----\n")
            model.write_soln('model/LP_3_flowshop_ta001.sol')
            print("The solver terminated with an OPTIMAL status (code {0}).".format(status_code))
            print("目标函数总收益是: {0}".format(model.get_real_attr("PrimalObjVal")))
            '''# 打印内容长
            print("原始解是:")
            for var_name,var_val in s.items():
                primal_soln = var_val.get_real_attr("PrimalSoln")
                print("{0:>20} : {1}".format(var_name,primal_soln))
            for var_name,var_val in x.items():
                primal_soln = var_val.get_real_attr("PrimalSoln")
                print("{0:>20} : {1}".format(var_name,primal_soln))
            '''
        else:
            print("Optimizer terminated with a(n) {0} status (code {1}).".format(status_msg, status_code))
    except MdoError as e:
        print("Received Mindopt exception.")
        print(" - Code          : {}".format(e.code))
        print(" - Reason        : {}".format(e.message))
    except Exception as e:
        print("Received exception.")
        print(" - Reason        : {}".format(e))
    finally:
        # Step 4. Free the model.
        model.free_mdl()

运行之后,得到如下结果:

Start license validation (current time : 17-JAN-2023 23:54:32).
License validation terminated. Time : 0.003s
Concurrent optimization started.
 - Num. threads       : 4
 - Num. optimizers    : 2
 - Registered optimizers.
   +                  : Simplex method (1 thread, enabled output)
   +                  : Interior point method (3 threads, disabled output)
Model summary.
 - Num. variables     : 481
 - Num. constraints   : 2190
 - Num. nonzeros      : 6280
 - Bound range        : [1.0e+00,1.0e+07]
 - Objective range    : [1.0e+00,1.0e+00]
 - Matrix range       : [1.0e+00,1.0e+07]
Presolver started.
Presolver terminated. Time : 0.013s
Simplex method started.
Model fingerprint: md3ZudWY3dmbmV2dm5WZ
    Iteration       Objective       Dual Inf.     Primal Inf.     Time
            0     1.01171e+12      1.0114e-01      4.9321e+10     0.02s    
          417     3.53000e+02      0.0000e+00      0.0000e+00     0.05s    
Postsolver started.
Simplex method terminated. Time : 0.037s
Concurrent optimization terminated.
Optimizer summary.
 - Optimizer used     : Simplex method
 - Optimizer status   : OPTIMAL
 - Total time         : 0.056s
Solution summary.       Primal solution
 - Objective          : 3.5300000000e+02 
----
The solver terminated with an OPTIMAL status (code 1).
目标函数总收益是: 353.0



方法2:命令行直接运行.py文件


上面是直接在cell中运行所有的脚本,我们也可以建立个新文档,将Python代码存在src/python_src文件夹的LP_3_flowshop.py文件,注意存文件的相对目录调整。然后在Launcher中打开Terminal,执行python xx.py文件来运行。


您也可以下载本.py文件,在自己的电脑上安装MindOpt求解器,然后在自己电脑的环境运行。


Luancher可以点击左上角的+打方块打开,Terminal在最下方,如截图示意。打开的窗口可以拖动调整位置

image.png

然后在Terminal命令行里运行如下指令:


cd src/python_src
python LP_3_flowshop.py


运行得到的结果同方法1:

image.png

方法3:  云上建模平台复制项目运行

此案例已经在案例广场中,可以直接复制:生产调度

image.png

3.求解结果


目标函数最优值是: 353.0。文件src/model/LP_3_flowshop.sol存了本问题的优化解。部分结果示例如下:


NAME             : 
PRIMAL OBJECTIVE : +3.53000000000000E+02
DUAL OBJECTIVE   : +3.53000000000000E+02
PROBLEM STATUS   : OPTIMAL
VARIABLES
Cmax                                     +3.53000000000000E+02
s_0_0                                    +0.00000000000000E+00
s_0_1                                    +0.00000000000000E+00
s_0_2                                    +0.00000000000000E+00
s_0_3                                    +6.00000000000000E+00
s_0_4                                    +0.00000000000000E+00
s_0_5                                    +0.00000000000000E+00
s_0_6                                    +4.50000000000000E+01
s_0_7                                    +0.00000000000000E+00
s_0_8                                    +0.00000000000000E+00
s_0_9                                    +0.00000000000000E+00
s_0_10                                   +0.00000000000000E+00
s_0_11                                   +0.00000000000000E+00
s_0_12                                   +6.60000000000000E+01
s_0_13                                   +0.00000000000000E+00
s_0_14                                   +8.00000000000000E+00
s_0_15                                   +0.00000000000000E+00
s_0_16                                   +0.00000000000000E+00
s_0_17                                   +0.00000000000000E+00
s_0_18                                   +0.00000000000000E+00
s_0_19                                   +0.00000000000000E+00
s_1_0                                    +5.40000000000000E+01

联系我们

钉钉答疑群:32451444

钉钉活动群:18890022111(精彩好礼等你来拿!)

邮箱地址:solver.damo@list.alibaba-inc.com

更多更新通知:https://solver.damo.alibaba.com

相关文章
|
3月前
|
达摩院 开发者 容器
「达摩院MindOpt」优化形状切割问题(MILP)
在制造业,高效地利用材料不仅是节约成本的重要环节,也是可持续发展的关键因素。无论是在金属加工、家具制造还是纺织品生产中,原材料的有效利用都直接影响了整体效率和环境影响。
「达摩院MindOpt」优化形状切割问题(MILP)
|
4月前
|
人工智能 自然语言处理 达摩院
MindOpt 云上建模求解平台:多求解器协同优化
数学规划是一种数学优化方法,主要是寻找变量的取值在特定的约束情况下,使我们的决策目标得到一个最大或者最小值的决策。
|
3月前
|
存储 达摩院 调度
「达摩院MindOpt」优化FlowShop流水线作业排班问题
在企业在面临大量多样化的生产任务时,如何合理地安排流水线作业以提高生产效率及确保交货期成为了一个重要的问题。
「达摩院MindOpt」优化FlowShop流水线作业排班问题
|
9月前
|
达摩院 调度
使用达摩院MindOpt优化交通调度_最大化通行量—线性规划问题
在数学规划中,网络流问题是指一类基于网络模型的流量分配问题。网络流问题的目标是在网络中分配资源,使得网络的流量满足一定的限制条件,并且使得某些目标函数最小或最大化。网络流问题通常涉及一个有向图,图中每个节点表示一个资源,每条边表示资源之间的关系。边上有一个容量值,表示该边上最多可以流动的资源数量。流量从源节点开始流出,经过一系列中间节点,最终到达汇节点。在这个过程中,需要遵守一定的流量守恒和容量限制条件。
|
5月前
|
API Python
MindOpt V1.0优化种植计划问题,新的建模方法
种植计划是指农业生产中针对不同农作物的种植时间、面积和种植方式等方面的规划安排。根据具体情况进行合理的规划和安排,以实现农作物的高产、优质和可持续发展。
MindOpt V1.0优化种植计划问题,新的建模方法
|
9月前
|
达摩院 供应链 JavaScript
网络流:优化仓储物流调度问题-达摩院MindOpt
仓储物流调度是指在物流供应链中,对仓储和运输(运输路线、成本)进行协调和安排的过程。主要包含物流计划、运输调度、运发管理、库存管理等重要环节。随着网络、电商行业的迅速发展,仓储物流调度对于企业来说也非常重要,优秀的调度方案可以帮助降低库存成本、物流配送的效率、成本等等等,从而给企业带来降本增效。
网络流:优化仓储物流调度问题-达摩院MindOpt
|
9月前
|
数据可视化
MindOpt优化如何分散化风险并实现收益与风险最优配比问题
资产配置,投资组合是指通过分散投资资金的方式来规避投资过程中的风险。在实际的投资过程中,如何决定投资哪些产品来实现收益最大化和风险最小化是一个关键的问题。
MindOpt优化如何分散化风险并实现收益与风险最优配比问题
|
11月前
|
机器学习/深度学习 人工智能 达摩院
MindOpt——优化虚拟电厂智能调度问题(二)
智慧楼宇调度,是在保证社区负荷需求的情况下,通过储能设备的指令控制,以用电经济性、环保性和对电网稳定性为综合目标的一种调度场景。
MindOpt——优化虚拟电厂智能调度问题(二)
|
11月前
|
SQL Oracle 关系型数据库
Oracle优化04-Optimizer优化器
Oracle优化04-Optimizer优化器
79 0
|
11月前
|
机器学习/深度学习 人工智能 运维
超参数调优河伯、组合优化器CompBO,华为诺亚开源贝叶斯优化库
超参数调优河伯、组合优化器CompBO,华为诺亚开源贝叶斯优化库
131 0