浅谈ILOG-CP-Schedule


ILOG-CP是市面上性能最佳的约束规划(Constraint Programing)求解引擎,ILOG-CP-Schedule是针对调度业务专门设计的函数包,涵盖了几乎全部的工业排程场景。接触了Schedule包一年半后,在此贴出我个人使用心得,欢迎志同道合的小伙伴们一起讨论。

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;

forbidStart\forbidEnd:用于约束某一任务在某一个是可以不能开始或者结束,如工厂周末休息,所以所有的工单都不能在双休日开始也不能在双休日结束,则可以如下表达:
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结束之前开始;
ps:可见逻辑功能描述之全,不愧为行业老大大笑
       定义任务纵向层级关系:继续场景a:设1->3工单隶属于项目v,4->6工单隶属于项目w,这种业务逻辑可以如下表示:
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中最晚的一个的结束时间*/
接着如果项目v必须在w完工后才能开始,可以继续如下:
startBeforeEnd(v,w);
/*这样保证了v(即1->3)中最早任务的开始时间都晚于w(即4->6)中最晚结束任务的结束时间*/

2.顺序变量(sequence variables)

顺序变量用来描述在某一资源(一般可理解为车间内的车床)上执行的各区间变量间的关系,可以用来约束各任务只能先后在车床上进行操作(noOverlap)。同时可以同一车床在处理前后两任务之间需要的setup time(借助过渡矩阵来实现);顺序变量定义如下:
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)

这次就先写到这把,洗洗睡了,后面空了在写。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值