1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | /* Car sequencing in B-Prolog. Based on the OPL3 model car.mod. This model is based on the car sequencing model in Pascal Van Hentenryck 'The OPL Optimization Programming Language' , page 184ff. (Via other implementations: ) Model created by Hakan Kjellerstrand, hakank @gmail .com */ % Licenced under CC-BY-4.0 : http://creativecommons.org/licenses/by/4.0/ go :- NbCars = 6, Cars = 1..NbCars, NbOptions = 5, Options = 1..NbOptions, NbSlots = 10, Slots = 1..NbSlots, Demand = [1, 1, 2, 2, 2, 2], Option = [[1, 0, 0, 0, 1, 1], [0, 0, 1, 1, 0, 1], [1, 0, 0, 0, 1, 0], [1, 1, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0]], Capacity = [[1,2], [2,3], [1,3], [2,5], [1,5]], %% This don't work: % OptionDemand @= [sum([Demand[J]*Option[I,J] : J in Cars]) : I in Options], % Have to use an accumulator ac/2 foreach (I in Options,ac(OptionDemandTmp,[]),[OD], ( OD #= sum([ Demand[J]*Option[I,J] : J in Cars]), OptionDemandTmp^1 = [OD|OptionDemandTmp^0] ) ), reverse (OptionDemandTmp,OptionDemand), % % decision variables % length (Slot,NbSlots), Slot :: 1..NbCars, new_array(Setup,[NbOptions,NbSlots]), array_to_list(Setup,SetupVars), SetupVars :: 0..1, % To minimize Z #= sum([S*Slot[S] : S in Cars]), % % Constraints % foreach (C in Cars, sum([(Slot[S] #= C) : S in Slots]) #= Demand[C] ), foreach (O in Options, S in 1..NbSlots - Capacity[O,2] + 1, sum([Setup[O,J] : J in S..S + Capacity[O,2]- 1]) #=< Capacity[O,1] ), %% This don't work % foreach (O in Options, S in Slots, % Setup[O,S] #= Option[O,Slot[S]] % ), %% Instead one has to use a couple of element/3. foreach (O in Options, S in Slots, [SlotS,SS], (element(S,Slot,SlotS), matrix_element(Option,O,SlotS,SS), Setup[O,S] #= SS )), foreach (O in Options, I in 1..OptionDemand[O], ( sum([Setup[O,S] : S in 1..(NbSlots - I * Capacity[O,2])]) #>= (OptionDemand[O] - I * Capacity[O,1]) ) ), term_variables([Slot,SetupVars], Vars), minof(labeling(Vars),Z), writeln(z:Z), writeln(slot:Slot), SetupRows @= Setup^rows, foreach (Row in SetupRows, writeln(Row)), nl. matrix_element(X, I, J, Val) :- element(I, X, Row), element(J, Row, Val). |