3
* Mikael Lagerkvist <lagerkvist@gecode.org>
6
* Mikael Lagerkvist, 2005
9
* $Date: 2005-08-05 10:53:14 +0200 (Fri, 05 Aug 2005) $ by $Author: zayenz $
12
* This file is part of Gecode, the generic constraint
13
* development environment:
14
* http://www.gecode.org
16
* See the file "LICENSE" for information on usage and
17
* redistribution of this file, and for a
18
* DISCLAIMER OF ALL WARRANTIES.
22
#include "minimodel.hh"
31
producer_consumer(Space *home,
32
const IntVarArgs& produce_date, const IntArgs& produce_amount,
33
const IntVarArgs& consume_date, const IntArgs& consume_amount,
34
int initial, IntConLevel cl)
36
if(produce_date.size() != produce_amount.size() ||
37
consume_date.size() != consume_amount.size())
38
throw new ArgumentSizeMismatch("Minimodel::producer_consumer");
40
int ntasks = produce_date.size() + consume_date.size();
42
IntArgs machine(ntasks), height(ntasks), limit(1);
43
IntVarArgs start(ntasks), duration(ntasks), end(ntasks);
46
int sum_height = initial;
47
if(initial < Limits::Int::int_min ||
48
initial > Limits::Int::int_max)
49
throw new NumericalOverflow("MiniModel::producer_consumer");
52
for (int j = produce_date.size(); j--; )
53
maxval = std::max(produce_date[i].max(), maxval);
54
for (int j = consume_date.size(); j--; )
55
maxval = std::max(consume_date[j].max(), maxval);
58
IntVar minvar = IntVar(home, 0, 0);
59
IntVar maxvar = IntVar(home, maxval, maxval);
62
// Construct producer tasks
63
for (int k = produce_date.size(); k--; ++i) {
64
sum_height += produce_amount[k];
68
end[i] = produce_date[k];
69
duration[i] = IntVar(home, end[i].min(), end[i].max());
70
height[i] = produce_amount[k];
71
if(height[i] < Limits::Int::int_min ||
72
height[i] > Limits::Int::int_max)
73
throw new NumericalOverflow("MiniModel::producer_consumer");
76
// Construct consumer tasks
77
for (int k = consume_date.size(); k--; ++i) {
80
start[i] = consume_date[k];
82
duration[i] = IntVar(home, maxval - start[i].max(),
83
maxval - start[i].min());
84
height[i] = consume_amount[k];
85
if(height[i] < Limits::Int::int_min ||
86
height[i] > Limits::Int::int_max)
87
throw new NumericalOverflow("MiniModel::producer_consumer");
90
limit[0] = sum_height;
92
cumulatives(home, machine, start, duration, end, height, limit, true, cl);
96
template<class In> class ArgType;
99
class ArgType<IntArgs> {
101
typedef IntArgs Result;
105
class ArgType<IntVarArgs> {
107
typedef IntView Result;
115
ConstVar(Space *home, int val) : home_(home), val_(val) {}
117
operator int() { return val_; }
118
operator IntVar() { return IntVar(home_, val_, val_); }
121
IntVar make_intvar(Space *home, int val)
123
return IntVar(home, val, val);
126
IntVar make_intvar(Space *home, IntVar iv)
131
template<class Duration, class Height>
133
post_cumulative(Space *home, const IntVarArgs& start, const Duration& duration,
134
const Height& height, int limit, bool at_most, IntConLevel cl)
136
if(start.size() != duration.size() ||
137
duration.size() != height.size())
138
throw new ArgumentSizeMismatch("MiniModel::cumulative");
140
if(limit < Limits::Int::int_min ||
141
limit > Limits::Int::int_max)
142
throw new NumericalOverflow("MiniModel::cumulative");
144
int n = start.size() + !at_most;
145
IntArgs m(n), l(1, limit);
146
IntVarArgs s(n), d(n), e(n);
150
int smin, smax, emin, emax;
152
for (int i = start.size(); i--; ) {
155
smin = std::min(s[i].min(), smin);
156
smax = std::max(s[i].max(), smax);
157
d[i] = make_intvar(home, duration[i]);
158
e[i] = IntVar(home, Limits::Int::int_min, Limits::Int::int_max);
159
//s[i].min()+d[i].min(), s[i].max()+d[i].max());
161
emin = std::min(e[i].min(), emin);
162
emax = std::max(e[i].max(), emax);
166
s[n-1] = IntVar(home, smin, smax);
167
d[n-1] = IntVar(home, 0, emax - smin);
168
e[n-1] = IntVar(home, emin, emax);
169
h[n-1] = ConstVar(home, 0);
171
min(home, start, s[n-1]);
172
max(home, end, e[n-1]);
174
for (int i = start.size(); i--; ) {
177
d[i] = make_intvar(home, duration[i]);
178
e[i] = IntVar(home, s[i].min()+d[i].min(), s[i].max()+d[i].max());
183
cumulatives(home, m, s, d, e, h, l, at_most, cl);
189
cumulative(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
190
const IntVarArgs& height, int limit, bool at_most, IntConLevel cl)
192
post_cumulative(home, start, duration, height, limit, at_most, cl);
196
cumulative(Space *home, const IntVarArgs& start, const IntArgs& duration,
197
const IntVarArgs& height, int limit, bool at_most, IntConLevel cl)
199
post_cumulative(home, start, duration, height, limit, at_most, cl);
203
cumulative(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
204
const IntArgs& height, int limit, bool at_most, IntConLevel cl)
206
post_cumulative(home, start, duration, height, limit, at_most, cl);
210
cumulative(Space *home, const IntVarArgs& start, const IntArgs& duration,
211
const IntArgs& height, int limit, bool at_most, IntConLevel cl)
213
post_cumulative(home, start, duration, height, limit, at_most, cl);
218
template <class Duration>
220
post_serialized(Space *home, const IntVarArgs& start, const Duration& duration,
223
if(start.size() != duration.size())
224
throw new ArgumentSizeMismatch("MiniModel::serialized");
226
IntArgs height(start.size());
227
for (int i = start.size(); i--; ) height[i] = 1;
229
post_cumulative(home, start, duration, height, 1, true, cl);
234
serialized(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
237
post_serialized(home, start, duration, cl);
242
serialized(Space *home, const IntVarArgs& start, const IntArgs& duration,
245
post_serialized(home, start, duration, cl);
250
// STATISTICS: minimodel-any