git-subtree-dir: software/gecode_on_replay git-subtree-split: 8051d92b9c89e49cccfbd1c201371580d7703ab4
331 lines
9.6 KiB
C++
331 lines
9.6 KiB
C++
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
/*
|
|
* Main authors:
|
|
* Christian Schulte <schulte@gecode.org>
|
|
* Guido Tack <tack@gecode.org>
|
|
*
|
|
* Copyright:
|
|
* Christian Schulte, 2002
|
|
* Guido Tack, 2004
|
|
*
|
|
* 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_VIEW_VAL_GRAPH_HH
|
|
#define GECODE_INT_VIEW_VAL_GRAPH_HH
|
|
|
|
#include <gecode/int.hh>
|
|
|
|
/**
|
|
* \namespace Gecode::Int::ViewValGraph
|
|
* \brief Support classes for propagators using a view-value graph
|
|
*/
|
|
namespace Gecode { namespace Int { namespace ViewValGraph {
|
|
|
|
/**
|
|
* \brief Class for combining two pointers with a flag
|
|
*
|
|
* When one pointer is given, the other can be retrieved.
|
|
*
|
|
*/
|
|
template<class T>
|
|
class CombPtrFlag {
|
|
private:
|
|
/// Store pointer and flag
|
|
ptrdiff_t cpf;
|
|
public:
|
|
/// Initialize with pointer \a p1 and \a p2
|
|
CombPtrFlag(T* p1, T* p2);
|
|
/// Initialize with pointer \a p1 and \a p2
|
|
void init(T* p1, T* p2);
|
|
/// Return the other pointer when \a p is given
|
|
T* ptr(T* p) const;
|
|
/// Check whether flag is set
|
|
int is_set(void) const;
|
|
/// Set flag
|
|
void set(void);
|
|
/// Clear flag
|
|
void unset(void);
|
|
};
|
|
|
|
/// Bidirectional links for edges and anchors in nodes of view-value graph
|
|
class BiLink {
|
|
private:
|
|
/// Link to previous element
|
|
BiLink* _prev;
|
|
/// Link to next element
|
|
BiLink* _next;
|
|
public:
|
|
/// Initialize as empty (self referenced)
|
|
BiLink(void);
|
|
/// Return previous element
|
|
BiLink* prev(void) const;
|
|
/// Return next element
|
|
BiLink* next(void) const;
|
|
/// Set previous element to \a l
|
|
void prev(BiLink* l);
|
|
/// Set next element to \a l
|
|
void next(BiLink* l);
|
|
/// Add \a l after this element
|
|
void add(BiLink* l);
|
|
/// Unlink this element
|
|
void unlink(void);
|
|
/// Mark element (invalidates next element pointer)
|
|
void mark(void);
|
|
/// Whether element is marked
|
|
bool marked(void) const;
|
|
/// Whether element has no previous and next element
|
|
bool empty(void) const;
|
|
};
|
|
|
|
|
|
template<class View> class Edge;
|
|
|
|
/**
|
|
* \brief Base-class for nodes (both view and value nodes)
|
|
*
|
|
* Note: the obvious ill-design to have also nodes and edges
|
|
* parametric wrt View is because the right design (having template
|
|
* function members) gets miscompiled (and actually not even compiled
|
|
* with some C++ compilers). Duh!
|
|
*
|
|
*/
|
|
template<class View>
|
|
class Node : public BiLink {
|
|
public:
|
|
/// Next edge for computing strongly connected components
|
|
Edge<View>* iter;
|
|
/// Values for computing strongly connected components
|
|
unsigned int low, min, comp;
|
|
/// Initialize
|
|
Node(void);
|
|
/// Return first edge (organized by bi-links)
|
|
Edge<View>* edge_fst(void) const;
|
|
/// Return last edge (organized by bi-links)
|
|
Edge<View>* edge_lst(void) const;
|
|
|
|
/// Allocate memory from space
|
|
static void* operator new(size_t, Space&);
|
|
/// Needed for exceptions
|
|
static void operator delete(void*, size_t);
|
|
/// Needed for exceptions
|
|
static void operator delete(void*,Space&);
|
|
};
|
|
|
|
/**
|
|
* \brief Value nodes in view-value graph
|
|
*
|
|
*/
|
|
template<class View>
|
|
class ValNode : public Node<View> {
|
|
protected:
|
|
/// The value of the node
|
|
const int _val;
|
|
/// The matching edge
|
|
Edge<View>* _matching;
|
|
/// The next value node
|
|
ValNode<View>* _next_val;
|
|
public:
|
|
/// Initialize with value \a v
|
|
ValNode(int v);
|
|
/// Initialize with value \a v and successor \a n
|
|
ValNode(int v, ValNode<View>* n);
|
|
/// Return value of node
|
|
int val(void) const;
|
|
/// Set matching edge to \a m
|
|
void matching(Edge<View>* m);
|
|
/// Return matching edge (nullptr if unmatched)
|
|
Edge<View>* matching(void) const;
|
|
/// Return pointer to next value node fields
|
|
ValNode<View>** next_val_ref(void);
|
|
/// Return next value node
|
|
ValNode<View>* next_val(void) const;
|
|
/// Set next value node to \a v
|
|
void next_val(ValNode<View>* v);
|
|
};
|
|
|
|
/**
|
|
* \brief View nodes in view-value graph
|
|
*
|
|
*/
|
|
template<class View>
|
|
class ViewNode : public Node<View> {
|
|
protected:
|
|
/// The size of the view after last change
|
|
unsigned int _size;
|
|
/// The node's view
|
|
View _view;
|
|
/// The first value edge
|
|
Edge<View>* _val_edges;
|
|
public:
|
|
/// Initialize node for a non-view
|
|
ViewNode(void);
|
|
/// Initialize new node for view \a x
|
|
ViewNode(View x);
|
|
/// Return first edge of all value edges
|
|
Edge<View>* val_edges(void) const;
|
|
/// Return pointer to first edge fields of all value edges
|
|
Edge<View>** val_edges_ref(void);
|
|
/// Test whether node has a fake view
|
|
bool fake(void) const;
|
|
/// Return view
|
|
View view(void) const;
|
|
/// Update size of view after change
|
|
void update(void);
|
|
/// Return whether view has changed its size
|
|
bool changed(void) const;
|
|
/// Whether the node is matched
|
|
bool matched(void) const;
|
|
};
|
|
|
|
/**
|
|
* \brief Edges in view-value graph
|
|
*
|
|
*/
|
|
template<class View>
|
|
class Edge : public BiLink {
|
|
protected:
|
|
/// Next edge in chain of value edges
|
|
Edge<View>* _next_edge;
|
|
/// Combine source and destination node and flag
|
|
CombPtrFlag<Node<View> > sd;
|
|
public:
|
|
/// Construct new edge between \a x and \a v
|
|
Edge(ValNode<View>* v, ViewNode<View>* x);
|
|
/// Construct new edge between \a x and \a v with next edge \a n
|
|
Edge(ValNode<View>* v, ViewNode<View>* x, Edge<View>* n);
|
|
/// Return destination of edge when source \a s is given
|
|
Node<View>* dst(Node<View>* s) const;
|
|
|
|
/// Return view node when value node \a v is given
|
|
ViewNode<View>* view(ValNode<View>* v) const;
|
|
/// Return value node when view node \a x is given
|
|
ValNode<View>* val(ViewNode<View>* x) const;
|
|
|
|
/// Whether edge is used (marked or between nodes from the same scc)
|
|
bool used(Node<View>* v) const;
|
|
/// Mark node as used
|
|
void use(void);
|
|
/// Unmark node as used
|
|
void free(void);
|
|
|
|
/// Revert edge to node \a d for matching
|
|
void revert(Node<View>* d);
|
|
|
|
/// Return next edge in list of value edges
|
|
Edge<View>* next_edge(void) const;
|
|
/// Return reference to next edge in list of value edges
|
|
Edge<View>** next_edge_ref(void);
|
|
/// Return next edge in list of edges per node
|
|
Edge<View>* next(void) const;
|
|
|
|
/// Allocate memory from space
|
|
static void* operator new(size_t, Space&);
|
|
/// Needed for exceptions
|
|
static void operator delete(void*, size_t);
|
|
/// Needed for exceptions
|
|
static void operator delete(void*,Space&);
|
|
};
|
|
|
|
/// Iterates the values to be pruned from a view node
|
|
template<class View>
|
|
class IterPruneVal {
|
|
protected:
|
|
/// View node
|
|
ViewNode<View>* x;
|
|
/// Current value edge
|
|
Edge<View>* e;
|
|
public:
|
|
/// \name Constructors and initialization
|
|
//@{
|
|
/// Initialize with edges for view node \a x
|
|
IterPruneVal(ViewNode<View>* x);
|
|
//@}
|
|
|
|
/// \name Iteration control
|
|
//@{
|
|
/// Test whether iterator is still at a value or done
|
|
bool operator ()(void) const;
|
|
/// Move iterator to next value (if possible)
|
|
void operator ++(void);
|
|
//@}
|
|
|
|
/// \name Value access
|
|
//@{
|
|
/// Return current value
|
|
int val(void) const;
|
|
//@}
|
|
};
|
|
|
|
}}}
|
|
|
|
#include <gecode/int/view-val-graph/comb-ptr-flag.hpp>
|
|
#include <gecode/int/view-val-graph/bi-link.hpp>
|
|
#include <gecode/int/view-val-graph/edge.hpp>
|
|
#include <gecode/int/view-val-graph/node.hpp>
|
|
#include <gecode/int/view-val-graph/iter-prune-val.hpp>
|
|
|
|
namespace Gecode { namespace Int { namespace ViewValGraph {
|
|
|
|
/// View-value graph base class
|
|
template<class View>
|
|
class Graph {
|
|
protected:
|
|
/// Array of view nodes
|
|
ViewNode<View>** view;
|
|
/// Array of value nodes
|
|
ValNode<View>* val;
|
|
/// Number of view nodes
|
|
int n_view;
|
|
/// Number of value nodes
|
|
int n_val;
|
|
/// Marking counter
|
|
unsigned int count;
|
|
/// Stack used during matching
|
|
typedef Support::StaticStack<ViewNode<View>*,Region> ViewNodeStack;
|
|
/// Initialize the edges for the view node \a x
|
|
void init(Space& home, ViewNode<View>* x);
|
|
/// Find a matching for node \a x
|
|
bool match(ViewNodeStack& m, ViewNode<View>* x);
|
|
/// Compute the strongly connected components
|
|
void scc(void);
|
|
public:
|
|
/// Construct graph as not yet initialized
|
|
Graph(void);
|
|
/// Test whether graph has been initialized
|
|
operator bool(void) const;
|
|
/// Purge graph if necessary (reset information to avoid overflow)
|
|
void purge(void);
|
|
};
|
|
|
|
}}}
|
|
|
|
#include <gecode/int/view-val-graph/graph.hpp>
|
|
|
|
#endif
|
|
|
|
// STATISTICS: int-prop
|
|
|