Originally posted by: SystemAdmin
Hi,
I am working on a preemptive scheduling problem, by using the techniques described in "P. Laborie, IBM ILOG CP Optimizer for Detailed Scheduling Illustrated on Three Problems".
In the attached example, there is only one task with two slices. And there are two labors who can perform this task. Duration of the task is 29000 secs (200 seconds more then one shift, so will need to preempt-resume in the second day). I limited the solution time to 25secs. Two issues here:
1. it consumes all the time (25secs), for such a trivial instance. (you can also try adding more tasks, and calendar days by uncommenting relevant lines).
2. Objective is to minimize the task end time, however, task is scheduled such that, small portion of it is performed in the first day, and big portion of it is scheduled in the second day. Optimally, the tasks should be completed by time 86600 (28800 in first shift, and 200 in the second shift after the break).
Please advise.
(in case you desired to have quick look, below is the copy of the model, same as attached)---
using CP;
{string
} labors =
{
"labor1",
"labor2"
};
{string
} tasks =
{
"task1"
};
//, "task2"};
int taskSize[t in tasks] = 29000;
//200 seconds more than one shift (28800) tuple Slice
{string task;
int rank;
};
{Slice
} taskSlices =
{<t,r>|t in tasks, r in 1..2
};
// Calendar ======================================================================================= tuple Tshifts
{ string labor;
int startTime;
int endTime;
};
{Tshifts
} shiftIntensity =
{<
", 0, 0>, <", 100, 28800>
// 1st day , <
", 0, 86400>, <", 100, 115200>
// 2nd day
// , <", 0, 172800>, <", 100, 201600> // 3rd day
// , <", 0, 259200>, <", 100, 288000> // 4th day
// , <", 0, 345600>, <", 100, 374400> // 5th day , <
", 0, 0>, <", 100, 28800>
// 1st day , <
", 0, 86400>, <", 100, 115200>
// 2nd day
// , <", 0, 172800>, <", 100, 201600> // 3rd day
// , <", 0, 259200>, <", 100, 288000> // 4th day
// , <", 0, 345600>, <", 100, 374400> // 5th day
}; stepFunction Calendar[l in labors] = stepwise (s in shiftIntensity: s.labor==l)
{ s.startTime -> s.endTime; 0
}; execute
{writeln(Calendar);
};
// ================================================================================================
// EXECUTION PARAMETERS =========================================================================== execute runParameters
{ var p = cp.param;
// p.FailLimit = Opl.card(labors)*Opl.card(tasks)*10 + 100000; p.TimeLimit = Opl.card(labors)*Opl.card(tasks)*2 + 20;
// p.OptimalityTolerance = 0.1; cp.param.TimeMode =
"ElapsedTime"
}
// ================================================================================================ tuple Tallocation
{ Slice slice; string labor;
};
{Tallocation
} allocations =
{<ts, l> | ts in taskSlices, l in labors
};
// VARIABLES ====================================================================================== dvar interval V_task[t in tasks]
// optional ; dvar interval V_taskSlice[s in taskSlices] optional ; dvar interval V_allocation[a in allocations] optional intensity Calendar[a.labor] ; dvar sequence V_labor[l in labors] in all(a in allocations: a.labor == l) V_allocation[a];
// OBJECTIVE ====================================================================================== minimize
// sum(t in tasks) presenceOf(V_task[t]) sum(t in tasks) endOf(V_task[t]) + sum(ts in taskSlices) endOf(V_taskSlice[ts]) ;
// ================================================================================================
// CONSTRAINTS ==================================================================================== subject to
{
// forall(t in tasks)
// endOf(V_task[t]) <= 86600; forall(l in labors) noOverlap(V_labor[l]); forall(s in taskSlices) alternative(V_taskSlice[s], all(l in labors) V_allocation[<s,l>],1); forall(s1 in taskSlices, s2 in taskSlices:s1.task==s2.task && s2.rank==s1.rank+1)
{ presenceOf(V_taskSlice[s1])=>presenceOf(V_taskSlice[s2]); endBeforeStart(V_taskSlice[s1], V_taskSlice[s2]);
} forall(t in tasks)
{ span(V_task[t],all(s in taskSlices: s.task==t)V_taskSlice[s]); taskSize[t] == sum(s in taskSlices: s.task==t)sizeOf(V_taskSlice[s]);
} forall(a in allocations) forbidExtent(V_allocation[a],Calendar[a.labor]);
}
#ConstraintProgramming-General#DecisionOptimization