git-subtree-dir: software/gecode_on_replay git-subtree-split: 8051d92b9c89e49cccfbd1c201371580d7703ab4
537 lines
16 KiB
C++
537 lines
16 KiB
C++
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
/*
|
|
* Main authors:
|
|
* Christian Schulte <schulte@gecode.org>
|
|
*
|
|
* 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 <gecode/int.hh>
|
|
|
|
namespace Gecode { namespace Int {
|
|
|
|
/// Class to define an optional from a mandatory task
|
|
template<class ManTask>
|
|
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 <gecode/int/task/man-to-opt.hpp>
|
|
|
|
namespace Gecode { namespace Int {
|
|
|
|
/// Task mapper: turns a task view into its dual
|
|
template<class TaskView>
|
|
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 <gecode/int/task/fwd-to-bwd.hpp>
|
|
|
|
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 TaskView>
|
|
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 Task>
|
|
class TaskTraits {};
|
|
|
|
}}
|
|
|
|
namespace Gecode { namespace Int {
|
|
|
|
/// Task array
|
|
template<class Task>
|
|
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<Task>& a);
|
|
/// Initialize from task array \a a (share elements)
|
|
const TaskArray<Task>& operator =(const TaskArray<Task>& 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<class Char, class Traits, class Task>
|
|
std::basic_ostream<Char,Traits>&
|
|
operator <<(std::basic_ostream<Char,Traits>& os,
|
|
const TaskArray<Task>& t);
|
|
|
|
|
|
/// Task view array
|
|
template<class TaskView>
|
|
class TaskViewArray {
|
|
protected:
|
|
/// The underlying task type
|
|
typedef typename TaskViewTraits<TaskView>::Task Task;
|
|
/// Access to task array
|
|
TaskArray<Task>& t;
|
|
public:
|
|
/// \name Constructors and initialization
|
|
//@{
|
|
/// Initialize from task array \a a
|
|
TaskViewArray(TaskArray<Task>& 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<class Char, class Traits, class TaskView>
|
|
std::basic_ostream<Char,Traits>&
|
|
operator <<(std::basic_ostream<Char,Traits>& os,
|
|
const TaskViewArray<TaskView>& t);
|
|
|
|
}}
|
|
|
|
#include <gecode/int/task/array.hpp>
|
|
|
|
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<class TaskView, SortTaskOrder sto, bool inc>
|
|
void sort(TaskViewArray<TaskView>& t);
|
|
|
|
/// Initialize and sort \a map for task view array \a t according to \a sto and \a inc (increasing or decreasing)
|
|
template<class TaskView, SortTaskOrder sto, bool inc>
|
|
void sort(int* map, const TaskViewArray<TaskView>& 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<class TaskView, SortTaskOrder sto, bool inc>
|
|
void sort(int* map, int n, const TaskViewArray<TaskView>& t);
|
|
|
|
}}
|
|
|
|
#include <gecode/int/task/sort.hpp>
|
|
|
|
namespace Gecode { namespace Int {
|
|
|
|
/// Allows to iterate over task views according to a specified order
|
|
template<class TaskView, SortTaskOrder sto, bool inc>
|
|
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<TaskView>& 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 OptTaskView, SortTaskOrder sto, bool inc>
|
|
class ManTaskViewIter : public TaskViewIter<OptTaskView,sto,inc> {
|
|
protected:
|
|
using TaskViewIter<OptTaskView,sto,inc>::map;
|
|
using TaskViewIter<OptTaskView,sto,inc>::i;
|
|
public:
|
|
/// Initialize iterator with mandatory tasks
|
|
ManTaskViewIter(Region& r, const TaskViewArray<OptTaskView>& t);
|
|
};
|
|
|
|
}}
|
|
|
|
#include <gecode/int/task/iter.hpp>
|
|
|
|
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 TaskView, class Node>
|
|
class TaskTree {
|
|
template<class,class> friend class TaskTree;
|
|
protected:
|
|
/// The tasks from which the tree is computed
|
|
const TaskViewArray<TaskView>& 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<TaskView>& t);
|
|
/// Initialize tree using tree \a t
|
|
template<class Node2> TaskTree(Region& r,
|
|
const TaskTree<TaskView,Node2>& t);
|
|
};
|
|
|
|
}}
|
|
|
|
#include <gecode/int/task/tree.hpp>
|
|
|
|
namespace Gecode { namespace Int {
|
|
|
|
/**
|
|
* \brief %Propagator for tasks
|
|
*
|
|
* Requires \code #include <gecode/int/task.hh> \endcode
|
|
* \ingroup FuncIntProp
|
|
*/
|
|
template<class Task, class PL>
|
|
class TaskProp : public Propagator {
|
|
protected:
|
|
/// Tasks
|
|
TaskArray<Task> t;
|
|
/// Constructor for creation
|
|
TaskProp(Home home, TaskArray<Task>& t);
|
|
/// Constructor for cloning \a p
|
|
TaskProp(Space& home, TaskProp<Task,PL>& 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<class OptTask, class PL>
|
|
ExecStatus purge(Space& home, Propagator& p, TaskArray<OptTask>& t);
|
|
|
|
/// Purge optional tasks that are excluded and possibly rewrite propagator
|
|
template<class OptTask, class PL, class Cap>
|
|
ExecStatus purge(Space& home, Propagator& p, TaskArray<OptTask>& 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 <gecode/int/task/prop.hpp>
|
|
#include <gecode/int/task/purge.hpp>
|
|
|
|
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<class Task>
|
|
static Event* events(Region& r, const TaskArray<Task>& t, bool& assigned);
|
|
/// Allocate from \a r and initialize event array with assigned tasks \a t only
|
|
template<class Task>
|
|
static Event* events(Region& r, const TaskArray<Task>& t);
|
|
};
|
|
|
|
/// Print event \a e on stream \a os
|
|
template<class Char, class Traits>
|
|
std::basic_ostream<Char,Traits>&
|
|
operator <<(std::basic_ostream<Char,Traits>& os, const Event& e);
|
|
|
|
}}
|
|
|
|
#include <gecode/int/task/event.hpp>
|
|
|
|
#endif
|
|
|
|
// STATISTICS: int-prop
|