ILOG-CP-Schedule(以下简称Schedule)引用了几种新变量类型:区间变量(interval variables)、顺序变量(sequence variables)。同时Schedule内置了一些特有函数:步阶函数(stepwise function)、累积函数(cumul function)。
1、区间变量(interval variables)
区间变代表某一个任务持续一段时间,可以简单的理解为一个基本调度任务(task),或是生产车间里的一个基本工单(work order)。Schedule内置了区间变量一些属性和方法(类似于面向对象中,对象自身的属性和方法,每新建了一个区间变量,就等于new的一个区间变量对象)。区间变量常用的属性包括:起点(任务开始时间)、终点(任务结束时间)、长度(任务持续时间)、是否可选(option表示任务是否出现在最终调度方案中)、intensity(抱歉实在翻译不来,一般用来实现绩效考核功能,比如任务在a1->a2段执行计全工时(100%),在a2->a3完成计半工时(50%),则可以通过设定a1->a2阶段的intensity 为100% ,a2->a3阶段的intensity为50%来实现。ps:需要定义步阶函数:stepFunction(见下图)来实现)。区间变量的定义如下:
stepFunction F = stepwise{ 100% -> a2; 50 -> a3};
dvar interval a [optional [in StartMin..EndMax] [size SZ | in SZMin .. SZMax] [intensity F];
/*[]代表可选属性 */
1.1 区间变量函数
Schedule内置了一些函数来对区间变量施加约束,这些函数总体可以分为两类:一类约束单个变量;另一类约束多个变量间的相互关系。
1.1.1常用的第一类函数如下:
presenceOf:用来约束某一个区间变量是否存在,假设场景a--车间内一共有10个工单,最少完成7个,但是其中假设5号工单必须完成,则可以如下表达:
dvar interval task[1..10] optional;
presenceOf(task[5])==1;
用来约束某一个任务的最早开工时间和最晚完工时间,如在同样场景a,要求5号工单的交货期是30这一时刻,因此5号工单必须在30之前完成,则可以如下表达:
startOf\endOf:
endOf(task[5])<30;
stepFunction F = stepwise{ 1 -> 5; 0};
forbidStart(task[i],F);
forbidEnd(task[i],F);
1.1.2常用的第二类函数如下:
endAtStart(task[i],task[j]):i任务必须在j开工的时候结束;
endAtEnd(task[i],task[j]):i,j两个任务同时结束;
endBeforeEnd(task[i],task[j]):i任务必须在j任务之前完成;
endBeforeStart(task[i],task[j]):i任务必须在j任务开始之前结束;
startAtStart(task[i],task[j]):i,j任务必须同时开始;
startAtEnd(task[i],task[j]):i任务必须在j结束时候开始;
startBeforeStart(task[i],task[j]):i任务在j开始之前开始;
startBeforeEnd(task[i],task[j]):i任务必须在j结束之前开始;
span( v,all( i in 1..3 ) task[i] );
span( w,all( i in 4..6) task[i] );
/* v的开始时刻是1->3 task[i]最早的一个的开始时间,同时v的结束时间是1->3中最晚的一个的结束时间*/
startBeforeEnd(v,w);
/*这样保证了v(即1->3)中最早任务的开始时间都晚于w(即4->6)中最晚结束任务的结束时间*/
2.顺序变量(sequence variables)
dvar sequence p in A [types T];
Where:
dvar interval A[];
int T[];
2.1noOverlap函数
noOverlap(p);
在处理相邻两任务间的setup time时,需要定义任务到任务之间的过渡时间矩阵transition_time,然后如下:
noOverlap(p,transition_time)