流水车间调度算法分析的简单+Leapms实践--混合整数规划的启发式建模
流水车间调度算法分析的简单+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摘录: