Facebook
From Flying Tortoise, 4 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 130
  1. int: nr; % number of reclaimers
  2.            % number of rails = nr for stages A,B,C,D,E
  3.            % number of rails = (nr + 1) div 2 for stage F
  4. set of int: RECLAIMER = 1..nr;
  5. bool: stageF; % is this stage F data
  6.  
  7. int: ns; % number of stockpiles
  8. set of int: STOCKPILE = 1..ns;
  9. array[STOCKPILE] of int: size; % size in 10000 tonnes
  10. array[STOCKPILE] of SHIP: ship; % which ship carries stockpile
  11.  
  12. int: maxtime; % time considered
  13. set of int: TIME = 0..maxtime;
  14.  
  15. int: nsh; % number of ships
  16. set of int: SHIP = 1..nsh;
  17. array[SHIP] of TIME: arrival; % when ship arrives in port
  18.  
  19. int: len; % length of pad
  20. set of int: POSITION = 0..len;
  21.  
  22. int: stack_time;
  23. int: reclaim_time;
  24. int: reclaim_speed;
  25.  
  26. array[STOCKPILE] of var POSITION: westend;
  27. array[STOCKPILE] of var POSITION: eastend;
  28. array[STOCKPILE] of var TIME: stack;
  29. array[STOCKPILE] of var TIME: endstack;
  30. array[STOCKPILE] of var TIME: reclaim;
  31. array[STOCKPILE] of var TIME: finished;
  32. array[STOCKPILE] of var RECLAIMER: which;
  33.  
  34.  
  35. % Go crazy here
  36.  
  37. % Stage A - Packing Problem
  38. % Two stockpiles can't overlap in "spacetime"
  39.  
  40.  
  41. % 1) what's the relation between endstack and stack times
  42. constraint forall(s in STOCKPILE)(stack[s] + stack_time*size[s] = endstack[s]);
  43. % 2) what's the relation between finished and stack times
  44. constraint forall(s in STOCKPILE)(stack[s] < finished[s]);
  45. % 3) what's the relation between reclaim and endstack times
  46. constraint forall(s in STOCKPILE)(endstack[s] <= reclaim[s]);
  47. % 4) what's the relation between finished and reclam times
  48. constraint forall(s in STOCKPILE)(reclaim[s] + reclaim_time*size[s] = finished[s]);
  49. % constraint forall(s in STOCKPILE)(reclaim[s] + reclaim_time*size[s] + reclaim_speed*(size[s]-1) = finished[s]);
  50. % 5) what's the relation between eastend and westend offsets
  51. constraint forall(s in STOCKPILE)(westend[s] + size[s]= eastend[s]);
  52. % 6) packing problem
  53. %    a) stockpiles should not overlap in "spacetime", treat them as rectangles
  54. %    b) stockpiles can't use more space than there is available
  55. %    c) we can't go beyond the time limit
  56.  
  57. % constraint diffn(westend, stack, size, [stack_time*i|i in size ]);
  58. constraint forall(s1, s2 in STOCKPILE where s1<s2)
  59. (eastend[s1]<=westend[s2] \/ finished[s1]<= stack[s2] \/ westend[s1] >= eastend[s2] \/ stack[s1]>=finished[s2]);
  60.  
  61. constraint forall(s in STOCKPILE)(eastend[s]<=len);
  62. constraint forall(s in STOCKPILE)(finished[s]<=maxtime);
  63.  
  64.  
  65. % Stage B
  66. % Two stockpiles reclaimed by the same reclaimer do not overlap in time
  67. %
  68. % Tip: write your first custom predicate, i.e.
  69.  
  70. predicate not_overlap(var STOCKPILE: s1, var STOCKPILE: s2) =
  71.      finished[s1] <= reclaim[s2] \/ reclaim[s1] >= finished[s2];
  72.  
  73.  
  74. constraint forall(s1, s2 in STOCKPILE where (s1<s2) /\ which[s1]=which[s2])(not_overlap(s1,s2));
  75.  
  76. % Stage C
  77. % 1) no stockpile can be reclaimed onto a ship before the arrival time of the ship
  78. constraint forall(s in STOCKPILE)(arrival[ship[s]] <= reclaim[s]);
  79. % 2) also no two stockpiles can be reclaimed onto the same ship at the same time. Make sure these reclaims do not overlap in time.
  80. % TIP: reuse your "not_overlap" predicate
  81. constraint forall(s1, s2 in STOCKPILE where s1<s2 /\ ship[s1]=ship[s2])(not_overlap(s1,s2));
  82.  
  83. % Stage D
  84. % Add constraints to your model to ensure that if a reclaimer finishes reclaiming a stockpile with westend at x and then has to start reclaiming a stockpile with westend at y there is at least |y − x| ∗ reclaim speed time between these two events.
  85. % TIP: just make your "not_overlap" predicate smarter
  86. % TIP: you can introduce local variables in the constraints/predicates
  87. % let {
  88. %  <local variables>
  89. % } in <then something>
  90.  
  91. constraint forall(s1, s2 in STOCKPILE where s1<s2 /\ which[s1]=which[s2])
  92. (let{var POSITION: dif = (abs(westend[s1]-westend[s2])* reclaim_speed)} in reclaim[s1]!=reclaim[s2] /\ if (reclaim[s1] < reclaim[s2]) then (reclaim[s2] - finished[s1] >= dif) else (reclaim[s1] - finished[s2] >= dif) endif);
  93.  
  94.  
  95. % Stage E
  96. % Add a definition of the objective to your model and change the model to minimize this value.
  97. % You may well need to significantly change your search strategy to get good solutions for the objective.
  98.  
  99. % TIP: definetely change the line below
  100. function var int: getSumShipStay() =  sum([ '-'( max([ finished[s] | s in STOCKPILE where ship[s] = sh ]), arrival[sh]) | sh in SHIP]);
  101.  
  102. var int: obj = getSumShipStay();
  103.  
  104. % Stage F
  105. % Add constraints in your model so that the two reclaimers on rail i numbered 2i − 1 and 2i for i ∈ 1..nr div 2 remain so the western one 2i − 1 is never east of the eastern one 2i. Note they can legitimately be in the same position (this is for simplicity, its not very real). Note that if there are
  106. % an odd number of reclaimers the last reclaimer is on its own rail and has no further constraints.
  107. % TIP: do some "channeling" and model reclaimers' positions explicitely with a new array of variables.
  108.  
  109. % set of int: DOUBLE_RAILS = 0..nr div 2-1;
  110.  
  111. constraint stageF -> (
  112.   let { int: rails = nr div 2 } in
  113.     forall(rail in 1..rails)(
  114.       let {
  115.         int: r1 = 2 * rail - 1,
  116.         int: r2 = 2 * rail} in forall(s1, s2 in STOCKPILE where which[s1]=r1 /\ which[s2]=r2)(eastend[s1] <= westend[s2])));
  117.  
  118. % solve minimize obj;
  119. solve :: int_search(finished, input_order, indomain_min, complete) minimize obj;
  120.  
  121. % don't change the output
  122. output
  123. ["westend  = ", show(westend), ";\n"] ++
  124. ["eastend  = ", show(eastend), ";\n"] ++
  125. ["stack    = ", show(stack), ";\n"] ++
  126. ["endstack = ", show(endstack), ";\n"] ++
  127. ["reclaim  = ", show(reclaim), ";\n"] ++
  128. ["finish   = ", show(finished) , ";\n"] ++
  129. ["which    = ", show(which), ";\n"] ++
  130. ["obj = ",show(obj),";\n"]
  131. ;
  132.