3
* Patrick Pekczynski <pekczynski@ps.uni-sb.de>
6
* Patrick Pekczynski, 2005
9
* $Date: 2005-12-06 07:46:40 +0100 (Tue, 06 Dec 2005) $ by $Author: pekczynski $
12
* This file is part of Gecode, the generic constraint
13
* development environment:
14
* http://www.gecode.org
16
* See the file "LICENSE" for information on usage and
17
* redistribution of this file, and for a
18
* DISCLAIMER OF ALL WARRANTIES.
22
namespace Gecode { namespace Int { namespace GCC {
24
/// Debugging: Print a View
27
if (v.min() == v.max()) {
28
std::cout << v.min() <<" ";
31
std::cout << "["<<v.min() <<".."<<v.max()<<"] ";
34
ViewValues<View> iter(v);
36
std::cout << iter.val() <<",";
45
* \brief Bounds constraint (BC) type
47
* If BC = UBC, then we argue about the Upper Bounds Constraint
48
* else we use the functions for the Lower Bounds Constraint
50
enum BC {UBC = 1, LBC = 0};
53
/// Base class for nodes in the variable-value-graph
56
/// stores all incident edges on the node
58
/// returns the first edge
60
/// returns the last edge
62
/// single incoming edge used for storing a path in the algorithms
64
/// Mark as matching edge in LBC
66
/// Mark as matching edge in UBC
68
/// Explicit node type
71
/// \name Constructors and initialization
73
/// Default constructor
77
virtual ~VVGNode(void){};
79
void* operator new(size_t, void*);
83
/// return reference to the incident edges
85
/// return pointer to the first incident edge
87
/// return pointer to the last incident edge
89
/// return pointer to the node's inedge
91
/// return the type of the node
93
/// access the matching flag of the node
95
bool get_match_flag(void);
96
/// get the information on the node (either var-index or value)
97
virtual int get_info(void) = 0;
98
/// test whether the node is matched
99
virtual bool is_matched(BC) = 0;
101
/// check whether a node has been removed from the graph
102
virtual bool removed(void) = 0;
107
/// set the first edge pointer to \a p
109
/// set the last edge pointer to \a p
111
/// set the inedge pointer to \a p
112
void inedge(Edge* p);
113
/// set the node type to \a t
114
void set_type(bool t);
115
/// set the matching flag to \a f
117
void set_match_flag(bool f);
118
/// set the node information to \a i
119
virtual void set_info(int i) = 0;
124
class VarNode : public VVGNode{
126
/// stores the matching edge on this node in the UBC
128
/// stores the matching edge on this node in the LBC
132
/// stores the variable index of the node
134
/// stores the number of incident edges on the node
137
/// stores the variable index of the node
140
/// \name Constructors and initialization
142
/// Creates a variable node with index i
143
VarNode(int i, int oidx);
148
/// return the matching edge on the node
150
Edge* get_match(void);
151
/// return the variable index of the node
153
/// returns whether the node is still matchable
155
/// tests whether the node is matched or not
159
/// check for removal from graph
165
/// set the node info to \a i
166
void set_info(int i);
167
/// set the pointer of the matching edge to m
169
void set_match(Edge* m);
180
class ValNode : public VVGNode{
182
/// minimal required occurence of the value as stored in k
184
/// maximal required occurence of the value as stored in k
186
/// index to acces the value via cardinality array k
188
/// stores the current number of occurences of the value
192
/// mark as conflicting
196
* \brief Minimal capacity of the value node
198
* Stores who often the value node can be matched in a LBC-matching
203
* \brief Maximal capacity of the value node
205
* Stores who often the value node can be matched in a UBC-matching
211
/// stores the value of the node
213
/// stores the index of the node
215
/// stores the number of incident edges on the node
218
/// \name Constructors and destructors
221
* \brief Constructor for value node
223
* with minimal capacity \a min,
224
* maximal capacity \a max,
225
* the value \a value and the index \a k_access in \a k
227
ValNode(int min, int max, int value, int kidx, int kshift, int count);
233
/// set the max cap for LBC
234
void set_maxlow(int i);
235
/// get max cap for LBC
236
int get_maxlow(void);
239
/// Mark the value node as conflicting in case of variable cardinalities
240
void card_conflict(bool c);
241
/// Check whether the value node is conflicting
242
bool card_conflict(void);
244
/// check for removal from graph
247
/// increases the value counter
249
/// returns the current number of occurences of the value
251
/// returns the number of incident matching edges on a value node
253
int incid_match(void);
254
/// returns the index in cardinality array k
256
/// return the node information
258
/// returns \a true if the node is matched in BC, \a false otherwise
261
/// tests whether the node is a sink
263
/// tests whether the node is a source
265
/// return the minimal node capacity as stored in \a k
267
/// return the maximal node capacity as stored in \a k
269
/// return minimal or maximal capacity
273
/// returns whether the node is still matchable
280
/// changes the index in the cardinality array k
282
/// decrease the node-capacity
285
/// increase the node-capacity
288
/// return the the node-capacity
291
/// set the node-capacity to \a c
300
/// node reset to original capacity values
302
/// set the node infomration to \a i
303
void set_info(int i);
304
/// set the minimal k-capacity to min
305
void set_kmin(int min);
306
/// set the maximal k-capacity to max
307
void set_kmax(int max);
311
/// Class for edges \f$ e(x,v) \f$ in the variable-value-graph
314
/// pointer to the variable node
316
/// pointer to the value node
318
/// pointer to the next edge incident on the same variable node
320
/// pointer to the previous edge incident on the same variable node
322
/// pointer to the next edge on the same value node
324
/// pointer to the previous edge on the same value node
327
* \brief stores whether the edge is used in LBC
328
* Flag storing whether the edge is used in any maximum LBC matching
329
* in the variable-value-graph
333
* \brief stores whether the edge is used in UBC
334
* Flag storing whether the edge is used in any maximum UBC matching
335
* in the variable-value-graph
338
/// stores whether the edge is matched in LBC matching
340
/// stores whether the edge is matched in UBC matching
342
/// stores whether the edge has been deleted during syncronization
346
/// \name Constructors
349
* \brief Construct edge \f$e(x,v)\f$ from variable node \a x
350
* and value node \a y
352
Edge(VarNode* x, ValNode* v);
353
/// Create a new edge in memory
354
void* operator new(size_t, void*);
360
* \brief return whether the edge is used
362
* An edge can be used in a matching on the graph,
363
* a path on the graph or a cycle in the graph.
368
/// return whether the edge is matched
371
/// return whether the edge has been deleted from the graph
372
bool is_deleted(void);
374
* \brief return a pointer to the next edge
375
* If \a t is false the function returns the next edge incident on \a x
376
* otherwise it returns the next edge incident on \a v
378
Edge* next(bool t) const;
379
/// return the pointer to the next edge incident on \a x
380
Edge* next(void) const;
381
/// return the pointer to the previous edge incident on \a x
382
Edge* prev(void) const;
383
/// return the pointer to the next edge incident on \a v
384
Edge* vnext(void) const;
385
/// return the pointer to the previous edge incident on \a v
386
Edge* vprev(void) const;
387
/// return the pointer to the variable node \a x of this edge
388
VarNode* getVar(void);
389
/// return the pointer to the value node \a v of this edge
390
ValNode* getVal(void);
392
* \brief return pointer to \a x if \a t = true otherwise return \a v
395
VVGNode* getMate(bool t);
400
/// Mark the edge as used
403
/// Mark the edge as unused
407
* \brief Reset the edge ( free the edge, and unmatch
408
* the edge including its end-nodes
416
/// Unmatch the edge and the incident nodes
419
/// Unmatch the edge and ( \a x if t=false, \a v otherwise )
421
void unmatch(bool t);
422
/// Unlink the edge from the linked list of edges
424
/// Mark the edge as deleted during synchronization
426
/// Insert the edge again
427
void insert_edge(void);
428
/// return the reference to the next edge incident on \a x
429
Edge** next_ref(void);
430
/// return the reference to the previous edge incident on \a x
431
Edge** prev_ref(void);
432
/// return the reference to the next edge incident on \a v
433
Edge** vnext_ref(void);
434
/// return the reference to the previous edge incident on \a v
435
Edge** vprev_ref(void);
440
* \brief Variable-value-graph used during propagation
443
template <class View, class Card, bool isView>
448
/// Allocated memory for nodes and edges
450
/// Problem variables
452
/// Copy keeping track of removed variables
456
/// Variable partition representing the problem variables
459
* \brief Value partition
461
* \f$ v_i\in V=\left(\bigcup_\{0, \dots, |x|-1\}\right) D_i \f$
462
* in the domains of the
463
* problem variables there is a node in the graph.
465
ValNode** vals; // value partition De
466
/// the edges connecting the variable and the value partition
467
Edge* edges; // edges e
468
/// cardinality of the variable partition
471
* \brief cardinality of the value partition
473
* Computed as \f$ |V| = \left(\bigcup_\{0, \dots, |x|-1\}\right) D_i \f$
476
/// the number of edges in the graph
478
/// total number of nodes in the graph
481
* \brief The sum over the minimal capacities of all value nodes
483
* \f$sum_min = \sum_{v_i \in V} l_i= k[i].min() \f$
487
* \brief The sum over the maximal capacities of all value nodes
489
* \f$sum_max = \sum_{v_i \in V} l_i= k[i].max() \f$
493
/// \name Constructors and Destructors
495
VarValGraph(ViewArray<View>&, ViewArray<View>&, Card& , int , int , int );
499
/// \name Graph-interface
502
* \brief Check whether propagation failed
503
* This is actually needed to cope with failures
504
* occuring in functions returing only a boolean value
505
* and not an ExecStatus.
509
* \brief Set the failure flag of the graph
514
* \brief Check whether minimum requirements shrink variable domains
517
bool min_require(Space* home);
520
* \brief Synchronization of the graph
522
* If the graph has already been constructed and some edges have
523
* been removed during propagation \fn sync removes those edges
524
* that do not longer belong to the graph associated with the current
528
/// Print graph information for debugging
529
void print_graph(void);
530
/// Print matching information for debugging
532
void print_matching(void);
533
/// Gather matching information
534
void print_match(void);
536
/// Print edge information
537
void print_edges(void);
539
/// Allocate memory for the graph
540
void* operator new(size_t t);
541
/// Free the memory for the graph
542
void operator delete(void* p);
545
* \brief Narrow the variable domains
546
* Remove all those edges from the graph that do not belong
547
* to any possible maximum matching on the graph
553
/** \brief Compute a maximum matching M on the graph
555
* If BC=UBC then \f$|M|= |X|\f$
556
* If BC=LBC then \f$|M|= \sum_{i\in \{ 0, \dots, |X|-1\}}
560
bool maximum_matching(void);
562
/// Compute possible free alternating paths in the graph
564
void free_alternating_paths(void);
565
/// Compute possible strongly connected components of the graph
567
void strongly_connected_components(void);
569
* \brief Test whether the current maximal matching on the graph
570
* can be augmented by an alternating path starting and ending with
574
bool augmenting_path(VVGNode*);
578
* \brief DFS on the graph
580
* Depth first search used to compute the
581
* strongly connected components of the graph.
585
bool[], bool[], int[],
586
Support::StaticStack<VVGNode*>&,
587
Support::StaticStack<VVGNode*>&,
594
VVGNode::VVGNode(void){} //no-op
597
VVGNode::operator new(size_t n, void* p){
607
VVGNode::first(void){
617
VVGNode::first(Edge* p){
622
VVGNode::last(Edge* p){
627
VVGNode::get_type(void){
632
VVGNode::set_type(bool b){
637
VVGNode::inedge(void){
642
VVGNode::inedge(Edge* p){
646
template <BC direction>
648
VVGNode::set_match_flag(bool b){
649
if (direction == UBC) {
656
template <BC direction>
658
VVGNode::get_match_flag(void){
659
if (direction == UBC) {
670
VarNode::removed(void) {
677
VarNode::VarNode(int x, int orig_idx) :
678
ubm(NULL), lbm(NULL), var(x), noe(0), xindex(orig_idx){
688
VarNode::is_matched(BC d) {
690
return matched<UBC>();
692
return matched<LBC>();
696
template <BC direction>
698
VarNode::matched(void){
699
return get_match_flag<direction>();
702
template <BC direction>
704
VarNode::match(void){
705
set_match_flag<direction>(true);
708
template <BC direction>
710
VarNode::unmatch(void){
711
set_match_flag<direction>(false);
712
set_match<direction>(NULL);
715
template <BC direction>
717
VarNode::set_match(Edge* p){
718
if (direction == UBC) {
725
template <BC direction>
727
VarNode::get_match(void){
728
if (direction == UBC) {
736
VarNode::set_info(int i){
741
VarNode::get_info(void){
748
ValNode::set_maxlow(int i){
753
ValNode::get_maxlow(void) {
763
ValNode::card_conflict(bool c){
768
ValNode::card_conflict(void){
773
ValNode::removed(void) {
778
ValNode::is_matched(BC d) {
780
return matched<UBC>();
787
ValNode::reset(void){
794
template <BC direction>
796
ValNode::kbound(void){
797
if (direction == UBC) {
815
ValNode::set_kmin(int klb){
820
ValNode::set_kmax(int kub){
824
template <BC direction>
827
if (direction == UBC) {
834
template <BC direction>
837
if (direction == UBC) {
845
template <BC direction>
848
if (direction == UBC) {
856
template <BC direction>
858
ValNode::match(void){
862
template <BC direction>
864
ValNode::unmatch(void){
868
template <BC direction>
870
ValNode::matched(void){
871
return ( cap<direction>() == 0);
875
ValNode::ValNode(int min, int max, int value,
876
int kidx, int kshift, int count) :
877
_klb(min), _kub(max), _kidx(kidx), _kcount(count),
879
lb(min), ublow(max), ub(max),
880
val(value), idx(kshift), noe(0) {
884
Edge** vadjacent = adj();
889
template<BC direction>
891
ValNode::set_cap(int c){
892
if (direction == UBC) {
901
ValNode::set_info(int i){
906
ValNode::get_info(void){
916
ValNode::kcount(void) {
921
ValNode::kcount(int c) {
926
ValNode::kindex(int i){
931
ValNode::kindex(void){
935
/// Returs the number of incident matching edges on the node
936
template <BC direction>
938
ValNode::incid_match(void){
939
if (direction == LBC) {
940
return _kub - ublow + _kcount;
942
return _kub - ub + _kcount;
949
// there are only incoming edges
950
// in case of the UBC-matching
951
bool is_sink = false;
952
is_sink = (_kub - ub == noe);
957
ValNode::source(void){
958
// there are only incoming edges
959
// in case of the UBC-matching
960
bool is_sink = false;
961
is_sink = (_klb - lb == noe);
967
forceinline std::ostream&
968
operator<<(std::ostream& os, Edge* e){
972
os << "e("<<e->getVar()->var<<","<<e->getVal()->val<<")";
980
// unlink from variable side
985
Edge** pnext = p->next_ref();
990
Edge** nprev = n->prev_ref();
994
if (this == x->first()) {
995
Edge** ref = x->adj();
1000
if (this == x->last()) {
1004
// unlink from value side
1005
Edge* pv = prev_vedge;
1006
Edge* nv = next_vedge;
1009
Edge** pvnext = pv->vnext_ref();
1014
Edge** nvprev = nv->vprev_ref();
1018
if (this == v->first()) {
1019
Edge** ref = v->adj();
1024
if (this == v->last()) {
1030
Edge::Edge(VarNode* var, ValNode* val) :
1032
next_edge(NULL), prev_edge(NULL),
1033
next_vedge(NULL), prev_vedge(NULL),
1034
mrklb(false), mrkub(false),
1035
um(false), lm(false), deleted(false) {};
1038
Edge::operator new(size_t, void* p){ //why is there no argument?
1042
template <BC direction>
1045
if (direction == UBC) {
1052
template <BC direction>
1055
/// the failure is here, capacity is not increased for value nodes
1056
if (direction == UBC) {
1063
template <BC direction>
1066
this->free<direction>();
1067
this->unmatch<direction>();
1070
template <BC direction>
1073
if (direction == UBC){
1081
Edge::next(void) const{
1086
Edge::next(bool t) const{
1095
Edge::vnext(void) const{
1100
Edge::vnext_ref(void) {
1105
Edge::prev(void) const{
1110
Edge::prev_ref(void) {
1115
Edge::vprev(void) const{
1120
Edge::vprev_ref(void) {
1125
Edge::next_ref(void){
1128
forceinline VarNode*
1133
forceinline ValNode*
1138
forceinline VVGNode*
1139
Edge::getMate(bool type){
1147
template <BC direction>
1149
Edge::unmatch(void){
1150
if (direction == UBC) {
1155
x->unmatch<direction>();
1156
v->unmatch<direction>();
1159
template <BC direction>
1161
Edge::unmatch(bool node){
1162
if (direction == UBC) {
1168
v->template unmatch<direction>();
1170
x->template unmatch<direction>();
1174
template <BC direction>
1177
if (direction == UBC) {
1179
x->template match<direction>();
1180
x->template set_match<direction>(this);
1181
v->template match<direction>();
1184
x->template match<direction>();
1185
x->template set_match<direction>(this);
1186
v->template match<direction>();
1190
template <BC direction>
1192
Edge::matched(void){
1193
if (direction == UBC) {
1201
Edge::del_edge(void){
1206
Edge::insert_edge(void){
1212
Edge::is_deleted(void){
1217
* \brief Constructor for the variable-value-graph
1219
* The variable parition is initialized with the variables from \a x,
1220
* the value partition is initialized with the values from \a v,
1221
* where \f$ \forall v_i\in V: val_idx[i] is the
1222
* index of v_i in k \f$. \a nov denotes the cardinality of the
1223
* value partition in the graph, \a noe the number of edges in the
1224
* graph, \a min_occ the sum over the minimal occurences
1225
* of all values and \a max_occ the sum over the maximal occurences
1229
template <class View, class Card, bool isView>
1230
VarValGraph<View, Card, isView>::VarValGraph(ViewArray<View>& xref,
1231
ViewArray<View>& yref,
1242
node_size(n_var + n_val),
1247
size_t edge_size = sizeof(Edge) * n_edge;
1248
size_t var_size = sizeof(VarNode) * n_var;
1249
size_t var_ptr_size = sizeof(VarNode*) * n_var;
1250
size_t val_size = sizeof(ValNode) * n_val;
1251
size_t val_ptr_size = sizeof(ValNode*) * n_val;
1252
size_t size = edge_size + var_size + var_ptr_size +
1253
val_size + val_ptr_size;
1255
mem = reinterpret_cast<char*>
1256
(Memory::malloc(size));
1257
edges = reinterpret_cast<Edge*>
1259
VarNode* vars_ptr = reinterpret_cast<VarNode*>
1261
ValNode* vals_ptr = reinterpret_cast<ValNode*>
1262
(mem + edge_size + var_size);
1263
vars = reinterpret_cast<VarNode**>
1264
(mem + edge_size + var_size + val_size);
1265
vals = reinterpret_cast<ValNode**>
1266
(mem + edge_size + var_size + val_size + var_ptr_size);
1268
for (int i = n_val; i--; ){
1269
int kmi = k[i].min();
1270
int kma = k[i].max();
1271
int kc = k[i].counter();
1281
vals[i] = new (vals_ptr + i)
1282
ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
1284
vals[i] = new (vals_ptr + i)
1285
ValNode(0, 0, k[i].card(), i, i + n_var, kc);
1289
for (int i = n_var; i--; ){
1291
vars[i] = new (vars_ptr + i) VarNode(i, x[i].oldindex());
1292
VarNode* vrn = vars[i];
1293
// get the space for the edges of the varnode
1294
Edge** xadjacent = vrn->adj();
1296
ViewValues<View> xiter(x[i]);
1298
for (; xiter(); ++xiter){
1299
int v = xiter.val();
1300
// get the correct index for the value
1301
while(vals[j]->val < v){
1304
ValNode* vln = vals[j];
1305
*xadjacent = new (edges) Edge(vars_ptr + i, vals_ptr + j);
1307
if (vrn->first() == NULL) {
1308
vrn->first(*xadjacent);
1310
Edge* oldprev = vrn->last();
1311
vrn->last(*xadjacent);
1312
Edge** newprev = vrn->last()->prev_ref();
1315
if (vln->first() == NULL) {
1316
vln->first(*xadjacent);
1317
vln->last(*xadjacent);
1320
Edge* old = vln->first();
1321
vln->first(*xadjacent);
1322
Edge** newnext = vln->first()->vnext_ref();
1324
Edge** setprev = old->vprev_ref();
1325
*setprev = vln->first();
1329
xadjacent = (*xadjacent)->next_ref();
1335
template <class View, class Card, bool isView>
1337
VarValGraph<View, Card, isView>::failed(void){
1341
template <class View, class Card, bool isView>
1343
VarValGraph<View, Card, isView>::failed(bool b){
1347
template <class View, class Card, bool isView>
1349
VarValGraph<View, Card, isView>::min_require(Space* home){
1351
bool modified = false;
1352
for (int i = n_val; i--; ) {
1353
ValNode* vln = vals[i];
1355
if (k[i].min() == vln->noe) {
1356
// all variable nodes reachable from vln should be equal to vln->val
1357
for (Edge* e = vln->first(); e != NULL; e = e->vnext()) {
1358
VarNode* vrn = e->getVar();
1359
int vi = vrn->get_info();
1360
for (Edge* f = vrn->first(); f != NULL; f = f->next()) {
1362
ValNode* w = f->getVal();
1370
modified |= x[vi].modified();
1371
x[vi].eq(home, vln->val);
1373
vars[vi] = vars[--n_var];
1374
vars[vi]->set_info(vi);
1385
k[i].eq(home, k[i].min());
1386
k[i].counter(k[i].min());
1387
vln->template set_cap<UBC>(0);
1388
vln->template set_cap<LBC>(0);
1390
sum_min -= k[i].min();
1391
sum_max -= k[i].max();
1397
for (int i = n_val; i--; ) {
1398
vals[i]->set_info(n_var + i);
1404
template <class View, class Card, bool isView>
1406
VarValGraph<View, Card, isView>::sync(void){
1408
GECODE_AUTOARRAY(VVGNode*, re, node_size);
1409
GECODE_AUTOARRAY(BC, re_direct, node_size);
1410
GECODE_AUTOARRAY(Edge*, cre, node_size);
1414
for (int i = n_val; i--; ) {
1416
ValNode* v = vals[i];
1417
int inc_ubc = v->template incid_match<UBC>();
1418
int inc_lbc = v->template incid_match<LBC>();
1420
// the cardinality bounds have been modified
1421
if (k[i].max() < v->kmax() || k[i].min() > v->kmin()) {
1422
if (!k[i].max() == k[i].counter()) {
1423
// update the bounds
1424
v->set_kmax(k[i].max());
1425
v->set_kmin(k[i].min());
1427
//everything is fine
1428
if (inc_ubc <= k[i].max()) {
1429
v->template set_cap<UBC>(k[i].max() - (inc_ubc));
1430
v->set_maxlow(k[i].max() - (inc_lbc));
1431
if (v->kmin() == v->kmax()) {
1432
v->set_cap<LBC>(k[i].max() - (inc_lbc));
1435
// set cap to max and resolve conflicts on view side
1436
// set to full capacity for later rescheduling
1437
v->template set_cap<UBC>(k[i].max());
1438
v->set_maxlow(k[i].max() - (inc_lbc));
1439
if (v->kmin() == v->kmax()) {
1440
v->set_cap<LBC>(k[i].max() - (inc_lbc));
1442
v->card_conflict(true);
1447
if (inc_lbc < k[i].min()) {
1448
v->template set_cap<LBC>(k[i].min() - inc_lbc);
1451
re_direct[n_re] = LBC;
1456
for (int i = n_var; i--; ) {
1457
Edge* mub = vars[i]->template get_match<UBC>();
1459
ValNode* vu = mub->getVal();
1460
if (! (vars[i]->noe == 1) ) {
1461
if (vu->card_conflict()) {
1462
mub->template unmatch<UBC>(vars[i]->get_type());
1465
re_direct[n_re] = UBC;
1472
for (int i = n_val; i--; ) {
1473
if (vals[i]->card_conflict()) {
1474
vals[i]->card_conflict(false);
1479
// because of value propagation it is possible that
1480
// x.size < n_var => hence graphnodes have to be eliminated
1483
// graph size (variable partition)
1486
GECODE_AUTOARRAY(bool, idx_used, gs);
1488
for (int i = gs; i--; ) {
1489
idx_used[i] = false;
1491
// mark remaining indices in x
1492
for (int i = xs; i--; ) {
1493
idx_used[x[i].index()] = true;
1497
for (int i = 0; i < gs && j < x.size(); i++) {
1498
if (i != x[j].index()) {
1499
std::swap(vars[i], vars[x[j].index()]);
1504
for (int i = gs; i--; ) {
1505
if (!idx_used[vars[i]->get_info()]) {
1506
// the node to remove
1507
VarNode* rm = vars[i];
1508
// the value node it is assigned to
1510
Edge* mub = rm->template get_match<UBC>();
1511
Edge* mlb = rm->template get_match<LBC>();
1513
assert(y[rm->xindex].assigned());
1514
int v = y[rm->xindex].val();
1515
for (Edge* e = rm->first(); e != NULL; e = e->next()) {
1516
ValNode* w = e->getVal();
1517
if (e->getVal()->val == v) {
1526
// repair upper bound matching
1528
if (mub->getVal()->val != v) {
1529
mub->template unmatch<UBC>();
1530
if (!rv->is_matched(UBC)) {
1531
rv->template dec<UBC>();
1533
// find a blocking variable node
1534
for (Edge* f = rv->first(); f != NULL; f = f->vnext()) {
1535
if (mub != f && f->template matched<UBC>()) {
1536
f->template unmatch<UBC>(rm->get_type());
1538
re[n_re] = f->getVar();
1539
re_direct[n_re] = UBC;
1548
// repair lower bound matching
1549
if (mlb->getVal()->val != v) {
1550
mlb->template unmatch<LBC>();
1551
ValNode* w = mlb->getVal();
1552
if (!w->template matched<LBC>()) {
1555
re_direct[n_re] = LBC;
1558
if (!rv->is_matched(LBC)) {
1559
rv->template dec<LBC>();
1561
// find a blocking variable node
1562
for (Edge* f = rv->first(); f != NULL; f = f->vnext()) {
1563
if (mlb != f && f->template matched<LBC>()) {
1564
f->template unmatch<LBC>(rm->get_type());
1572
vars[i] = vars[--n_var];
1577
// adjust value information
1578
for (int i = n_val; i--; ) {
1579
vals[i]->set_info(n_var + i);
1582
// go on with synchronization
1583
assert(x.size() == n_var);
1584
for (int i = n_var; i--; ) {
1585
VarNode* vrn = vars[i];
1586
if(x[i].size() != vrn->noe){
1587
// if the variable is already assigned
1588
if (x[i].assigned()) {
1592
Edge* mub = vrn->template get_match<UBC>();
1594
if (v != mub->getVal()->val) {
1595
mub->template unmatch<UBC>();
1598
re_direct[n_re] = UBC;
1603
Edge* mlb = vrn->template get_match<LBC>();
1605
ValNode* vln = mlb->getVal();
1606
if (v != vln->val) {
1607
mlb->template unmatch<LBC>();
1608
int nom = vln->template incid_match<LBC>();
1609
// less values than required
1610
bool cond = nom < vln->kmin();
1614
re_direct[n_re] = LBC;
1620
for (Edge* e = vrn->first(); e != NULL; e = e->next()){
1621
ValNode* vln = e->getVal();
1622
if (vln->val != v) {
1629
rv_idx = rv->kindex();
1635
ViewValues<View> xiter(x[i]);
1636
Edge* mub = vrn->template get_match<UBC>();
1637
Edge* mlb = vrn->template get_match<LBC>();
1638
Edge** p = vrn->adj();
1641
// search the edge that has to be deleted
1642
while (e != NULL && e->getVal()->val < xiter.val()) {
1651
assert(xiter.val() == e->getVal()->val);
1653
// This edge must be kept
1654
e->template free<UBC>();
1655
e->template free<LBC>();
1670
if (mub->is_deleted()) {
1671
mub->template unmatch<UBC>();
1673
re[n_re] = mub->getVar();
1674
re_direct[n_re] = UBC;
1680
//lower bound matching can be zero
1682
if (mlb->is_deleted()) {
1683
ValNode* vln = mlb->getVal();
1684
mlb->template unmatch<LBC>();
1685
int nom = vln->template incid_match<LBC>();
1686
bool cond = nom < vln->kmin();
1690
re_direct[n_re] = LBC;
1699
for (int i = n_var; i--; ) {
1700
vars[i]->set_info(i);
1704
for (int i = n_val; i--; ) {
1705
vals[i]->set_info(n_var + i);
1708
// std::cout << "before end\n";
1712
// std::cout << "no repair\n";
1717
// resolve conflicts
1718
for (int i = n_re; i--; ) {
1719
if ( (cre[i] != NULL && cre[i]->is_deleted()) ||
1720
(re[i]->removed()) ) {
1721
// the conflict exists no more
1722
cre[i] = cre[--n_re];
1724
re_direct[i] = re_direct[n_re];
1728
bool repaired = true;
1731
if (!re[n_re]->is_matched(re_direct[n_re])) {
1732
if (re_direct[n_re] == UBC) {
1733
repaired &= augmenting_path<UBC>(re[n_re]);
1735
repaired &= augmenting_path<LBC>(re[n_re]);
1745
template <class View, class Card, bool isView> template <BC direction>
1747
VarValGraph<View, Card, isView>::narrow(Space* home){
1749
bool shared = false;
1750
for (int i = n_var; i--; ) {
1751
VarNode* vrn = vars[i];
1752
if (vrn->noe == 1) {
1753
Edge* e = vrn->first();
1754
shared |= x[i].modified();
1755
ValNode* v = e->getVal();
1756
e->template free<direction>();
1757
x[i].eq(home, v->val);
1762
for (int i = n_val; i--; ) {
1763
ValNode* v = vals[i];
1767
ModEvent klq = k[i].lq(home, v->noe);
1768
if (me_failed(klq)) {
1775
// If the maximum number of occurences of a value is reached
1776
// it cannot be consumed by another view
1778
if (v->kcount() == v->kmax()) {
1779
k[i].counter(v->kcount());
1780
// std::cout << "eq on : " << v->val<<"\n";
1782
ModEvent me = k[i].eq(home, k[i].counter());
1783
if (me_failed(me)) {
1789
bool delall = false;
1790
if (v->card_conflict() &&
1791
v->kmax() == v->kcount() &&
1792
v->noe > v->kmax()) {
1794
// std::cout << "delall : " << v->val<<"\n";
1797
for (Edge* e = v->last(); e != NULL; e = e->vprev()) {
1798
VarNode* vrn = e->getVar();
1799
if (vrn->noe == 1) {
1802
int vi= vrn->get_info();
1809
vars[vi] = vars[--n_var];
1810
vars[vi]->set_info(vi);
1816
x[vrn->get_info()].nq(home, v->val);
1826
int cur = v->kcount();
1834
for (int i = n_var; i--; ) {
1835
vars[i]->set_info(i);
1839
for (int i = n_val; i--; ) {
1840
vals[i]->set_info(n_var + i);
1843
for (int i = n_var; i--; ) {
1844
if (vars[i]->noe > 1){
1845
for (Edge* e = vars[i]->first(); e != NULL; e = e->next()){
1846
bool keepedge = false;
1847
keepedge = (e->template matched<direction>() ||
1848
e->template used<direction>());
1850
ValNode* v = e->getVal();
1851
shared |= x[i].modified();
1852
x[i].nq(home, v->val);
1854
e->template free<direction>();
1861
// min_require(home);
1865
template <class View, class Card, bool isView> template <BC direction>
1867
VarValGraph<View, Card, isView>::maximum_matching(void){
1868
int required_size = 0;
1871
if (direction == UBC) {
1872
required_size = n_var;
1874
required_size = sum_min;
1877
// find an intial matching in O(n*d)
1880
for (int i = n_val; i--; ){
1881
ValNode* vln = vals[i];
1882
for (Edge* e = vln->first(); e != NULL ; e = e->vnext()) {
1883
VarNode* vrn = e->getVar();
1884
if (!vrn->template matched<direction>() &&
1885
!vln->template matched<direction>()) {
1886
e->template match<direction>();
1892
if (card_match < required_size) {
1893
if (direction == LBC) {
1894
// collect free value nodes
1895
GECODE_AUTOARRAY(ValNode*, free, n_val);
1897
// find failed nodes
1898
for (int i = n_val; i--; ) {
1899
ValNode* vln = vals[i];
1900
if (!vln->template matched<direction>()) {
1905
for (int i = 0; i < f; i++) {
1906
while(!free[i]->template matched<direction>()) {
1907
if (augmenting_path<direction>(free[i])) {
1915
GECODE_AUTOARRAY(VarNode*, free, n_var);
1917
// find failed nodes
1918
for (int i = n_var; i--; ) {
1919
VarNode* vrn = vars[i];
1920
if (!vrn->template matched<direction>()) {
1925
for (int i = 0; i < f; i++) {
1926
if (!free[i]->template matched<direction>()) {
1927
if (augmenting_path<direction>(free[i])) {
1934
return (card_match >= required_size);
1937
template <class View, class Card, bool isView> template<BC direction>
1939
VarValGraph<View, Card, isView>::augmenting_path(VVGNode* v){
1941
Support::StaticStack<VVGNode*> ns(node_size);
1942
GECODE_AUTOARRAY(bool, visited, node_size);
1943
GECODE_AUTOARRAY(Edge*, start, node_size);
1945
// augmenting path starting in a free var node
1946
assert(!v->is_matched(direction));
1948
// keep track of the nodes that have already been visited
1951
// mark the start partition
1952
bool sp = sn->get_type();
1954
// nodes in sp only follow free edges
1955
// nodes in V - sp only follow matched edges
1957
for (int i = node_size; i--; ){
1961
for (int i = node_size; i--; ){
1963
vals[i - n_var]->inedge(NULL);
1964
start[i] = vals[i - n_var]->first();
1966
vars[i]->inedge(NULL);
1967
start[i] = vars[i]->first();
1973
visited[v->get_info()] = true;
1974
while (!ns.empty()) {
1975
VVGNode* v = ns.top();
1977
if (v->get_type() == sp) {
1978
// follow next free edge
1979
e = start[v->get_info()];
1980
while (e != NULL && e->template matched<direction>()) {
1981
e = e->next(v->get_type());
1984
e = start[v->get_info()];
1985
while (e != NULL && !e->template matched<direction>()) {
1986
e = e->next(v->get_type());
1988
start[v->get_info()] = e;
1991
start[v->get_info()] = e->next(v->get_type());
1992
VVGNode* w = e->getMate(v->get_type());
1993
if (!visited[w->get_info()]) {
1995
if (!w->is_matched(direction) && w->get_type() != sp) {
1996
if (v->inedge() != NULL) {
1997
// augmenting path of length l > 1
1998
e->template match<direction>();
2001
// augmenting path of length l = 1
2002
e->template match<direction>();
2008
visited[w->get_info()] = true;
2009
// find matching edge m incident with w
2014
// tried all outgoing edges without finding an augmenting path
2019
bool pathfound = false;
2024
while (!ns.empty()) {
2025
VVGNode* t = ns.top();
2027
Edge* in = t->inedge();
2028
if (t->get_type() != sp) {
2030
in->template match<direction>();
2034
in->template unmatch<direction>(!sp);
2036
in->template unmatch<direction>();
2047
template <class View, class Card, bool isView> template<BC direction>
2049
VarValGraph<View, Card, isView>::free_alternating_paths(void){
2051
Support::StaticStack<VVGNode*> ns(node_size);
2052
GECODE_AUTOARRAY(bool, visited, node_size);
2053
// keep track of the nodes that have already been visited
2054
for (int i = node_size; i--; ){
2058
if (direction == LBC) {
2059
// after a maximum matching on the value nodes there still can be
2060
// free value nodes, hence we have to consider ALL nodes whether
2061
// they are the starting point of an even alternating path in G
2062
for (int i = n_var; i--; ){
2063
if(!vars[i]->is_matched(LBC)){
2064
// unmatched var-node
2066
visited[vars[i]->get_info()] = true;
2070
// clearly, after a maximum matching on the x variables
2071
// corresponding to a set cover on x there are NO free var nodes
2072
// std::cout << "alt_path for ubm: \n";
2073
// after max_match_ub there can only be free val-nodes
2074
for (int i = n_val; i--; ){
2075
if(!vals[i]->is_matched(UBC)){
2076
// still capacities left
2078
visited[vals[i]->get_info()] = true;
2084
VVGNode* node = ns.top();
2086
if (node->get_type()) {
2088
ValNode* vln = reinterpret_cast<ValNode*> (node);
2089
for (Edge* cur = vln->first(); cur != NULL; cur = cur->vnext()){
2090
VarNode* mate = cur->getVar();
2091
bool follow = false;
2092
switch (direction) {
2093
// edges in M_l are directed from values to variables
2095
follow = cur->template matched<direction>();
2099
follow = !cur->template matched<direction>();
2105
cur->template use<direction>();
2106
if (!visited[mate->get_info()]) {
2108
visited[mate->get_info()] = true;
2114
VarNode* vrn = reinterpret_cast<VarNode*> (node);
2115
switch (direction) {
2116
// after LBC-matching we can follow every unmatched edge
2118
for (Edge* cur = vrn->first(); cur != NULL; cur = cur->next()){
2119
ValNode* mate = cur->getVal();
2120
if (!cur->template matched<LBC>()) {
2121
cur->template use<LBC>();
2122
if (!visited[mate->get_info()]) {
2124
visited[mate->get_info()] = true;
2130
// after ub-matching we can only follow a matched edge
2132
Edge* cur = vrn->template get_match<UBC>();
2134
cur->template use<UBC>();
2135
ValNode* mate = cur->getVal();
2136
if (!visited[mate->get_info()]) {
2138
visited[mate->get_info()] = true;
2148
template <class View, class Card, bool isView> template <BC direction>
2150
VarValGraph<View, Card, isView>::dfs(VVGNode* v,
2152
bool in_unfinished[],
2154
Support::StaticStack<VVGNode*>& roots,
2155
Support::StaticStack<VVGNode*>& unfinished,
2158
int v_index = v->get_info();
2159
dfsnum[v_index] = count;
2160
inscc[v_index] = true;
2161
in_unfinished[v_index] = true;
2165
for (Edge* e = v->first(); e != NULL; e = e->next(v->get_type())) {
2166
bool condition = false;
2168
if (direction == LBC) {
2170
if (v->get_type()) {
2171
condition = e->template matched<LBC>();
2173
condition = !e->template matched<LBC>();
2177
if (v->get_type()) {
2178
// in an upper bound matching a valnode only can follow unmatched edges
2179
condition = !e->template matched<UBC>();
2181
condition = e->template matched<UBC>();
2185
VVGNode* w = e->getMate(v->get_type());
2186
int w_index = w->get_info();
2188
assert(w_index < node_size);
2189
if (!inscc[w_index]) {
2190
// w is an uncompleted scc
2192
dfs<direction>(w, inscc, in_unfinished, dfsnum,
2193
roots, unfinished, count);
2195
if (in_unfinished[w_index]) {
2196
// even alternating cycle found mark the edge closing the cycle,
2197
// completing the scc
2198
e->template use<direction>();
2199
// if w belongs to an scc we detected earlier
2201
assert(roots.top()->get_info() < node_size);
2202
while (dfsnum[roots.top()->get_info()] > dfsnum[w_index]) {
2210
if (v == roots.top()) {
2211
while (v != unfinished.top()) {
2212
// w belongs to the scc with root v
2213
VVGNode* w = unfinished.top();
2214
Edge* ie = w->inedge();
2215
ie->template use<direction>();
2216
in_unfinished[w->get_info()] = false;
2219
assert(v == unfinished.top());
2220
in_unfinished[v_index] = false;
2226
template <class View, class Card, bool isView> template <BC direction>
2228
VarValGraph<View, Card, isView>::strongly_connected_components(void){
2230
GECODE_AUTOARRAY(bool, inscc, node_size);
2231
GECODE_AUTOARRAY(bool, in_unfinished, node_size);
2232
GECODE_AUTOARRAY(int, dfsnum, node_size);
2234
for (int i = node_size; i--; ) {
2236
in_unfinished[i] = false;
2241
Support::StaticStack<VVGNode*> roots(node_size);
2242
Support::StaticStack<VVGNode*> unfinished(node_size);
2244
for (int i = n_var; i--; ) {
2245
dfs<direction>(vars[i], inscc, in_unfinished, dfsnum,
2246
roots, unfinished, count);
2251
template <class View, class Card, bool isView>
2253
VarValGraph<View, Card, isView>::print_match(void) {
2254
print_matching<UBC>();
2255
print_matching<LBC>();
2259
template <class View, class Card, bool isView>
2261
VarValGraph<View, Card, isView>::print_edges(void) {
2262
for (int i = 0; i < n_var; i++) {
2263
std::cout << vars[i]->var<<": ";
2264
for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
2265
std::cout << e->getVal()->val<<"("
2266
<< e->template matched<LBC>() << ","
2267
<< e->template matched<UBC>() << ","
2268
<< e->template used<LBC>() << ","
2269
<< e->template used<UBC>() <<") ";
2276
// for debugging purposes
2277
template <class View, class Card, bool isView> template <BC direction>
2279
VarValGraph<View, Card, isView>::print_matching(void) {
2280
if (direction == UBC) {
2281
std::cout << "UBM - check:\n";
2283
std::cout << "LBM - check:\n";
2286
for (int i = 0; i < n_var; i++ ){
2287
std::cout << vars[i]->var <<" ";
2288
if (vars[i]->template matched<direction>()) {
2289
if (vars[i]->template get_match<direction>() == NULL) {
2292
std::cout << vars[i]->template get_match<direction>() << " ";
2293
std::cout << vars[i]->template get_match<direction>()->getVal()->val << " ";
2303
for (int i = 0; i < n_val; i++ ){
2304
(vals[i]->template matched<direction>())? std::cout << "X " : std::cout << "- ";
2305
std::cout << vals[i]->template cap<direction>() << " ";
2306
std::cout << vals[i]->val << " ";
2312
template <class View, class Card, bool isView>
2314
VarValGraph<View, Card, isView>::print_graph(void) {
2315
std::cout << "Graph-size = "<<node_size<<" ";
2316
std::cout << "sum_min ="<<sum_min << " & "
2317
<< "sum_max ="<<sum_max << "\n";
2318
std::cout << "X-Partition: \n";
2319
for (int i = 0; i < n_var; i++) {
2320
VarNode* vrn = vars[i];
2321
std::cout << "X("<<vars[i]->get_info()<<") ";
2322
std::cout << "["<<vrn->xindex <<"]";
2323
std::cout << "|"<<vrn->noe <<"|";
2325
for (Edge* e = vrn->first(); e != NULL; e = e->next()){
2326
std::cout << e->getVal()->val<<",";
2329
std::cout << "F"<<vrn->first() << ", L" << vrn->last() << " ";
2334
std::cout << "V-Partition: \n";
2335
for (int i = 0; i < n_val; i++) {
2336
ValNode* vln = vals[i];
2337
std::cout << vln->val <<" ";
2338
std::cout << "V(" << i << ") ";
2339
std::cout << "k(" << vln->kmin() << "," <<vln->kmax() << ") ";
2340
std::cout << "c(" << vln->template cap<LBC>() << ","
2341
<< vln->template cap<UBC>() << ") ";
2342
std::cout << "ublow: "<<vln->get_maxlow() <<" ";
2343
std::cout << "|"<<vln->noe <<"|";
2345
if (vln->noe == 0 || vln->first() == NULL) {
2346
std::cout << "EMPTY";
2348
for(Edge* c = vln->first(); c != NULL; c = c->vnext()){
2349
std::cout << c->getVar()->var << ",";
2354
if (vln->noe == 0 || vln->first() == NULL) {
2355
std::cout <<"no-ptr";
2357
std::cout << "F"<<vln->first() << ", L" <<vln->last() << " ";
2365
template <class View, class Card, bool isView>
2367
VarValGraph<View, Card, isView>::~VarValGraph(void){
2371
template <class View, class Card, bool isView>
2373
VarValGraph<View, Card, isView>::operator new(size_t t){
2374
return Memory::malloc(t);
2377
template <class View, class Card, bool isView>
2379
VarValGraph<View, Card, isView>::operator delete(void* p){
2385
// STATISTICS: int-prop