Generated on Thu Mar 22 10:39:35 2012 for Gecode by doxygen 1.6.3

cumulative.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2009
00008  *
00009  *  Last modified:
00010  *     $Date: 2011-07-13 11:03:39 +0200 (Wed, 13 Jul 2011) $ by $Author: tack $
00011  *     $Revision: 12180 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "test/int.hh"
00039 
00040 #include <gecode/minimodel.hh>
00041 
00042 namespace Test { namespace Int {
00043 
00045   namespace Cumulative {
00046 
00052 
00053     class ManFixPCumulative : public Test {
00054     protected:
00056       int c;
00058       Gecode::IntArgs p;
00060       Gecode::IntArgs u;
00062       static int st(int c, 
00063                     const Gecode::IntArgs& p, const Gecode::IntArgs& u) {
00064         double e = 0;
00065         for (int i=p.size(); i--; )
00066           e += static_cast<double>(p[i])*u[i];
00067         return e / std::max(1,std::abs(c));
00068       }
00070       int o;
00071     public:
00073       ManFixPCumulative(int c0, 
00074                        const Gecode::IntArgs& p0,
00075                        const Gecode::IntArgs& u0,
00076                        int o0)
00077         : Test("Cumulative::Man::Fix::"+str(o0)+"::"+
00078                str(c0)+"::"+str(p0)+"::"+str(u0),
00079                (c0 >= 0) ? p0.size():p0.size()+1,0,st(c0,p0,u0)), 
00080           c(c0), p(p0), u(u0), o(o0) {
00081         testsearch = false;
00082         testfix = false;
00083         contest = CTL_NONE;
00084       }
00086       virtual Assignment* assignment(void) const {
00087         return new RandomAssignment(arity,dom,500);
00088       }
00090       virtual bool solution(const Assignment& x) const {
00091         int cmax = (c >= 0) ? c : x[x.size()-1];
00092         int n = (c >= 0) ? x.size() : x.size()-1;
00093         
00094         if (c < 0 && x[n] > -c)
00095           return false;
00096         
00097         // Compute maximal time
00098         int t = 0;
00099         for (int i=0; i<n; i++)
00100           t = std::max(t,x[i]+std::max(1,p[i]));
00101         // Compute resource usage (including at start times)
00102         int* used = new int[t];
00103         for (int i=0; i<t; i++)
00104           used[i] = 0;
00105         for (int i=0; i<n; i++)
00106           for (int t=0; t<p[i]; t++)
00107             used[x[i]+t] += u[i];
00108         // Check resource usage
00109         for (int i=0; i<t; i++)
00110           if (used[i] > cmax) {
00111             delete [] used;
00112             return false;
00113           }
00114         // Compute resource usage (only internal)
00115         for (int i=0; i<t; i++)
00116           used[i] = 0;
00117         for (int i=0; i<n; i++) {
00118           for (int t=1; t<p[i]; t++) {
00119             used[x[i]+t] += u[i];
00120           }
00121         }
00122         // Check resource usage at start times
00123         for (int i=0; i<n; i++)
00124           if (used[x[i]]+u[i] > cmax) {
00125             delete [] used;
00126             return false;
00127           }
00128         delete [] used;
00129         return true;
00130       }
00132       virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00133         int n = (c >= 0) ? x.size() : x.size()-1;
00134         Gecode::IntVarArgs xx;
00135         if (o==0) {
00136           xx=x.slice(0,1,n);
00137         } else {
00138           xx=Gecode::IntVarArgs(n);
00139           for (int i=n; i--;)
00140             xx[i]=Gecode::expr(home,x[i]+o,Gecode::ICL_DOM);
00141         }
00142         if (c >= 0) {
00143           Gecode::cumulative(home, c, xx, p, u);
00144         } else {
00145           Gecode::rel(home, x[n] <= -c);
00146           Gecode::cumulative(home, x[n], xx, p, u);
00147         }
00148       }
00149     };
00150 
00151 
00153     class OptFixPCumulative : public Test {
00154     protected:
00156       int c;
00158       Gecode::IntArgs p;
00160       Gecode::IntArgs u;
00162       int l;
00164       int o;
00166       static int st(int c, 
00167                     const Gecode::IntArgs& p, const Gecode::IntArgs& u) {
00168         double e = 0;
00169         for (int i=p.size(); i--; )
00170           e += static_cast<double>(p[i])*u[i];
00171         return e / std::max(1,std::abs(c));
00172       }
00173     public:
00175       OptFixPCumulative(int c0, 
00176                         const Gecode::IntArgs& p0,
00177                         const Gecode::IntArgs& u0,
00178                         int o0)
00179         : Test("Cumulative::Opt::Fix::"+str(o0)+"::"+
00180                str(c0)+"::"+str(p0)+"::"+str(u0),
00181                (c0 >= 0) ? 2*p0.size() : 2*p0.size()+1,0,st(c0,p0,u0)), 
00182           c(c0), p(p0), u(u0), l(st(c,p,u)/2), o(o0) {
00183         testsearch = false;
00184         testfix = false;
00185         contest = CTL_NONE;
00186       }
00188       virtual Assignment* assignment(void) const {
00189         return new RandomAssignment(arity,dom,500);
00190       }
00192       virtual bool solution(const Assignment& x) const {
00193         int nn = (c >= 0) ? x.size() : x.size()-1;
00194         int cmax = (c >= 0) ? c : x[nn];
00195 
00196         if (c < 0 && x[nn] > -c)
00197           return false;
00198 
00199         int n = nn / 2;
00200         // Compute maximal time
00201         int t = 0;
00202         for (int i=0; i<n; i++)
00203           t = std::max(t,x[i]+std::max(1,p[i]));
00204         // Compute resource usage (including at start times)
00205         int* used = new int[t];
00206         for (int i=0; i<t; i++)
00207           used[i] = 0;
00208         for (int i=0; i<n; i++)
00209           if (x[n+i] > l)
00210             for (int t=0; t<p[i]; t++)
00211               used[x[i]+t] += u[i];
00212         // Check resource usage
00213         for (int i=0; i<t; i++) {
00214           if (used[i] > cmax) {
00215             delete [] used;
00216             return false;
00217           }
00218         }
00219         // Compute resource usage (only internal)
00220         for (int i=0; i<t; i++)
00221           used[i] = 0;
00222         for (int i=0; i<n; i++)
00223           if (x[n+i] > l) {
00224             for (int t=1; t<p[i]; t++)
00225               used[x[i]+t] += u[i];
00226           }
00227         // Check resource usage at start times
00228         for (int i=0; i<n; i++)
00229           if (x[n+i] > l)
00230             if (used[x[i]]+u[i] > cmax) {
00231               delete [] used;
00232               return false;
00233             }
00234         delete [] used;
00235         return true;
00236       }
00238       virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00239         int nn=(c >= 0) ? x.size() : x.size()-1;
00240         int n=nn / 2;
00241         Gecode::IntVarArgs s(n);
00242         Gecode::BoolVarArgs m(n);
00243 
00244         for (int i=0; i<n; i++) {
00245           s[i]=(c >= 0) ? x[i] : Gecode::expr(home,x[i]+o,Gecode::ICL_DOM);
00246           m[i]=Gecode::expr(home, x[n+i] > l);
00247         }
00248 
00249         if (c >= 0) {
00250           Gecode::cumulative(home, c, s, p, u, m);
00251         } else {
00252           Gecode::rel(home, x[nn] <= -c);
00253           Gecode::cumulative(home, x[nn], s, p, u, m);
00254         }
00255       }
00256     };
00257 
00259     class ManFlexCumulative : public Test {
00260     protected:
00262       int c;
00264       int _minP;
00266       int _maxP;
00268       Gecode::IntArgs u;
00270       static int st(int c, int maxP, const Gecode::IntArgs& u) {
00271         double e = 0;
00272         for (int i=u.size(); i--; )
00273           e += static_cast<double>(maxP)*u[i];
00274         return e / std::max(1,std::abs(c));
00275       }
00277       int o;
00278     public:
00280       ManFlexCumulative(int c0, int minP, int maxP,
00281                         const Gecode::IntArgs& u0,
00282                         int o0)
00283         : Test("Cumulative::Man::Flex::"+str(o0)+"::"+
00284                str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0),
00285                (c0 >= 0) ? 2*u0.size() : 2*u0.size()+1,
00286                0,std::max(maxP,st(c0,maxP,u0))), 
00287           c(c0), _minP(minP), _maxP(maxP), u(u0), o(o0) {
00288         testsearch = false;
00289         testfix = false;
00290         contest = CTL_NONE;
00291       }
00293       virtual Assignment* assignment(void) const {
00294         return new RandomMixAssignment((c >= 0) ? arity/2 : arity/2+1,
00295                                        dom,arity/2,
00296                                        Gecode::IntSet(_minP,_maxP),500);
00297       }
00299       virtual bool solution(const Assignment& x) const {
00300         int nn = (c >= 0) ? x.size() : x.size()-1;
00301         int n = nn/2;
00302         int cmax = (c >= 0) ? c : x[n];
00303         int pstart = (c >= 0) ? n : n+1;
00304 
00305         if (c < 0 && cmax > -c)
00306           return false;
00307 
00308         // Compute maximal time
00309         int t = 0;
00310         for (int i=0; i<n; i++) {
00311           t = std::max(t,x[i]+std::max(1,x[pstart+i]));
00312         }
00313         // Compute resource usage (including at start times)
00314         int* used = new int[t];
00315         for (int i=0; i<t; i++)
00316           used[i] = 0;
00317         for (int i=0; i<n; i++)
00318           for (int t=0; t<x[pstart+i]; t++)
00319             used[x[i]+t] += u[i];
00320         // Check resource usage
00321         for (int i=0; i<t; i++)
00322           if (used[i] > cmax) {
00323             delete [] used;
00324             return false;
00325           }
00326         // Compute resource usage (only internal)
00327         for (int i=0; i<t; i++)
00328           used[i] = 0;
00329         for (int i=0; i<n; i++) {
00330           for (int t=1; t<x[pstart+i]; t++)
00331             used[x[i]+t] += u[i];
00332         }
00333         // Check resource usage at start times
00334         for (int i=0; i<n; i++)
00335           if (used[x[i]]+u[i] > cmax) {
00336             delete [] used;
00337             return false;
00338           }
00339         delete [] used;
00340         return true;
00341       }
00343       virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00344         int nn = (c >= 0) ? x.size() : x.size()-1;
00345         int n = nn/2;
00346         int pstart = (c >= 0) ? n : n+1;
00347         Gecode::IntVarArgs s(n);
00348         Gecode::IntVarArgs px(x.slice(pstart,1,n));
00349         Gecode::IntVarArgs e(home,n,
00350                              Gecode::Int::Limits::min,
00351                              Gecode::Int::Limits::max);
00352         for (int i=s.size(); i--;) {
00353           s[i] = expr(home, o+x[i], Gecode::ICL_DOM);
00354           rel(home, s[i]+px[i] == e[i]);
00355           rel(home, _minP <= px[i]);
00356           rel(home, _maxP >= px[i]);
00357         }
00358         if (c >= 0) {
00359           Gecode::cumulative(home, c, s, px, e, u);
00360         } else {
00361           rel(home, x[n] <= -c);
00362           Gecode::cumulative(home, x[n], s, px, e, u);
00363         }
00364       }
00365     };
00366 
00368     class OptFlexCumulative : public Test {
00369     protected:
00371       int c;
00373       int _minP;
00375       int _maxP;
00377       Gecode::IntArgs u;
00379       int l;
00381       int o;
00383       static int st(int c, int maxP, const Gecode::IntArgs& u) {
00384         double e = 0;
00385         for (int i=u.size(); i--; )
00386           e += static_cast<double>(maxP)*u[i];
00387         return e / std::max(1,std::abs(c));
00388       }
00389     public:
00391       OptFlexCumulative(int c0, int minP, int maxP,
00392                         const Gecode::IntArgs& u0,
00393                         int o0)
00394         : Test("Cumulative::Opt::Flex::"+str(o0)+"::"+
00395                str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0),
00396                (c0 >= 0) ? 3*u0.size() : 3*u0.size()+1,
00397                0,std::max(maxP,st(c0,maxP,u0))), 
00398           c(c0), _minP(minP), _maxP(maxP), u(u0), 
00399           l(std::max(maxP,st(c0,maxP,u0))/2), o(o0) {
00400         testsearch = false;
00401         testfix = false;
00402         contest = CTL_NONE;
00403       }
00405       virtual Assignment* assignment(void) const {
00406         return new RandomMixAssignment((c >= 0) ? 2*(arity/3) : 2*(arity/3)+1,
00407                                        dom,arity/3,
00408                                        Gecode::IntSet(_minP,_maxP),500);
00409       }
00411       virtual bool solution(const Assignment& x) const {
00412         int nn = (c >= 0) ? x.size() : x.size()-1;
00413         int n = nn / 3;
00414         int cmax = (c >= 0) ? c : x[2*n];
00415         int pstart = (c >= 0) ? 2*n : 2*n+1;
00416         
00417         if (c < 0 && cmax > -c)
00418           return false;
00419         
00420         // Compute maximal time
00421         int t = 0;
00422         for (int i=0; i<n; i++)
00423           t = std::max(t,x[i]+std::max(1,x[pstart+i]));
00424         // Compute resource usage (including at start times)
00425         int* used = new int[t];
00426         for (int i=0; i<t; i++)
00427           used[i] = 0;
00428         for (int i=0; i<n; i++)
00429           if (x[n+i] > l)
00430             for (int t=0; t<x[pstart+i]; t++)
00431               used[x[i]+t] += u[i];
00432         // Check resource usage
00433         for (int i=0; i<t; i++)
00434           if (used[i] > cmax) {
00435             delete [] used;
00436             return false;
00437           }
00438         // Compute resource usage (only internal)
00439         for (int i=0; i<t; i++)
00440           used[i] = 0;
00441         for (int i=0; i<n; i++)
00442           if (x[n+i] > l)
00443             for (int t=1; t<x[pstart+i]; t++)
00444               used[x[i]+t] += u[i];
00445         // Check resource usage at start times
00446         for (int i=0; i<n; i++)
00447           if (x[n+i] > l && used[x[i]]+u[i] > cmax) {
00448             delete [] used;
00449             return false;
00450           }
00451         delete [] used;
00452         return true;
00453       }
00455       virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) {
00456         int nn = (c >= 0) ? x.size() : x.size()-1;
00457         int n=nn / 3;
00458         int pstart= (c >= 0) ? 2*n : 2*n+1;
00459 
00460         Gecode::IntVarArgs s(n);
00461         Gecode::IntVarArgs px(n);
00462         Gecode::IntVarArgs e(home,n,
00463                              Gecode::Int::Limits::min,
00464                              Gecode::Int::Limits::max);
00465         for (int i=n; i--;) {
00466           s[i] = expr(home, o+x[i]);
00467           px[i] = x[pstart+i];
00468           rel(home, s[i]+px[i] == e[i]);
00469           rel(home, _minP <= px[i]);
00470           rel(home, _maxP >= px[i]);
00471         }
00472         Gecode::BoolVarArgs m(n);
00473         for (int i=0; i<n; i++)
00474           m[i]=Gecode::expr(home, (x[n+i] > l));
00475         if (c >= 0) {
00476           Gecode::cumulative(home, c, s, px, e, u, m);
00477         } else {
00478           Gecode::rel(home, x[2*n] <= -c);
00479           Gecode::cumulative(home, x[2*n], s, px, e, u, m);
00480         }
00481       }
00482     };
00483 
00485     class Create {
00486     public:
00488       Create(void) {
00489         using namespace Gecode;
00490         IntArgs p1(4, 1,1,1,1);
00491         IntArgs p2(4, 2,2,2,2);
00492         IntArgs p3(4, 4,3,3,5);
00493         IntArgs p4(4, 4,0,3,5);
00494 
00495         IntArgs u1(4, 1,1,1,1);
00496         IntArgs u2(4, 2,2,2,2);
00497         IntArgs u3(4, 2,3,4,5);
00498 
00499         for (int c=-7; c<8; c++) {
00500           int off = 0;
00501           for (int coff=0; coff<2; coff++) {
00502             (void) new ManFixPCumulative(c,p1,u1,off);
00503             (void) new ManFixPCumulative(c,p1,u2,off);
00504             (void) new ManFixPCumulative(c,p1,u3,off);
00505             (void) new ManFixPCumulative(c,p2,u1,off);
00506             (void) new ManFixPCumulative(c,p2,u2,off);
00507             (void) new ManFixPCumulative(c,p2,u3,off);
00508             (void) new ManFixPCumulative(c,p3,u1,off);
00509             (void) new ManFixPCumulative(c,p3,u2,off);
00510             (void) new ManFixPCumulative(c,p3,u3,off);
00511             (void) new ManFixPCumulative(c,p4,u1,off);
00512             (void) new ManFixPCumulative(c,p4,u2,off);
00513             (void) new ManFixPCumulative(c,p4,u3,off);
00514 
00515             (void) new ManFlexCumulative(c,0,1,u1,off);
00516             (void) new ManFlexCumulative(c,0,1,u2,off);
00517             (void) new ManFlexCumulative(c,0,1,u3,off);
00518             (void) new ManFlexCumulative(c,0,2,u1,off);
00519             (void) new ManFlexCumulative(c,0,2,u2,off);
00520             (void) new ManFlexCumulative(c,0,2,u3,off);
00521             (void) new ManFlexCumulative(c,3,5,u1,off);
00522             (void) new ManFlexCumulative(c,3,5,u2,off);
00523             (void) new ManFlexCumulative(c,3,5,u3,off);
00524 
00525             (void) new OptFixPCumulative(c,p1,u1,off);
00526             (void) new OptFixPCumulative(c,p1,u2,off);
00527             (void) new OptFixPCumulative(c,p1,u3,off);
00528             (void) new OptFixPCumulative(c,p2,u1,off);
00529             (void) new OptFixPCumulative(c,p2,u2,off);
00530             (void) new OptFixPCumulative(c,p2,u3,off);
00531             (void) new OptFixPCumulative(c,p3,u1,off);
00532             (void) new OptFixPCumulative(c,p3,u2,off);
00533             (void) new OptFixPCumulative(c,p3,u3,off);
00534             (void) new OptFixPCumulative(c,p4,u1,off);
00535             (void) new OptFixPCumulative(c,p4,u2,off);
00536             (void) new OptFixPCumulative(c,p4,u3,off);
00537 
00538             (void) new OptFlexCumulative(c,0,1,u1,off);
00539             (void) new OptFlexCumulative(c,0,1,u2,off);
00540             (void) new OptFlexCumulative(c,0,1,u3,off);
00541             (void) new OptFlexCumulative(c,0,2,u1,off);
00542             (void) new OptFlexCumulative(c,0,2,u2,off);
00543             (void) new OptFlexCumulative(c,0,2,u3,off);
00544             (void) new OptFlexCumulative(c,3,5,u1,off);
00545             (void) new OptFlexCumulative(c,3,5,u2,off);
00546             (void) new OptFlexCumulative(c,3,5,u3,off);
00547 
00548             off = Gecode::Int::Limits::min;
00549           }
00550         }
00551       }
00552     };
00553 
00554     Create c;
00556 
00557   }
00558 }}
00559 
00560 // STATISTICS: test-int