00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/minimodel.hh"
00023
00024 #include <algorithm>
00025
00026 namespace Gecode {
00027
00028 using namespace Int;
00029
00030 void
00031 producer_consumer(Space *home,
00032 const IntVarArgs& produce_date, const IntArgs& produce_amount,
00033 const IntVarArgs& consume_date, const IntArgs& consume_amount,
00034 int initial, IntConLevel cl)
00035 {
00036 if (produce_date.size() != produce_amount.size() ||
00037 consume_date.size() != consume_amount.size())
00038 throw new ArgumentSizeMismatch("Minimodel::producer_consumer");
00039
00040 int ntasks = produce_date.size() + consume_date.size();
00041
00042 IntArgs machine(ntasks), height(ntasks), limit(1);
00043 IntVarArgs start(ntasks), duration(ntasks), end(ntasks);
00044
00045 int i = 0;
00046 int sum_height = initial;
00047 if (initial < Limits::Int::int_min ||
00048 initial > Limits::Int::int_max)
00049 throw new NumericalOverflow("MiniModel::producer_consumer");
00050
00051 int maxval = 0;
00052 for (int j = produce_date.size(); j--; )
00053 maxval = std::max(produce_date[i].max(), maxval);
00054 for (int j = consume_date.size(); j--; )
00055 maxval = std::max(consume_date[j].max(), maxval);
00056 ++maxval;
00057
00058 IntVar minvar = IntVar(home, 0, 0);
00059 IntVar maxvar = IntVar(home, maxval, maxval);
00060
00061
00062
00063 for (int k = produce_date.size(); k--; ++i) {
00064 sum_height += produce_amount[k];
00065 machine[i] = 0;
00066
00067 start[i] = minvar;
00068 end[i] = produce_date[k];
00069 duration[i] = IntVar(home, end[i].min(), end[i].max());
00070 height[i] = produce_amount[k];
00071 if (height[i] < Limits::Int::int_min ||
00072 height[i] > Limits::Int::int_max)
00073 throw new NumericalOverflow("MiniModel::producer_consumer");
00074 }
00075
00076
00077 for (int k = consume_date.size(); k--; ++i) {
00078 machine[i] = 0;
00079
00080 start[i] = consume_date[k];
00081 end[i] = maxvar;
00082 duration[i] = IntVar(home, maxval - start[i].max(),
00083 maxval - start[i].min());
00084 height[i] = consume_amount[k];
00085 if (height[i] < Limits::Int::int_min ||
00086 height[i] > Limits::Int::int_max)
00087 throw new NumericalOverflow("MiniModel::producer_consumer");
00088 }
00089
00090 limit[0] = sum_height;
00091
00092 cumulatives(home, machine, start, duration, end, height, limit, true, cl);
00093 }
00094
00095
00096 namespace {
00098 class ConstVar {
00099 Space *home_;
00100 int val_;
00101 public:
00102 ConstVar(Space *home, int val) : home_(home), val_(val) {}
00103
00104 operator int() { return val_; }
00105 operator IntVar() { return IntVar(home_, val_, val_); }
00106 };
00107
00109 IntVar make_intvar(Space *home, int val)
00110 {
00111 return IntVar(home, val, val);
00112 }
00113
00115 IntVar make_intvar(Space *home, IntVar iv)
00116 {
00117 return iv;
00118 }
00119
00120 template<class Duration, class Height>
00121 void
00122 post_cumulative(Space *home, const IntVarArgs& start, const Duration& duration,
00123 const Height& height, int limit, bool at_most, IntConLevel cl)
00124 {
00125 if (start.size() != duration.size() ||
00126 duration.size() != height.size())
00127 throw new ArgumentSizeMismatch("MiniModel::cumulative");
00128
00129 if (limit < Limits::Int::int_min ||
00130 limit > Limits::Int::int_max)
00131 throw new NumericalOverflow("MiniModel::cumulative");
00132
00133 int n = start.size() + !at_most;
00134 IntArgs m(n), l(1, limit);
00135 IntVarArgs s(n), d(n), e(n);
00136 Height h(n);
00137
00138 if (!at_most) {
00139 int smin = Limits::Int::int_max,
00140 smax = Limits::Int::int_min,
00141 emin = Limits::Int::int_max,
00142 emax = Limits::Int::int_min;
00143 IntVarArgs end(n-1);
00144 for (int i = start.size(); i--; ) {
00145 m[i] = 0;
00146 s[i] = start[i];
00147 smin = std::min(s[i].min(), smin);
00148 smax = std::max(s[i].max(), smax);
00149 d[i] = make_intvar(home, duration[i]);
00150 e[i] = IntVar(home, Limits::Int::int_min, Limits::Int::int_max);
00151 end[i] = e[i];
00152 emin = std::min(e[i].min(), emin);
00153 emax = std::max(e[i].max(), emax);
00154 h[i] = height[i];
00155 }
00156 m[n-1] = 0;
00157 s[n-1] = IntVar(home, smin, smax);
00158 d[n-1] = IntVar(home, 0, emax - smin);
00159 e[n-1] = IntVar(home, emin, emax);
00160 h[n-1] = ConstVar(home, 0);
00161
00162 min(home, start, s[n-1]);
00163 max(home, end, e[n-1]);
00164 } else {
00165 for (int i = start.size(); i--; ) {
00166 m[i] = 0;
00167 s[i] = start[i];
00168 d[i] = make_intvar(home, duration[i]);
00169 e[i] = IntVar(home, s[i].min()+d[i].min(), s[i].max()+d[i].max());
00170 h[i] = height[i];
00171 }
00172 }
00173
00174 cumulatives(home, m, s, d, e, h, l, at_most, cl);
00175 }
00176
00177 }
00178
00179 void
00180 cumulative(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
00181 const IntVarArgs& height, int limit, bool at_most, IntConLevel cl)
00182 {
00183 post_cumulative(home, start, duration, height, limit, at_most, cl);
00184 }
00185
00186 void
00187 cumulative(Space *home, const IntVarArgs& start, const IntArgs& duration,
00188 const IntVarArgs& height, int limit, bool at_most, IntConLevel cl)
00189 {
00190 post_cumulative(home, start, duration, height, limit, at_most, cl);
00191 }
00192
00193 void
00194 cumulative(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
00195 const IntArgs& height, int limit, bool at_most, IntConLevel cl)
00196 {
00197 post_cumulative(home, start, duration, height, limit, at_most, cl);
00198 }
00199
00200 void
00201 cumulative(Space *home, const IntVarArgs& start, const IntArgs& duration,
00202 const IntArgs& height, int limit, bool at_most, IntConLevel cl)
00203 {
00204 post_cumulative(home, start, duration, height, limit, at_most, cl);
00205 }
00206
00207
00208 namespace {
00209 template <class Duration>
00210 void
00211 post_serialized(Space *home, const IntVarArgs& start, const Duration& duration,
00212 IntConLevel cl)
00213 {
00214 if (start.size() != duration.size())
00215 throw new ArgumentSizeMismatch("MiniModel::serialized");
00216
00217 IntArgs height(start.size());
00218 for (int i = start.size(); i--; ) height[i] = 1;
00219
00220 post_cumulative(home, start, duration, height, 1, true, cl);
00221 }
00222 }
00223
00224 void
00225 serialized(Space *home, const IntVarArgs& start, const IntVarArgs& duration,
00226 IntConLevel cl)
00227 {
00228 post_serialized(home, start, duration, cl);
00229 }
00230
00231
00232 void
00233 serialized(Space *home, const IntVarArgs& start, const IntArgs& duration,
00234 IntConLevel cl)
00235 {
00236 post_serialized(home, start, duration, cl);
00237 }
00238
00239 }
00240
00241