Originally posted by: SystemAdmin
Hello,
The problem is due to the fact the engine does not notice early enough that once he has started to schedule two trains to run on opposite direction on a part of the network where crossing is not allowed (say sections 6..44) then, this whole sub-tree is infeasible.
You could try to add redundant constraints that for each segment (segment = set of contiguous sections) on which no crossing is allowed will post the constraint that at any moment, there cannot be several trains moving on different directions along this segment. This can be done thanks to a state function per segment. The state of the state function represents the direction that is currently used (at most one). Here is a model adapted from yours that implement this idea. Note that I hard-coded the additional interval variables and state functions, this is only for illustrative purpose. Depending on the exact topology of the network this idea may be harder to implement.
using CP;
int maxSections = 50;
{
int
} stationYard =
{ 5, 45
};
// Simulation of yard station range sections = 1..maxSections; range trains = 1..2;
// 1 minute for tail
int TailTime = 1;
// At least 1 minute for pass
int DMin = 1;
int DMax = 10; dvar interval dvOcupacao[k in sections][l in trains] size (TailTime+DMin)..(TailTime+DMax);
//..10; cumulFunction cfOcupacao[c in sections] = sum(k in sections, l in trains : ((c==k) && (k not in stationYard))) pulse(dvOcupacao[k][l], 1);
// Tardiness of activities dexpr
float totalLinWeightedTardiness = sum(k in sections, l in trains) ((sizeOf(dvOcupacao[k][l]) - DMin - TailTime) * (maxSections - k) / maxSections); execute
{ cp.param.TimeLimit = 20;
}
// Those model elements (stateFunction, intervals) are hard-coded for illustration stateFunction Dir1_4;
// Segment of line between sections 1 and 4 (no crossing allowed, so at most one direction used) stateFunction Dir6_44;
// Segment of line between sections 6 and 44 (no crossing allowed, so at most one direction used) stateFunction Dir46_50;
// Segment of line between sections 46 and 50 (no crossing allowed, so at most one direction used) dvar interval T1Sections1To4;
// Segment {1..4} used by Train 1, direction 1 dvar interval T1Sections6To44;
// Segment {6..44} used by Train 1, direction 1 dvar interval T1Sections46To50;
// Segment {46..50} used by Train 1, direction 1 dvar interval T2Sections4To1;
// Segment {1..4} used by Train 2, direction 2 dvar interval T2Sections44To6;
// Segment {6..44} used by Train 2, direction 2 dvar interval T2Sections50To46;
// Segment {46..50} used by Train 2, direction 2 minimize totalLinWeightedTardiness; subject to
{ startAtStart(T1Sections1To4, dvOcupacao[1][1]); endAtEnd(T1Sections1To4, dvOcupacao[4][1]); alwaysEqual(Dir1_4,T1Sections1To4,1); startAtStart(T1Sections6To44, dvOcupacao[6][1]); endAtEnd(T1Sections6To44, dvOcupacao[44][1]); alwaysEqual(Dir6_44,T1Sections6To44,1); startAtStart(T1Sections46To50, dvOcupacao[46][1]); endAtEnd(T1Sections46To50, dvOcupacao[50][1]); alwaysEqual(Dir46_50,T1Sections46To50,1); startAtStart(T2Sections4To1, dvOcupacao[4][2]); endAtEnd(T2Sections4To1, dvOcupacao[1][2]); alwaysEqual(Dir1_4,T2Sections4To1,2); startAtStart(T2Sections44To6, dvOcupacao[44][2]); endAtEnd(T2Sections44To6, dvOcupacao[6][2]); alwaysEqual(Dir6_44,T2Sections44To6,2); startAtStart(T2Sections50To46, dvOcupacao[50][2]); endAtEnd(T2Sections50To46, dvOcupacao[46][2]); alwaysEqual(Dir46_50,T2Sections50To46,2);
// Start of Activities startOf(dvOcupacao[1][1]) == 0; startOf(dvOcupacao[maxSections][2]) == 0;
// Max time in arrives sizeOf(dvOcupacao[maxSections][1]) == 1+TailTime; sizeOf(dvOcupacao[1][2]) == 1+TailTime;
// Sequence of activities forall (i in sections : i < maxSections)
{
// From section 1 to max sections (down) endAtStart(dvOcupacao[i][1], dvOcupacao[i+1][1],-TailTime);
// From section MAX to section 1 (oposite direction - up) endAtStart(dvOcupacao[(maxSections+1)-i][2], dvOcupacao[maxSections - i][2],-TailTime);
}
// Ocupation control forall (i in sections)
{ cfOcupacao[i] <= 1;
}
}
This model works indeed much better.
Philippe
#CPOptimizer#DecisionOptimization