/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte * * Copyright: * Christian Schulte, 2009 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef GECODE_INT_TASK_HH #define GECODE_INT_TASK_HH #include namespace Gecode { namespace Int { /// Class to define an optional from a mandatory task template class ManToOptTask : public ManTask { protected: /// Boolean view whether task is mandatory (= 1) or not Int::BoolView _m; public: /// \name Constructors and initialization //@{ /// Default constructor ManToOptTask(void); //@} /// \name Value access //@{ /// Whether task is mandatory bool mandatory(void) const; /// Whether task is excluded bool excluded(void) const; /// Whether task can still be optional bool optional(void) const; //@} //@{ /// Test whether task is assigned bool assigned(void) const; //@} /// \name Value update //@{ /// Mark task as mandatory ModEvent mandatory(Space& home); /// Mark task as excluded ModEvent excluded(Space& home); //@} /// \name Cloning //@{ /// Update this task to be a clone of task \a t void update(Space& home, ManToOptTask& t); //@} /// \name Dependencies //@{ /// Subscribe propagator \a p to task void subscribe(Space& home, Propagator& p, PropCond pc); /// Cancel subscription of propagator \a p for task void cancel(Space& home, Propagator& p, PropCond pc); /// Schedule propagator \a p void reschedule(Space& home, Propagator& p, PropCond pc); //@} }; }} #include namespace Gecode { namespace Int { /// Task mapper: turns a task view into its dual template class FwdToBwd : public TaskView { public: /// \name Value access //@{ /// Return earliest start time int est(void) const; /// Return earliest completion time int ect(void) const; /// Return latest start time int lst(void) const; /// Return latest completion time int lct(void) const; /// Return minimum processing time int pmin(void) const; /// Return maximum processing time int pmax(void) const; //@} /// \name Value update //@{ /// Update earliest start time to \a n ModEvent est(Space& home, int n); /// Update earliest completion time to \a n ModEvent ect(Space& home, int n); /// Update latest start time to \a n ModEvent lst(Space& home, int n); /// Update latest completion time to \a n ModEvent lct(Space& home, int n); /// Update such that task cannot run from \a e to \a l ModEvent norun(Space& home, int e, int l); //@} }; }} #include namespace Gecode { namespace Int { /** * \brief Traits class for mapping task views to tasks * * Each task view must specialize this traits class and add a \code * typedef \endcode for the task corresponding to this task view. */ template class TaskViewTraits {}; /** * \brief Traits class for mapping tasks to task views * * Each task must specialize this traits class and add \code * typedef \endcode for the task views corresponding to this task. */ template class TaskTraits {}; }} namespace Gecode { namespace Int { /// Task array template class TaskArray { private: /// Number of tasks (size) int n; /// Tasks Task* t; public: /// \name Constructors and initialization //@{ /// Default constructor (array of size 0) TaskArray(void); /// Allocate memory for \a n tasks (no initialization) TaskArray(Space& home, int n); /// Initialize from task array \a a (share elements) TaskArray(const TaskArray& a); /// Initialize from task array \a a (share elements) const TaskArray& operator =(const TaskArray& a); //@} /// \name Array size //@{ /// Return size of array (number of elements) int size(void) const; /// Set size of array (number of elements) to \a n, must not be larger void size(int n); //@} /// \name Array elements //@{ /// Return task at position \a i Task& operator [](int i); /// Return task at position \a i const Task& operator [](int i) const; //@} /// \name Dependencies //@{ /// Subscribe propagator \a p to all tasks void subscribe(Space& home, Propagator& p, PropCond pc=Int::PC_INT_BND); /// Cancel subscription of propagator \a p for all tasks void cancel(Space& home, Propagator& p, PropCond pc=Int::PC_INT_BND); /// Schedule propagator \a p void reschedule(Space& home, Propagator& p, PropCond pc=Int::PC_INT_BND); //@} /// \name Cloning //@{ /// Update array to be a clone of array \a a void update(Space&, TaskArray& a); //@} private: static void* operator new(size_t); static void operator delete(void*,size_t); }; /** * \brief Print array elements enclosed in curly brackets * \relates TaskArray */ template std::basic_ostream& operator <<(std::basic_ostream& os, const TaskArray& t); /// Task view array template class TaskViewArray { protected: /// The underlying task type typedef typename TaskViewTraits::Task Task; /// Access to task array TaskArray& t; public: /// \name Constructors and initialization //@{ /// Initialize from task array \a a TaskViewArray(TaskArray& t); //@} /// \name Array information //@{ /// Return size of array (number of elements) int size(void) const; /// Set size of array (number of elements) to \a n, must not be larger void size(int n); //@} /// \name Array elements //@{ /// Return task view at position \a i TaskView& operator [](int i); /// Return task view at position \a i const TaskView& operator [](int i) const; //@} private: static void* operator new(size_t); static void operator delete(void*,size_t); }; /** * \brief Print array elements enclosed in curly brackets * \relates TaskViewArray */ template std::basic_ostream& operator <<(std::basic_ostream& os, const TaskViewArray& t); }} #include namespace Gecode { namespace Int { /// How to sort tasks enum SortTaskOrder { STO_EST, ///< Sort by earliest start times STO_ECT, ///< Sort by earliest completion times STO_LST, ///< Sort by latest start times STO_LCT ///< Sort by latest completion times }; /// Sort task view array \a t according to \a sto and \a inc (increasing or decreasing) template void sort(TaskViewArray& t); /// Initialize and sort \a map for task view array \a t according to \a sto and \a inc (increasing or decreasing) template void sort(int* map, const TaskViewArray& t); /// Sort \a map with size \a n for task view array \a t according to \a sto and \a inc (increasing or decreasing) template void sort(int* map, int n, const TaskViewArray& t); }} #include namespace Gecode { namespace Int { /// Allows to iterate over task views according to a specified order template class TaskViewIter { protected: /// Map for iteration order int* map; /// Current position int i; /// Default constructor (no initialization) TaskViewIter(void); public: /// Initialize iterator TaskViewIter(Region& r, const TaskViewArray& t); /// \name Iteration control //@{ /// Test whether iterator is still at a task bool operator ()(void) const; /// How many tasks are left to be iterated int left(void) const; /// Move iterator to next task void operator ++(void); //@} /// \name %Task access //@{ /// Return current task position int task(void) const; //@} }; /// Allows to iterate over mandatory task views according to a specified order template class ManTaskViewIter : public TaskViewIter { protected: using TaskViewIter::map; using TaskViewIter::i; public: /// Initialize iterator with mandatory tasks ManTaskViewIter(Region& r, const TaskViewArray& t); }; }} #include namespace Gecode { namespace Int { /// Safe addition in case \a x is -Int::Limits::infinity int plus(int x, int y); /// Safe addition in case \a x is -Int::Limits::llinfinity long long int plus(long long int x, long long int y); /// Safe addition in case \a x is -Int::Limits::double_infinity double plus(double x, double y); /// Task trees for task views with node type \a Node template class TaskTree { template friend class TaskTree; protected: /// The tasks from which the tree is computed const TaskViewArray& tasks; /// Task nodes Node* node; /// Map task number to leaf node number in right order int* _leaf; /// Return number of inner nodes int n_inner(void) const; /// Return number of nodes for balanced binary tree int n_nodes(void) const; /// Whether node \a i is index of root static bool n_root(int i); /// Whether node \a i is leaf bool n_leaf(int i) const; /// Return index of left child of node \a i static int n_left(int i); /// Test whether node \a i is a left child static bool left(int i); /// Return index of right child of node \a i static int n_right(int i); /// Test whether node \a i is a right child static bool right(int i); /// Return index of parent of node \a i static int n_parent(int i); protected: /// Return leaf for task \a i Node& leaf(int i); /// Return root node const Node& root(void) const; /// Update tree after leaf for task \a i has changed (\a l whether i refers to a leaf) void update(int i, bool l=true); /// Initialize tree after leaves have been initialized void init(void); /// Update all inner nodes of tree after leaves have been initialized void update(void); /// Initialize tree for tasks \a t TaskTree(Region& r, const TaskViewArray& t); /// Initialize tree using tree \a t template TaskTree(Region& r, const TaskTree& t); }; }} #include namespace Gecode { namespace Int { /** * \brief %Propagator for tasks * * Requires \code #include \endcode * \ingroup FuncIntProp */ template class TaskProp : public Propagator { protected: /// Tasks TaskArray t; /// Constructor for creation TaskProp(Home home, TaskArray& t); /// Constructor for cloning \a p TaskProp(Space& home, TaskProp& p); public: /// Cost function (defined as high linear) virtual PropCost cost(const Space& home, const ModEventDelta& med) const; /// Schedule function virtual void reschedule(Space& home); /// Delete propagator and return its size virtual size_t dispose(Space& home); }; /// Purge optional tasks that are excluded and possibly rewrite propagator template ExecStatus purge(Space& home, Propagator& p, TaskArray& t); /// Purge optional tasks that are excluded and possibly rewrite propagator template ExecStatus purge(Space& home, Propagator& p, TaskArray& t, Cap c); /// Class for defining basic propagation level class PLB { public: /// Perform basic propagation static const bool basic = true; /// Do not perform advanced propagation static const bool advanced = false; /// For basic propagation, domain operations are needed static const PropCond pc = PC_INT_DOM; }; /// Class for defining advanced propagation level class PLA { public: /// Perform basic propagation static const bool basic = false; /// Do not perform advanced propagation static const bool advanced = true; /// For basic propagation, domain operations are needed static const PropCond pc = PC_INT_BND; }; /// Class for defining basic and advanced propagation level class PLBA { public: /// Perform basic propagation static const bool basic = true; /// Do not perform advanced propagation static const bool advanced = true; /// For basic propagation, domain operations are needed static const PropCond pc = PC_INT_DOM; }; }} #include #include namespace Gecode { namespace Int { /// Time-tabling event for task class Event { public: /// Event type for task with order in which they are processed enum Type { LRT = 0, ///< Latest required time of task LCT = 1, ///< Latest completion time of task EST = 2, ///< Earliest start time of task ZRO = 3, ///< Zero-length task start time ERT = 4, ///< Earliest required time of task END = 5 ///< End marker }; protected: /// Combines type and number of task unsigned int ei; /// Time of event int t; public: /// Initialize event void init(Type e, int t, int i); /// Return event type Type type(void) const; /// Return event time int time(void) const; /// Return event index int idx(void) const; /// Order among events bool operator <(const Event& e) const; /// Allocate from \a r and initialize event array with tasks \a t template static Event* events(Region& r, const TaskArray& t, bool& assigned); /// Allocate from \a r and initialize event array with assigned tasks \a t only template static Event* events(Region& r, const TaskArray& t); }; /// Print event \a e on stream \a os template std::basic_ostream& operator <<(std::basic_ostream& os, const Event& e); }} #include #endif // STATISTICS: int-prop