Generated on Wed Nov 1 15:04:43 2006 for Gecode by doxygen 1.4.5

scheduling.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Mikael Lagerkvist, 2005
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-09-04 14:13:40 +0200 (Mon, 04 Sep 2006) $ by $Author: zayenz $
00010  *     $Revision: 3584 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
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     // Construct producer tasks
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     // Construct consumer tasks
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 // STATISTICS: minimodel-any