Generated on Tue Apr 18 10:22:00 2017 for Gecode by doxygen 1.6.3

event.hpp

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, 2015
00008  *
00009  *  Last modified:
00010  *     $Date: 2016-04-19 17:19:45 +0200 (Tue, 19 Apr 2016) $ by $Author: schulte $
00011  *     $Revision: 14967 $
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 namespace Gecode { namespace Int {
00039 
00040   forceinline void
00041   Event::init(Event::Type e0, int t0, int i0) {
00042     ei=static_cast<unsigned int>(e0 | (i0 << 3)); t=t0;
00043   }
00044 
00045   forceinline Event::Type
00046   Event::type(void) const {
00047     return static_cast<Type>(ei & 7);
00048   }
00049   forceinline int
00050   Event::time(void) const {
00051     return t;
00052   }
00053   forceinline int
00054   Event::idx(void) const {
00055     return static_cast<int>(ei >> 3);;
00056   }
00057 
00058   forceinline bool
00059   Event::operator <(const Event& e) const {
00060     if (time() == e.time())
00061       return type() < e.type();
00062     return time() < e.time();
00063   }
00064 
00065 
00066   template<class Char, class Traits>
00067   inline std::basic_ostream<Char,Traits>&
00068   operator <<(std::basic_ostream<Char,Traits>& os, const Event& e) {
00069     std::basic_ostringstream<Char,Traits> s;
00070     s.copyfmt(os); s.width(0);
00071     s << '[';
00072     switch (e.type()) {
00073     case Event::LRT: s << "LRT"; break;
00074     case Event::LCT: s << "LCT"; break;
00075     case Event::EST: s << "EST"; break;
00076     case Event::ZRO: s << "ZRO"; break;
00077     case Event::ERT: s << "ERT"; break;
00078     default: GECODE_NEVER;
00079     }
00080     s << ',' << e.time() << ',' << e.idx() << ']';
00081     return os << s.str();
00082   }
00083 
00084 
00085   template<class Task>
00086   forceinline Event*
00087   Event::events(Region& r, const TaskArray<Task>& t, bool& assigned) {
00088     Event* e = r.alloc<Event>(4*t.size()+1);
00089 
00090     // Initialize events
00091     assigned=true;
00092     bool required=false;
00093 
00094     int n=0;
00095     for (int i=t.size(); i--; )
00096       if (t[i].assigned()) {
00097         // Only add required part
00098         if (t[i].pmin() > 0) {
00099           required = true;
00100           e[n++].init(Event::ERT,t[i].lst(),i);
00101           e[n++].init(Event::LRT,t[i].ect(),i);
00102         } else if (t[i].pmax() == 0) {
00103           required = true;
00104           e[n++].init(Event::ZRO,t[i].lst(),i);
00105         }
00106       } else {
00107         assigned = false;
00108         e[n++].init(Event::EST,t[i].est(),i);
00109         e[n++].init(Event::LCT,t[i].lct(),i);
00110         // Check whether task has required part
00111         if (t[i].lst() < t[i].ect()) {
00112           required = true;
00113           e[n++].init(Event::ERT,t[i].lst(),i);
00114           e[n++].init(Event::LRT,t[i].ect(),i);
00115         }
00116       }
00117 
00118     if (!required)
00119       return NULL;
00120 
00121     // Sort events
00122     Support::quicksort(e, n);
00123 
00124     // Write end marker
00125     e[n++].init(Event::END,Limits::infinity,0);
00126 
00127     return e;
00128   }
00129 
00130   template<class Task>
00131   forceinline Event*
00132   Event::events(Region& r, const TaskArray<Task>& t) {
00133     Event* e = r.alloc<Event>(2*t.size()+1);
00134 
00135     // Only add assigned and mandatory tasks
00136     int n=0;
00137     for (int i=t.size(); i--; )
00138       if (t[i].assigned() && t[i].mandatory()) {
00139         if (t[i].pmin() > 0) {
00140           e[n++].init(Event::ERT,t[i].lst(),i);
00141           e[n++].init(Event::LRT,t[i].ect(),i);
00142         } else if (t[i].pmax() == 0) {
00143           e[n++].init(Event::ZRO,t[i].lst(),i);
00144         }
00145       } else {
00146         assert(!t[i].excluded());
00147         return NULL;
00148       }
00149 
00150     // Sort events
00151     Support::quicksort(e, n);
00152 
00153     // Write end marker
00154     e[n++].init(Event::END,Limits::infinity,0);
00155 
00156     return e;
00157   }
00158 
00159 }}
00160 
00161 // STATISTICS: int-prop