首页 > 技术文章 > 流水车间调度算法分析的简单+Leapms实践--混合整数规划的启发式建模

leapms 2019-01-11 17:53 原文

流水车间调度算法分析的简单+Leapms实践--混合整数规划的启发式建模

清华大学出版社出版的白丹宇教授著作《流水车间与开放车间调度算法渐近分析》采用渐近分析方法分析多个NP-难类启发调度算法的收敛性,学术性很强。

本帖用数学规划模型方法对比精确模型和启发模型之间的差异,从实践角度感觉启发算法的魅力。本帖的要点如下:

1。有人说数学规划模型是精确方法。其实广义地讲,数学规划模型也可以是启发算法,只要你对问题进行启发建模就行。

2。启发建模会牺牲求解精确性,但是对NP-难问题来说,由于对大规模问题的精确解很难获得,启发算法或启发建模是必须的。

3。当测试算法时,原始数据经常是随机生成的,最好能把数据的生成简洁地写进模型,那么测试就简单多了。

流水车间调度问题

假设有m个机器,n个工件,已知每个工件在不同机器上的加工时间,求如何排序工件在不同机器上的加工次序使得总完工时间最短(以此目标为例)。

流水车间调度的精确模型

设x[i][j] 为工件j 在机器i上的开始加工时间,设c为总完工时间,于是目标是:

      min c

c肯定大于任何工件在任何机器上的完成时间:

    c>=x[i][j]+T[i][j] | i=1,..,m;j=1,..,n

把工件 j 在机器 i 上的加工时间设置为T[i][j]。

对两个工件 j1,j2, j1$\neq$ j2,在同一台机器上的加工时间不可以冲突,即:

    x[i][j2]>=x[i][j1]+T[i][j1] - M(1-u[i][j1][j2])|i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2
    x[i][j1]>=x[i][j2]+T[i][j2] - M*u[i][j1][j2] | i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2

对同一个工件j, 其在两台不同机器 i1,i2, i1 $\neq $ i2上加工的时间不能冲突,即:

    x[i2][j]>=x[i1][j]+T[i1][j] - M(1-v[i1][i2][j])| i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2
    x[i1][j]>=x[i2][j]+T[i2][j] - M*v[i1][i2][j] |  i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2

说明一下引入的常量和变量:

where
    m,n are integers
    M is a number
    c is a variable of number
    T[i][j] is a number|i=1,..,m;j=1,..,n
    x[i][j] is a variable of nonnegative number|i=1,..,m;j=1,..,n
    u[i][j1][j2] is a variable of binary|i=1,..,m;j1=1,..,n;j2=1,..,n;j1<>j2
    v[i1][i2][j] is a variable of binary|i1=1,..,m;i2=1,..,m;j=1,..,n;i1<>i2

提供计算得来的数据,注意T[i][j]是用随机函数随机生成的0-100之间的数:

data_relation
    T[i][j]=rand(100)|i=1,...,m;j=1,...,n
    M=sum{i=1,..,m;j=1,..,n}T[i][j]

提供数据,这里设m=3使得问题NP-难,n=100规模足够大:

data
    m=3
    n=100

总体的模型:

//x[i][j] -- start time of job j on machine i
min c
subject to 
    c>=x[i][j]+T[i][j] | i=1,..,m;j=1,..,n
    x[i][j2]>=x[i][j1]+T[i][j1] - M(1-u[i][j1][j2])|i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2
    x[i][j1]>=x[i][j2]+T[i][j2] - M*u[i][j1][j2] | i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2
    x[i2][j]>=x[i1][j]+T[i1][j] - M(1-v[i1][i2][j])| i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2
    x[i1][j]>=x[i2][j]+T[i2][j] - M*v[i1][i2][j] |  i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2
where
    m,n are integers
    M is a number
    c is a variable of number
    T[i][j] is a number|i=1,..,m;j=1,..,n
    x[i][j] is a variable of nonnegative number|i=1,..,m;j=1,..,n
    u[i][j1][j2] is a variable of binary|i=1,..,m;j1=1,..,n;j2=1,..,n;j1<>j2
    v[i1][i2][j] is a variable of binary|i1=1,..,m;i2=1,..,m;j=1,..,n;i1<>i2
data_relation
    T[i][j]=rand(100)|i=1,...,m;j=1,...,n
    M=sum{i=1,..,m;j=1,..,n}T[i][j]
data
    m=3
    n=100

流水车间调度的启发模型

使用这个启发: 让在机器上加工时间较小的任务早些执行。即同一个机器上工件不冲突约束改变为:

    x[i][j2]>=x[i][j1]+T[i][j1] |i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2;T[i][j1]<T[i][j2]
    x[i][j1]>=x[i][j2]+T[i][j2] | i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2;T[i][j1]>=T[i][j2]

总体模型是:

//x[i][j] -- start time of job j on machine i
min c
subject to 
    c>=x[i][j]+T[i][j] | i=1,..,m;j=1,..,n
    x[i][j2]>=x[i][j1]+T[i][j1] |i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2;T[i][j1]<T[i][j2]
    x[i][j1]>=x[i][j2]+T[i][j2] | i=1,..,m;j1=1,..,n;j2=1,..,n;j1<j2;T[i][j1]>=T[i][j2]
    x[i2][j]>=x[i1][j]+T[i1][j] - M(1-v[i1][i2][j])| i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2
    x[i1][j]>=x[i2][j]+T[i2][j] - M*v[i1][i2][j] |  i1=1,..,m;i2=1,..,m;j=1,..,n;i1<i2
where
    m,n are integers
    M is a number
    c is a variable of number
    T[i][j] is a number|i=1,..,m;j=1,..,n
    x[i][j] is a variable of nonnegative number|i=1,..,m;j=1,..,n
    v[i1][i2][j] is a variable of binary|i1=1,..,m;i2=1,..,m;j=1,..,n;i1<>i2
data_relation
    T[i][j]=rand(100)|i=1,...,m;j=1,...,n
    M=sum{i=1,..,m;j=1,..,n}T[i][j]
data
    m=3
    n=100

对比试算

将两个模型调入+Leapms环境中进行解析。

精确模型有3061个变量和30600个约束:

启发模型有901个变量,15750个约束:

两者不仅是变量和约束数字的差异,关键是模型结构上的差异。

在+Leapms中使用cplex命令呼叫 CPLEX求解:

精确模型在笔者能忍受的时间内求不到精确解,两分钟之后的最好解是5715, gap 96%,这样大的gap很难降下来。刚刚几乎死机,赶紧杀掉进程,保护本帖。

启发模型呼叫CPLEX后瞬间被求解,最优解4904。

关于渐进性的进一步实验统计得换m,n值慢慢算,有时间的再全面试下,该吃饭了,先下了。最后贴下两个模型的PDF摘录。

两个模型的PDF摘录:

 

推荐阅读