92 bool type(
void)
const;
102 int index(
void)
const;
122 static void*
operator new(
size_t s,
Space& home);
124 static void operator delete(
void*,
Space&) {};
126 static void operator delete(
void*) {};
223 bool sink(
void)
const;
227 int kmin(
void)
const;
229 int kmax(
void)
const;
247 int cap(
BC bc)
const;
249 void cap(
BC bc,
int c);
373 static void*
operator new(
size_t s,
Space& home);
375 static void operator delete(
void*,
Space&) {};
377 static void operator delete(
void*) {};
489 void dfs(
Node*, BitSet&, BitSet&,
int[],
490 NodeStack&, NodeStack&,
int&);
495 void*
operator new(
size_t t,
Space& home);
497 void operator delete(
void*,
Space&) {}
510 :
e(nullptr),
fst(nullptr),
lst(nullptr),
ie(nullptr),
idx(i),
511 nf(static_cast<unsigned char>(nf0)),
noe(0) {}
559 Node::operator
new(
size_t s,
Space& home) {
560 return home.ralloc(s);
629 int kidx,
int kshift,
int count) :
818 if (
this == x->first()) {
819 Edge** ref = x->adj();
824 if (
this == x->last())
828 Edge* pv = prev_vedge;
829 Edge* nv = next_vedge;
835 if (
this == v->first()) {
836 Edge** ref = v->adj();
840 if (
this == v->last())
847 next_edge(nullptr), prev_edge(nullptr),
848 next_vedge(nullptr), prev_vedge(nullptr), ef(EF_NONE) {}
867 return (ef & EF_MRKUB) != 0;
869 return (ef & EF_MRKLB) != 0;
914 assert(x !=
nullptr);
920 assert(v !=
nullptr);
938 x->unmatch(bc); v->unmatch(bc);
965 x->set_match(bc,
this);
972 return (ef & EF_UM) != 0;
974 return (ef & EF_LM) != 0;
990 return (ef & EF_DEL) != 0;
994 Edge::operator
new(
size_t s,
Space& home) {
995 return home.ralloc(s);
1003 template<
class Card>
1009 n_node(n_var + n_val),
1016 for (
int i = n_val; i--; ) {
1017 int kmi = k[i].min();
1018 int kma = k[i].max();
1019 int kc = k[i].counter();
1029 vals[i] =
new (home)
1030 ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
1032 vals[i] =
new (home)
1033 ValNode(0, 0, k[i].card(), i, i + n_var, kc);
1037 for (
int i = n_var; i--; ) {
1038 vars[i] =
new (home)
VarNode(i);
1040 Edge** xadjacent = vars[i]->adj();
1045 while(vals[j]->val < xi.val())
1047 *xadjacent =
new (home)
Edge(vars[i],vals[j]);
1049 if (vars[i]->first() ==
nullptr)
1050 vars[i]->first(*xadjacent);
1051 Edge* oldprev = vars[i]->last();
1052 vars[i]->last(*xadjacent);
1053 *vars[i]->last()->
prev_ref() = oldprev;
1055 if (vals[j]->first() ==
nullptr) {
1056 vals[j]->first(*xadjacent);
1057 vals[j]->last(*xadjacent);
1059 Edge* old = vals[j]->first();
1060 vals[j]->first(*xadjacent);
1065 xadjacent = (*xadjacent)->
next_ref();
1067 *xadjacent =
nullptr;
1072 template<
class Card>
1077 for (
int i = n_val; i--; ) {
1080 if (k[i].
min() == vln->
noe) {
1092 assert(vrn->
noe == 1);
1094 int vi = vrn->
index();
1097 vars[vi] = vars[--n_var];
1098 vars[vi]->index(vi);
1105 int vidx = vln->
kindex();
1106 if (Card::propagate)
1109 k[vidx].counter(k[vidx].
min());
1115 if (sum_min >= k[vidx].
min())
1116 sum_min -= k[vidx].min();
1117 if (sum_max >= k[vidx].
max())
1118 sum_max -= k[vidx].max();
1121 vals[i]->cap(
UBC,0);
1122 vals[i]->cap(
LBC,0);
1128 if (Card::propagate && (k[i].counter() == 0))
1132 for (
int i = n_val; i--; )
1133 vals[i]->index(n_var + i);
1138 template<
class Card>
template<BC bc>
1142 NodeStack ns(r,n_node);
1143 BitSet visited(r,
static_cast<unsigned int>(n_node));
1150 bool sp = sn->
type();
1155 for (
int i = n_node; i--; )
1157 vals[i-n_var]->inedge(
nullptr);
1158 start[i] = vals[i-n_var]->first();
1160 vars[i]->inedge(
nullptr);
1161 start[i] = vars[i]->first();
1166 visited.
set(
static_cast<unsigned int>(v->
index()));
1167 while (!ns.
empty()) {
1170 if (vv->
type() == sp) {
1171 e = start[vv->
index()];
1172 while ((e !=
nullptr) && e->
matched(bc))
1175 e = start[vv->
index()];
1176 while ((e !=
nullptr) && !e->
matched(bc))
1178 start[vv->
index()] = e;
1183 if (!visited.
get(
static_cast<unsigned int>(w->
index()))) {
1185 bool m = w->
type() ?
1186 static_cast<ValNode*
>(w)->matched(bc) :
1187 static_cast<VarNode*
>(w)->matched(bc);
1188 if (!m && w->
type() != sp) {
1189 if (vv->
inedge() !=
nullptr) {
1201 visited.
set(
static_cast<unsigned int>(w->
index()));
1212 bool pathfound = !ns.
empty();
1214 while (!ns.
empty()) {
1218 if (t->
type() != sp) {
1231 template<
class Card>
1236 NodeStack re(r,2*n_node);
1239 if (Card::propagate) {
1240 for (
int i = n_val; i--; ) {
1248 int rm = v->
kmax() - k[i].max();
1250 if ((k[i].
max() < v->
kmax()) || (k[i].min() > v->
kmin())) {
1251 if ((k[i].
max() != k[i].counter()) || (k[i].
max() == 0)) {
1257 if (inc_ubc <= k[i].
max()) {
1271 int matched = inc_ubc - v->
kcount();
1276 if (inc_lbc < k[i].
min() && v->
noe > 0) {
1282 for (
int i = n_var; i--; ) {
1283 Edge* mub = vars[i]->get_match(
UBC);
1284 if (mub !=
nullptr) {
1296 assert(x.
size() == n_var);
1297 for (
int i = n_var; i--; ) {
1300 if (
static_cast<int>(x[i].size()) != vrn->
noe) {
1302 if (x[i].assigned()) {
1305 if ((mub !=
nullptr) && (v != mub->
getVal()->
val)) {
1311 if (mlb !=
nullptr) {
1313 if (v != vln->
val) {
1322 if (vln->
val != v) {
1340 while ((e !=
nullptr) && (e->
getVal()->
val < xiter.
val())) {
1361 while (e !=
nullptr) {
1369 if ((mub !=
nullptr) && mub->
deleted()) {
1375 if ((mlb !=
nullptr) && mlb->
deleted()) {
1386 for (
int i = n_val; i--; ) {
1387 if ((k[i].
min() > vals[i]->noe) && (k[i].counter() == 0))
1389 vals[i]->index(n_var + i);
1393 while (!re.
empty()) {
1412 template<
class Card>
template<BC bc>
1416 for (
int i = n_var; i--; )
1417 if (vars[i]->noe == 1) {
1425 for (
int i = n_val; i--; ) {
1427 if (Card::propagate && (k[i].counter() == 0))
1430 if (Card::propagate)
1439 k[i].counter(v->
kcount());
1441 if (Card::propagate)
1448 if (vrn->
noe == 1) {
1451 int vi= vrn->
index();
1454 vars[vi] = vars[--n_var];
1455 vars[vi]->index(vi);
1460 }
else if (delall) {
1471 if (sum_min >= k[vidx].
min())
1472 sum_min -= k[vidx].min();
1473 if (sum_max >= k[vidx].
max())
1474 sum_max -= k[vidx].max();
1476 }
else if (v->
kcount() > 0) {
1481 for (
int i = n_var; i--; )
1484 for (
int i = n_val; i--; ) {
1485 if (vals[i]->noe == 0) {
1486 vals[i]->cap(
UBC,0);
1487 vals[i]->cap(
LBC,0);
1490 vals[i]->index(n_var + i);
1493 for (
int i = n_var; i--; ) {
1494 if (vars[i]->noe > 1) {
1495 for (
Edge* e = vars[i]->first(); e !=
nullptr; e = e->
next()) {
1496 if (!e->matched(bc) && !e->used(bc)) {
1507 template<
class Card>
template<BC bc>
1513 for (
int i = n_val; i--; )
1514 for (
Edge* e = vals[i]->first(); e != nullptr ; e = e->
vnext())
1515 if (!e->getVar()->matched(bc) && !vals[i]->matched(bc)) {
1516 e->match(bc); card_match++;
1522 if (card_match < sum_min) {
1526 for (
int i = n_val; i--; )
1527 if (!vals[i]->matched(
LBC))
1530 while (!free.
empty()) {
1545 if (card_match < n_var) {
1549 for (
int i = n_var; i--; )
1550 if (!vars[i]->matched(
UBC))
1553 while (!free.
empty()) {
1571 template<
class Card>
template<BC bc>
1575 NodeStack ns(r,n_node);
1576 BitSet visited(r,
static_cast<unsigned int>(n_node));
1583 for (
int i = n_var; i--; )
1584 if (!vars[i]->matched(
LBC)) {
1586 visited.
set(
static_cast<unsigned int>(vars[i]->index()));
1588 for (
int i = n_val; i--; )
1589 if (!vals[i]->matched(
LBC)) {
1591 visited.
set(
static_cast<unsigned int>(vals[i]->index()));
1597 for (
int i = n_val; i--; )
1598 if (!vals[i]->matched(
UBC)) {
1600 visited.
set(
static_cast<unsigned int>(vals[i]->index()));
1606 while (!ns.
empty()) {
1612 for (
Edge* cur = vln->
first(); cur !=
nullptr; cur = cur->
vnext()) {
1613 VarNode* mate = cur->getVar();
1616 if (cur->matched(
LBC)) {
1619 if (!visited.
get(
static_cast<unsigned int>(mate->
index()))) {
1621 visited.
set(
static_cast<unsigned int>(mate->
index()));
1626 if (!cur->matched(
UBC)) {
1629 if (!visited.
get(
static_cast<unsigned int>(mate->
index()))) {
1631 visited.
set(
static_cast<unsigned int>(mate->
index()));
1646 for (
Edge* cur = vrn->
first(); cur !=
nullptr; cur = cur->
next()) {
1647 ValNode* mate = cur->getVal();
1648 if (!cur->matched(
LBC)) {
1650 if (!visited.
get(
static_cast<unsigned int>(mate->
index()))) {
1652 visited.
set(
static_cast<unsigned int>(mate->
index()));
1661 if (cur !=
nullptr) {
1664 if (!visited.
get(
static_cast<unsigned int>(mate->
index()))) {
1666 visited.
set(
static_cast<unsigned int>(mate->
index()));
1677 template<
class Card>
template<BC bc>
1680 BitSet& inscc, BitSet& in_unfinished,
int dfsnum[],
1681 NodeStack&
roots, NodeStack& unfinished,
1684 int v_index = v->
index();
1685 dfsnum[v_index] =
count;
1686 inscc.
set(
static_cast<unsigned int>(v_index));
1687 in_unfinished.
set(
static_cast<unsigned int>(v_index));
1695 m = v->
type() ? e->matched(
LBC) : !e->matched(
LBC);
1698 m = v->
type() ? !e->matched(
UBC) : e->matched(
UBC);
1704 int w_index = w->
index();
1706 assert(w_index < n_node);
1707 if (!inscc.
get(
static_cast<unsigned int>(w_index))) {
1710 dfs<bc>(w, inscc, in_unfinished, dfsnum,
1712 }
else if (in_unfinished.
get(
static_cast<unsigned int>(w_index))) {
1718 assert(
roots.top()->index() < n_node);
1719 while (dfsnum[
roots.top()->index()] > dfsnum[w_index]) {
1726 if (v ==
roots.top()) {
1727 while (v != unfinished.
top()) {
1731 in_unfinished.
clear(
static_cast<unsigned int>(w->
index()));
1734 assert(v == unfinished.
top());
1735 in_unfinished.
clear(
static_cast<unsigned int>(v_index));
1741 template<
class Card>
template<BC bc>
1745 BitSet inscc(r,
static_cast<unsigned int>(n_node));
1746 BitSet in_unfinished(r,
static_cast<unsigned int>(n_node));
1747 int* dfsnum = r.
alloc<
int>(n_node);
1749 for (
int i = n_node; i--; )
1753 NodeStack
roots(r,n_node);
1754 NodeStack unfinished(r,n_node);
1756 for (
int i = n_var; i--; )
1757 dfs<bc>(vars[i], inscc, in_unfinished, dfsnum,
1761 template<
class Card>
1764 return home.ralloc(t);
Class for edges in the variable-value-graph.
void free(BC bc)
Mark the edge as unused.
Edge * vprev(void) const
return the pointer to the previous edge incident on v
Edge * vnext(void) const
return the pointer to the next edge incident on v
void del_edge(void)
Mark the edge as deleted during synchronization.
Edge ** prev_ref(void)
return the reference to the previous edge incident on x
bool deleted(void) const
return whether the edge has been deleted from the graph
void match(BC bc)
Match the edge.
void unmatch(BC bc)
Unmatch the edge and the incident nodes.
Edge ** vprev_ref(void)
return the reference to the previous edge incident on v
Edge * prev(void) const
return the pointer to the previous edge incident on x
void unlink(void)
Unlink the edge from the linked list of edges.
void insert_edge(void)
Insert the edge again.
Edge ** vnext_ref(void)
return the reference to the next edge incident on v
Edge(void)
Default constructor.
ValNode * getVal(void) const
return the pointer to the value node v of this edge
Node * getMate(bool t) const
return pointer to x if t = true otherwise return v
bool matched(BC bc) const
return whether the edge is matched
void reset(BC bc)
Reset the edge (free the edge, and unmatch the edge).
bool used(BC bc) const
Whether the edge is used.
Edge * next(void) const
return the pointer to the next edge incident on x
Edge ** next_ref(void)
return the reference to the next edge incident on x
VarNode * getVar(void) const
return the pointer to the variable node x of this edge
Edge * next(bool t) const
return a pointer to the next edge If t is false the function returns the next edge incident on x othe...
Base class for nodes in the variable-value-graph.
Edge * e
Stores all incident edges on the node.
bool type(void) const
Return the type of the node (false for a variable node).
Edge * last(void) const
Return pointer to the last incident edge.
bool removed(void) const
check whether a node has been removed from the graph
Node(void)
Default constructor.
int noe
stores the number of incident edges on the node
@ NF_M_UBC
Whether matched for UBC.
@ NF_VAL
Whether node is a value node.
@ NF_M_LBC
Whether matched for LBC.
Edge * inedge(void) const
Return pointer to the node's inedge.
Edge * first(void) const
Return pointer to the first incident edge.
unsigned char nf
Flags for node.
Edge * ie
Single incoming edge used for storing a path in the algorithms.
Edge ** adj(void)
Return reference to the incident edges.
int index(void) const
Get index of either variable or value.
int lb
Minimal capacity of the value node.
int _kidx
Index to access the value via cardinality array k.
void unmatch(BC bc)
unmatch the node
int kmin(void) const
return the minimal node capacity as stored in k
int kbound(BC bc) const
return minimal or maximal capacity
void match(BC bc)
match the node
int incid_match(BC bc) const
returns the number of incident matching edges on a value node
int _klb
Minimal required occurrence of the value as stored in k.
int _kcount
Stores the current number of occurrences of the value.
int ublow
Smallest maximal capacity of the value node.
bool matched(BC bc) const
returns true if the node is matched in BC, false otherwise
bool source(void) const
tests whether the node is a source
int maxlow(void) const
get max cap for LBC
int card_conflict(void) const
Check whether the value node is conflicting.
int noc
Store numbre of conflicting matching edges.
void card_conflict(int c)
Mark the value node as conflicting in case of variable cardinalities.
void dec(BC bc)
decrease the node-capacity
void reset(void)
node reset to original capacity values
int val
Stores the value of the node.
int kmax(void) const
return the maximal node capacity as stored in k
void red_conflict(void)
Reduce the conflict counter.
int kcount(void) const
returns the current number of occurrences of the value
bool sink(void) const
tests whether the node is a sink
int _kub
Maximal required occurrence of the value as stored in k.
int ub
Maximal capacity of the value node.
int cap(BC bc) const
return the node-capacity
int kindex(void) const
returns the index in cardinality array k
ValNode(void)
Default constructor.
void inc(void)
increases the value counter
Edge * ubm
Stores the matching edge on this node in the UBC.
void match(BC bc)
Set node to matched.
VarNode(void)
Default constructor.
bool matched(BC bc) const
tests whether the node is matched or not
void set_match(BC bc, Edge *m)
Set the pointer of the matching edge to m.
Edge * get_match(BC bc) const
Return the matching edge on the node.
void unmatch(BC bc)
Unmatch the node.
Edge * lbm
Stores the matching edge on this node in the LBC.
ExecStatus maximum_matching(void)
Compute a maximum matching M on the graph.
ExecStatus min_require(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k)
Check whether minimum requirements shrink variable domains.
void strongly_connected_components(void)
Compute possible strongly connected components of the graph.
ExecStatus narrow(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k)
Remove edges that do not belong to any maximal matching.
void dfs(Node *, BitSet &, BitSet &, int[], NodeStack &, NodeStack &, int &)
Perform depth-first search on the graph.
void free_alternating_paths(void)
Compute possible free alternating paths in the graph.
bool augmenting_path(Node *)
Test whether the current maximal matching on the graph can be augmented by an alternating path starti...
ExecStatus sync(ViewArray< IntView > &x, ViewArray< Card > &k)
Synchronization of the graph.
VarValGraph(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k, int smin, int smax)
Constructor for the variable-value-graph.
Value iterator for integer views.
int val(void) const
Return current value.
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
bool get(unsigned int i) const
Access value at bit i.
void clear(unsigned int i)
Clear bit i.
void set(unsigned int i)
Set bit i.
Stack with fixed number of elements.
void push(const T &x)
Push element x on top of stack.
T pop(void)
Pop topmost element from stack and return it.
bool empty(void) const
Test whether stack is empty.
T & top(void) const
Return element on top of stack.
void move_lst(int i)
Move view from position size()-1 to position i (truncate array by one).
int size(void) const
Return size of array (number of elements).
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Global cardinality propagators (Counting).
BC
Bounds constraint (BC) type.
Gecode toplevel namespace
void count(Home home, const IntVarArgs &x, int n, IntRelType irt, int m, IntPropLevel ipl=IPL_DEF)
Post propagator for .
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
void roots(Home home, const IntVarArgs &x, SetVar y, SetVar z)
Post constraint .
T * dfs(T *s, const Search::Options &o=Search::Options::def)
Invoke depth-first search engine for subclass T of space s with options o.
@ ES_OK
Execution is okay.
@ ES_FAILED
Execution has resulted in failure.
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
#define GECODE_NEVER
Assert that this command is never executed.
#define GECODE_ASSUME(p)
Assert certain property.