Generated on for Gecode by doxygen 1.17.0
dom-sup.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Patrick Pekczynski <pekczynski@ps.uni-sb.de>
5 *
6 * Contributing authors:
7 * Christian Schulte <schulte@gecode.dev>
8 * Guido Tack <tack@gecode.dev>
9 *
10 * Copyright:
11 * Patrick Pekczynski, 2005
12 * Christian Schulte, 2009
13 * Guido Tack, 2009
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.dev
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40namespace Gecode { namespace Int { namespace GCC {
41
48 enum BC {UBC = 1, LBC = 0};
49
50 class Edge;
52 class Node {
53 protected:
63 int idx;
65 enum NodeFlag {
69 NF_VAL = 1 << 0,
71 NF_M_LBC = 1 << 1,
73 NF_M_UBC = 1 << 2
74 };
75
76 unsigned char nf;
77 public:
79 int noe;
80
82
83
84 Node(void);
86 Node(NodeFlag nf, int i);
88
90
91
92 bool type(void) const;
94 Edge** adj(void);
96 Edge* first(void) const;
98 Edge* last(void) const;
100 Edge* inedge(void) const;
102 int index(void) const;
104 bool removed(void) const;
106
108
109
110 void first(Edge* p);
112 void last(Edge* p);
114 void inedge(Edge* p);
116 void index(int i);
118
120
121
122 static void* operator new(size_t s, Space& home);
124 static void operator delete(void*, Space&) {};
126 static void operator delete(void*) {};
128 };
129
131 class VarNode : public Node {
132 protected:
137 public:
139
140
141 VarNode(void);
143 VarNode(int i);
145
147
148
149 Edge* get_match(BC bc) const;
151 bool matched(BC bc) const;
153
155
156
157 void set_match(BC bc, Edge* m);
159 void match(BC bc);
161 void unmatch(BC bc);
163 };
164
166 class ValNode : public Node {
167 protected:
169 int _klb;
171 int _kub;
173 int _kidx;
177 int noc;
179 int lb;
181 int ublow;
183 int ub;
184 public:
186 int val;
187
189
190
191 ValNode(void);
199 ValNode(int min, int max, int value, int kidx, int kshift, int count);
201
203
204
205 int maxlow(void) const;
207 void card_conflict(int c);
209 int card_conflict(void) const;
211 void red_conflict(void);
213 void inc(void);
215 int kcount(void) const;
217 int incid_match(BC bc) const;
219 int kindex(void) const;
221 bool matched(BC bc) const;
223 bool sink(void) const;
225 bool source(void) const;
227 int kmin(void) const;
229 int kmax(void) const;
231 int kbound(BC bc) const;
233
235
236
237 void maxlow(int i);
239 void kcount(int);
241 void kindex(int);
243 void dec(BC bc);
245 void inc(BC bc);
247 int cap(BC bc) const;
249 void cap(BC bc, int c);
251 void match(BC bc);
253 void unmatch(BC bc);
255 void reset(void);
257 void kmin(int min);
259 void kmax(int max);
261 };
262
264 class Edge {
265 private:
267 VarNode* x;
269 ValNode* v;
271 Edge* next_edge;
273 Edge* prev_edge;
275 Edge* next_vedge;
277 Edge* prev_vedge;
279 enum EdgeFlag {
281 EF_NONE = 0,
283 EF_MRKLB = 1 << 0,
285 EF_MRKUB = 1 << 1,
287 EF_LM = 1 << 2,
289 EF_UM = 1 << 3,
291 EF_DEL = 1 << 4
292 };
294 unsigned char ef;
295 public:
297
298
299 Edge(void) {}
304 Edge(VarNode* x, ValNode* v);
306
308
309
310 bool used(BC bc) const;
312 bool matched(BC bc) const;
314 bool deleted(void) const;
320 Edge* next(bool t) const;
322 Edge* next(void) const;
324 Edge* prev(void) const;
326 Edge* vnext(void) const;
328 Edge* vprev(void) const;
330 VarNode* getVar(void) const;
332 ValNode* getVal(void) const;
337 Node* getMate(bool t) const;
339
341
342
343 void use(BC bc);
345 void free(BC bc);
347 void reset(BC bc);
349 void match(BC bc);
351 void unmatch(BC bc);
353 void unmatch(BC bc, bool t);
355 void unlink(void);
357 void del_edge(void);
359 void insert_edge(void);
361 Edge** next_ref(void);
363 Edge** prev_ref(void);
365 Edge** vnext_ref(void);
367 Edge** vprev_ref(void);
369
371
372
373 static void* operator new(size_t s, Space& home);
375 static void operator delete(void*, Space&) {};
377 static void operator delete(void*) {};
379 };
380
381
386 template<class Card>
388 private:
390 typedef Support::StaticStack<Node*,Region> NodeStack;
392 typedef Support::BitSet<Region> BitSet;
394 VarNode** vars;
402 ValNode** vals;
404 int n_var;
410 int n_val;
412 int n_node;
418 int sum_min;
424 int sum_max;
425 public:
427
428
434 VarValGraph(Space& home,
436 int smin, int smax);
438
440
443
454 template<BC>
455 ExecStatus narrow(Space& home,
457
464 template<BC>
466
468 template<BC>
469 void free_alternating_paths(void);
471 template<BC>
478 template<BC>
479 bool augmenting_path(Node*);
480
481 protected:
488 template<BC>
489 void dfs(Node*, BitSet&, BitSet&, int[],
490 NodeStack&, NodeStack&, int&);
491
493 public:
495 void* operator new(size_t t, Space& home);
497 void operator delete(void*, Space&) {}
498 };
499
500
501
502 /*
503 * Nodes
504 *
505 */
506 forceinline
507 Node::Node(void) {}
508 forceinline
510 : e(nullptr), fst(nullptr), lst(nullptr), ie(nullptr), idx(i),
511 nf(static_cast<unsigned char>(nf0)), noe(0) {}
512
513 forceinline Edge**
514 Node::adj(void) {
515 return &e;
516 }
517 forceinline Edge*
518 Node::first(void) const {
519 return fst;
520 }
521 forceinline Edge*
522 Node::last(void) const {
523 return lst;
524 }
525 forceinline void
527 fst = p;
528 }
529 forceinline void
531 lst = p;
532 }
533 forceinline bool
534 Node::type(void) const {
535 return (nf & NF_VAL) != 0;
536 }
537 forceinline Edge*
538 Node::inedge(void) const {
539 return ie;
540 }
541 forceinline void
543 ie = p;
544 }
545 forceinline bool
546 Node::removed(void) const {
547 return noe == 0;
548 }
549 forceinline void
550 Node::index(int i) {
551 idx = i;
552 }
553 forceinline int
554 Node::index(void) const {
555 return idx;
556 }
557
558 forceinline void*
559 Node::operator new(size_t s, Space& home) {
560 return home.ralloc(s);
561 }
562
563
564
565 /*
566 * Variable nodes
567 *
568 */
569 forceinline
571
572 forceinline
574 Node(NF_NONE,x), ubm(nullptr), lbm(nullptr) {}
575
576 forceinline bool
578 if (bc == UBC)
579 return (nf & NF_M_UBC) != 0;
580 else
581 return (nf & NF_M_LBC) != 0;
582 }
583
584 forceinline void
586 if (bc == UBC)
587 nf |= NF_M_UBC;
588 else
589 nf |= NF_M_LBC;
590 }
591
592 forceinline void
594 if (bc == UBC)
595 ubm = p;
596 else
597 lbm = p;
598 }
599
600 forceinline void
602 if (bc == UBC) {
603 nf &= ~NF_M_UBC; ubm = nullptr;
604 } else {
605 nf &= ~NF_M_LBC; lbm = nullptr;
606 }
607 }
608
609 forceinline Edge*
611 if (bc == UBC)
612 return ubm;
613 else
614 return lbm;
615 }
616
617
618
619
620 /*
621 * Value nodes
622 *
623 */
624 forceinline
626
627 forceinline
628 ValNode::ValNode(int min, int max, int value,
629 int kidx, int kshift, int count) :
630 Node(NF_VAL,kshift), _klb(min), _kub(max), _kidx(kidx), _kcount(count),
631 noc(0),
632 lb(min), ublow(max), ub(max),
633 val(value) {}
634
635 forceinline void
637 assert(i >= lb);
638 ublow = i;
639 }
640
641 forceinline int
642 ValNode::maxlow(void) const {
643 if (_klb == _kub) {
644 assert(ublow == lb);
645 }
646 return ublow;
647 }
648
649
650 forceinline void
652 noc = c;
653 }
654
655 forceinline void
657 noc--;
658 assert(noc >= 0);
659 }
660
661 forceinline int
663 return noc;
664 }
665
666 forceinline int
667 ValNode::cap(BC bc) const {
668 if (bc == UBC)
669 return ub;
670 else
671 return lb;
672 }
673 forceinline bool
675 return cap(bc) == 0;
676 }
677
678 forceinline void
680 lb = _klb;
681 ublow = _kub;
682 ub = _kub;
683 noe = 0;
684 }
685
686 forceinline int
687 ValNode::kbound(BC bc) const {
688 if (bc == UBC) {
689 return _kub;
690 } else {
691 return _klb;
692 }
693 }
694
695 forceinline int
696 ValNode::kmax(void) const {
697 return _kub;
698 }
699
700 forceinline int
701 ValNode::kmin(void) const {
702 return _klb;
703 }
704
705 forceinline void
706 ValNode::kmin(int klb) {
707 _klb = klb;
708 }
709
710 forceinline void
711 ValNode::kmax(int kub) {
712 _kub = kub;
713 }
714
715
716 forceinline void
718 if (bc == UBC) {
719 ub--;
720 } else {
721 lb--; ublow--;
722 }
723 }
724
725 forceinline void
727 if (bc == UBC) {
728 ub++;
729 } else {
730 lb++; ublow++;
731 }
732 }
733
734 forceinline void
736 dec(bc);
737 }
738
739 forceinline void
741 inc(bc);
742 }
743
744 forceinline void
745 ValNode::cap(BC bc, int c) {
746 if (bc == UBC)
747 ub = c;
748 else
749 lb = c;
750 }
751
752 forceinline void
754 _kcount++;
755 }
756
757 forceinline int
758 ValNode::kcount(void) const {
759 return _kcount;
760 }
761
762 forceinline void
764 _kcount = c;
765 }
766
767 forceinline void
769 _kidx = i;
770 }
771
772 forceinline int
773 ValNode::kindex(void) const {
774 return _kidx;
775 }
776
778 forceinline int
780 if (bc == LBC)
781 return _kub - ublow + _kcount;
782 else
783 return _kub - ub + _kcount;
784 }
785
786
787 forceinline bool
788 ValNode::sink(void) const {
789 // there are only incoming edges
790 // in case of the UBC-matching
791 return _kub - ub == noe;
792 }
793
794 forceinline bool
795 ValNode::source(void) const {
796 // there are only incoming edges
797 // in case of the UBC-matching
798 return _klb - lb == noe;
799 }
800
801
802
803 /*
804 * Edges
805 *
806 */
807 forceinline void
809 // unlink from variable side
810 Edge* p = prev_edge;
811 Edge* n = next_edge;
812
813 if (p != nullptr)
814 *p->next_ref() = n;
815 if (n != nullptr)
816 *n->prev_ref() = p;
817
818 if (this == x->first()) {
819 Edge** ref = x->adj();
820 *ref = n;
821 x->first(n);
822 }
823
824 if (this == x->last())
825 x->last(p);
826
827 // unlink from value side
828 Edge* pv = prev_vedge;
829 Edge* nv = next_vedge;
830
831 if (pv != nullptr)
832 *pv->vnext_ref() = nv;
833 if (nv != nullptr)
834 *nv->vprev_ref() = pv;
835 if (this == v->first()) {
836 Edge** ref = v->adj();
837 *ref = nv;
838 v->first(nv);
839 }
840 if (this == v->last())
841 v->last(pv);
842 }
843
844 forceinline
846 x(var), v(val),
847 next_edge(nullptr), prev_edge(nullptr),
848 next_vedge(nullptr), prev_vedge(nullptr), ef(EF_NONE) {}
849
850 forceinline void
852 if (bc == UBC)
853 ef |= EF_MRKUB;
854 else
855 ef |= EF_MRKLB;
856 }
857 forceinline void
859 if (bc == UBC)
860 ef &= ~EF_MRKUB;
861 else
862 ef &= ~EF_MRKLB;
863 }
864 forceinline bool
865 Edge::used(BC bc) const {
866 if (bc == UBC)
867 return (ef & EF_MRKUB) != 0;
868 else
869 return (ef & EF_MRKLB) != 0;
870 }
871 forceinline Edge*
872 Edge::next(void) const {
873 return next_edge;
874 }
875 forceinline Edge*
876 Edge::next(bool t) const {
877 if (t) {
878 return next_vedge;
879 } else {
880 return next_edge;
881 }
882 }
883
884 forceinline Edge*
885 Edge::vnext(void) const {
886 return next_vedge;
887 }
888 forceinline Edge**
890 return &next_vedge;
891 }
892 forceinline Edge*
893 Edge::prev(void) const {
894 return prev_edge;
895 }
896 forceinline Edge**
898 return &prev_edge;
899 }
900 forceinline Edge*
901 Edge::vprev(void) const {
902 return prev_vedge;
903 }
904 forceinline Edge**
906 return &prev_vedge;
907 }
908 forceinline Edge**
910 return &next_edge;
911 }
912 forceinline VarNode*
913 Edge::getVar(void) const {
914 assert(x != nullptr);
915 return x;
916 }
917
918 forceinline ValNode*
919 Edge::getVal(void) const {
920 assert(v != nullptr);
921 return v;
922 }
923
924 forceinline Node*
925 Edge::getMate(bool type) const {
926 if (type)
927 return x;
928 else
929 return v;
930 }
931
932 forceinline void
934 if (bc == UBC)
935 ef &= ~EF_UM;
936 else
937 ef &= ~EF_LM;
938 x->unmatch(bc); v->unmatch(bc);
939 }
940
941 forceinline void
942 Edge::unmatch(BC bc, bool node) {
943 if (bc == UBC)
944 ef &= ~EF_UM;
945 else
946 ef &= ~EF_LM;
947 if (node)
948 v->unmatch(bc);
949 else
950 x->unmatch(bc);
951 }
952
953 forceinline void
955 free(bc); unmatch(bc);
956 }
957
958 forceinline void
960 if (bc == UBC)
961 ef |= EF_UM;
962 else
963 ef |= EF_LM;
964 x->match(bc);
965 x->set_match(bc,this);
966 v->match(bc);
967 }
968
969 forceinline bool
970 Edge::matched(BC bc) const {
971 if (bc == UBC)
972 return (ef & EF_UM) != 0;
973 else
974 return (ef & EF_LM) != 0;
975 }
976
977 forceinline void
979 ef |= EF_DEL;
980 }
981
982 forceinline void
984 ef &= ~EF_DEL;
985 }
986
987
988 forceinline bool
989 Edge::deleted(void) const {
990 return (ef & EF_DEL) != 0;
991 }
992
993 forceinline void*
994 Edge::operator new(size_t s, Space& home) {
995 return home.ralloc(s);
996 }
997
998
999 /*
1000 * Variable value graph
1001 *
1002 */
1003 template<class Card>
1006 int smin, int smax)
1007 : n_var(x.size()),
1008 n_val(k.size()),
1009 n_node(n_var + n_val),
1010 sum_min(smin),
1011 sum_max(smax) {
1012
1013 vars = home.alloc<VarNode*>(n_var);
1014 vals = home.alloc<ValNode*>(n_val);
1015
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();
1020 if (kc != kma) {
1021 if (kmi >= kc) {
1022 kmi -=kc;
1023 assert(kmi >=0);
1024 } else {
1025 kmi = 0;
1026 }
1027 kma -= kc;
1028 assert (kma > 0);
1029 vals[i] = new (home)
1030 ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
1031 } else {
1032 vals[i] = new (home)
1033 ValNode(0, 0, k[i].card(), i, i + n_var, kc);
1034 }
1035 }
1036
1037 for (int i = n_var; i--; ) {
1038 vars[i] = new (home) VarNode(i);
1039 // get the space for the edges of the varnode
1040 Edge** xadjacent = vars[i]->adj();
1041
1042 int j = 0;
1043 for (ViewValues<IntView> xi(x[i]); xi(); ++xi) {
1044 // get the correct index for the value
1045 while(vals[j]->val < xi.val())
1046 j++;
1047 *xadjacent = new (home) Edge(vars[i],vals[j]);
1048 vars[i]->noe++;
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;
1054
1055 if (vals[j]->first() == nullptr) {
1056 vals[j]->first(*xadjacent);
1057 vals[j]->last(*xadjacent);
1058 } else {
1059 Edge* old = vals[j]->first();
1060 vals[j]->first(*xadjacent);
1061 *vals[j]->first()->vnext_ref() = old;
1062 *old->vprev_ref() = vals[j]->first();
1063 }
1064 vals[j]->noe++;
1065 xadjacent = (*xadjacent)->next_ref();
1066 }
1067 *xadjacent = nullptr;
1068 }
1069 }
1070
1071
1072 template<class Card>
1073 inline ExecStatus
1076 ViewArray<Card>& k) {
1077 for (int i = n_val; i--; ) {
1078 ValNode* vln = vals[i];
1079 if (vln->noe > 0) {
1080 if (k[i].min() == vln->noe) {
1081 // all variable nodes reachable from vln should be equal to vln->val
1082 for (Edge* e = vln->first(); e != nullptr; e = e->vnext()) {
1083 VarNode* vrn = e->getVar();
1084 for (Edge* f = vrn->first(); f != nullptr; f = f->next())
1085 if (f != e) {
1086 ValNode* w = f->getVal();
1087 w->noe--;
1088 vrn->noe--;
1089 f->del_edge();
1090 f->unlink();
1091 }
1092 assert(vrn->noe == 1);
1093
1094 int vi = vrn->index();
1095 GECODE_ME_CHECK(x[vi].eq(home, vln->val));
1096
1097 vars[vi] = vars[--n_var];
1098 vars[vi]->index(vi);
1099 x.move_lst(vi);
1100 n_node--;
1101 vln->noe--;
1102 }
1103
1104
1105 int vidx = vln->kindex();
1106 if (Card::propagate)
1107 GECODE_ME_CHECK(k[vidx].eq(home, k[vidx].min()));
1108
1109 k[vidx].counter(k[vidx].min());
1110
1111 vln->cap(UBC,0);
1112 vln->cap(LBC,0);
1113 vln->maxlow(0);
1114
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();
1119 }
1120 } else {
1121 vals[i]->cap(UBC,0);
1122 vals[i]->cap(LBC,0);
1123 vals[i]->maxlow(0);
1124 vals[i]->kmax(0);
1125 vals[i]->kmin(0);
1126 }
1127
1128 if (Card::propagate && (k[i].counter() == 0))
1129 GECODE_ME_CHECK(k[i].lq(home, vals[i]->noe));
1130 }
1131
1132 for (int i = n_val; i--; )
1133 vals[i]->index(n_var + i);
1134
1135 return ES_OK;
1136 }
1137
1138 template<class Card> template<BC bc>
1139 forceinline bool
1141 Region r;
1142 NodeStack ns(r,n_node);
1143 BitSet visited(r,static_cast<unsigned int>(n_node));
1144 Edge** start = r.alloc<Edge*>(n_node);
1145
1146 // keep track of the nodes that have already been visited
1147 Node* sn = v;
1148
1149 // mark the start partition
1150 bool sp = sn->type();
1151
1152 // nodes in sp only follow free edges
1153 // nodes in V - sp only follow matched edges
1154
1155 for (int i = n_node; i--; )
1156 if (i >= n_var) {
1157 vals[i-n_var]->inedge(nullptr);
1158 start[i] = vals[i-n_var]->first();
1159 } else {
1160 vars[i]->inedge(nullptr);
1161 start[i] = vars[i]->first();
1162 }
1163
1164 v->inedge(nullptr);
1165 ns.push(v);
1166 visited.set(static_cast<unsigned int>(v->index()));
1167 while (!ns.empty()) {
1168 Node* vv = ns.top();
1169 Edge* e = nullptr;
1170 if (vv->type() == sp) {
1171 e = start[vv->index()];
1172 while ((e != nullptr) && e->matched(bc))
1173 e = e->next(vv->type());
1174 } else {
1175 e = start[vv->index()];
1176 while ((e != nullptr) && !e->matched(bc))
1177 e = e->next(vv->type());
1178 start[vv->index()] = e;
1179 }
1180 if (e != nullptr) {
1181 start[vv->index()] = e->next(vv->type());
1182 Node* w = e->getMate(vv->type());
1183 if (!visited.get(static_cast<unsigned int>(w->index()))) {
1184 // unexplored path
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) {
1190 // augmenting path of length l > 1
1191 e->match(bc);
1192 break;
1193 } else {
1194 // augmenting path of length l = 1
1195 e->match(bc);
1196 ns.pop();
1197 return true;
1198 }
1199 } else {
1200 w->inedge(e);
1201 visited.set(static_cast<unsigned int>(w->index()));
1202 // find matching edge m incident with w
1203 ns.push(w);
1204 }
1205 }
1206 } else {
1207 // tried all outgoing edges without finding an augmenting path
1208 ns.pop();
1209 }
1210 }
1211
1212 bool pathfound = !ns.empty();
1213
1214 while (!ns.empty()) {
1215 Node* t = ns.pop();
1216 if (t != sn) {
1217 Edge* in = t->inedge();
1218 if (t->type() != sp) {
1219 in->match(bc);
1220 } else if (!sp) {
1221 in->unmatch(bc,!sp);
1222 } else {
1223 in->unmatch(bc);
1224 }
1225 }
1226 }
1227 return pathfound;
1228 }
1229
1230
1231 template<class Card>
1232 inline ExecStatus
1234 Region r;
1235 // A node can be pushed twice (once when checking cardinality and later again)
1236 NodeStack re(r,2*n_node);
1237
1238 // synchronize cardinality variables
1239 if (Card::propagate) {
1240 for (int i = n_val; i--; ) {
1241 ValNode* v = vals[i];
1242 int inc_ubc = v->incid_match(UBC);
1243 int inc_lbc = v->incid_match(LBC);
1244 if (v->noe == 0) {
1245 inc_ubc = 0;
1246 inc_lbc = 0;
1247 }
1248 int rm = v->kmax() - k[i].max();
1249 // the cardinality bounds have been modified
1250 if ((k[i].max() < v->kmax()) || (k[i].min() > v->kmin())) {
1251 if ((k[i].max() != k[i].counter()) || (k[i].max() == 0)) {
1252 // update the bounds
1253 v->kmax(k[i].max());
1254 v->kmin(k[i].min());
1255
1256 //everything is fine
1257 if (inc_ubc <= k[i].max()) {
1258 // adjust capacities
1259 v->cap(UBC, k[i].max() - inc_ubc);
1260 v->maxlow(k[i].max() - inc_lbc);
1261 if (v->kmin() == v->kmax())
1262 v->cap(LBC, k[i].max() - inc_lbc);
1263 } else {
1264 // set cap to max and resolve conflicts on view side
1265 // set to full capacity for later rescheduling
1266 if (v->cap(UBC))
1267 v->cap(UBC,k[i].max());
1268 v->maxlow(k[i].max() - (inc_lbc));
1269 if (v->kmin() == v->kmax())
1270 v->cap(LBC,k[i].max() - (inc_lbc));
1271 int matched = inc_ubc - v->kcount();
1272 v->card_conflict(std::min(rm, matched));
1273 }
1274 }
1275 }
1276 if (inc_lbc < k[i].min() && v->noe > 0) {
1277 v->cap(LBC, k[i].min() - inc_lbc);
1278 re.push(v);
1279 }
1280 }
1281
1282 for (int i = n_var; i--; ) {
1283 Edge* mub = vars[i]->get_match(UBC);
1284 if (mub != nullptr) {
1285 ValNode* vu = mub->getVal();
1286 if ((vars[i]->noe != 1) && vu->card_conflict()) {
1287 vu->red_conflict();
1288 mub->unmatch(UBC,vars[i]->type());
1289 re.push(vars[i]);
1290 }
1291 }
1292 }
1293 }
1294
1295 // go on with synchronization
1296 assert(x.size() == n_var);
1297 for (int i = n_var; i--; ) {
1298
1299 VarNode* vrn = vars[i];
1300 if (static_cast<int>(x[i].size()) != vrn->noe) {
1301 // if the variable is already assigned
1302 if (x[i].assigned()) {
1303 int v = x[i].val();
1304 Edge* mub = vrn->get_match(UBC);
1305 if ((mub != nullptr) && (v != mub->getVal()->val)) {
1306 mub->unmatch(UBC);
1307 re.push(vars[i]);
1308 }
1309
1310 Edge* mlb = vrn->get_match(LBC);
1311 if (mlb != nullptr) {
1312 ValNode* vln = mlb->getVal();
1313 if (v != vln->val) {
1314 mlb->unmatch(LBC);
1315 if (vln->incid_match(LBC) < vln->kmin())
1316 re.push(vln);
1317 }
1318 }
1319
1320 for (Edge* e = vrn->first(); e != nullptr; e = e->next()) {
1321 ValNode* vln = e->getVal();
1322 if (vln->val != v) {
1323 vrn->noe--;
1324 e->getVal()->noe--;
1325 e->del_edge();
1326 e->unlink();
1327 }
1328 }
1329 } else {
1330
1331 // delete the edge
1332 ViewValues<IntView> xiter(x[i]);
1333 Edge* mub = vrn->get_match(UBC);
1334 Edge* mlb = vrn->get_match(LBC);
1335 Edge** p = vrn->adj();
1336 Edge* e = *p;
1337 GECODE_ASSUME(e != nullptr);
1338 do {
1339 // search the edge that has to be deleted
1340 while ((e != nullptr) && (e->getVal()->val < xiter.val())) {
1341 // Skip edge
1342 e->getVal()->noe--;
1343 vrn->noe--;
1344 e->del_edge();
1345 e->unlink();
1346 e = e ->next();
1347 *p = e;
1348 }
1349 GECODE_ASSUME(e != nullptr);
1350
1351 assert(xiter.val() == e->getVal()->val);
1352
1353 // This edge must be kept
1354 e->free(UBC);
1355 e->free(LBC);
1356 ++xiter;
1357 p = e->next_ref();
1358 e = e->next();
1359 } while (xiter());
1360 *p = nullptr;
1361 while (e != nullptr) {
1362 e->getVar()->noe--;
1363 e->getVal()->noe--;
1364 e->del_edge();
1365 e->unlink();
1366 e = e->next();
1367 }
1368
1369 if ((mub != nullptr) && mub->deleted()) {
1370 mub->unmatch(UBC);
1371 re.push(vars[i]);
1372 }
1373
1374 //lower bound matching can be zero
1375 if ((mlb != nullptr) && mlb->deleted()) {
1376 ValNode* vln = mlb->getVal();
1377 mlb->unmatch(LBC);
1378 if (vln->incid_match(LBC) < vln->kmin())
1379 re.push(vln);
1380 }
1381 }
1382 }
1383 vars[i]->index(i);
1384 }
1385
1386 for (int i = n_val; i--; ) {
1387 if ((k[i].min() > vals[i]->noe) && (k[i].counter() == 0))
1388 return ES_FAILED;
1389 vals[i]->index(n_var + i);
1390 }
1391
1392 // start repair
1393 while (!re.empty()) {
1394 Node* n = re.pop();
1395 if (!n->removed()) {
1396 if (!n->type()) {
1397 VarNode* vrn = static_cast<VarNode*>(n);
1398 if (!vrn->matched(UBC) && !augmenting_path<UBC>(vrn))
1399 return ES_FAILED;
1400 } else {
1401 ValNode* vln = static_cast<ValNode*>(n);
1402 while (!vln->matched(LBC))
1403 if (!augmenting_path<LBC>(vln))
1404 return ES_FAILED;
1405 }
1406 }
1407 }
1408
1409 return ES_OK;
1410 }
1411
1412 template<class Card> template<BC bc>
1413 inline ExecStatus
1416 for (int i = n_var; i--; )
1417 if (vars[i]->noe == 1) {
1418 ValNode* v = vars[i]->first()->getVal();
1419 vars[i]->first()->free(bc);
1420 GECODE_ME_CHECK(x[i].eq(home, v->val));
1421 if (bc == UBC)
1422 v->inc();
1423 }
1424
1425 for (int i = n_val; i--; ) {
1426 ValNode* v = vals[i];
1427 if (Card::propagate && (k[i].counter() == 0))
1428 GECODE_ME_CHECK(k[i].lq(home, v->noe));
1429 if (v->noe > 0) {
1430 if (Card::propagate)
1431 GECODE_ME_CHECK(k[i].lq(home, v->noe));
1432
1433 // If the maximum number of occurrences of a value is reached
1434 // it cannot be consumed by another view
1435
1436 if (v->kcount() == v->kmax()) {
1437 int vidx = v->kindex();
1438
1439 k[i].counter(v->kcount());
1440
1441 if (Card::propagate)
1442 GECODE_ME_CHECK(k[i].eq(home, k[i].counter()));
1443
1444 bool delall = v->card_conflict() && (v->noe > v->kmax());
1445
1446 for (Edge* e = v->last(); e != nullptr; e = e->vprev()) {
1447 VarNode* vrn = e->getVar();
1448 if (vrn->noe == 1) {
1449 vrn->noe--;
1450 v->noe--;
1451 int vi= vrn->index();
1452
1453 x.move_lst(vi);
1454 vars[vi] = vars[--n_var];
1455 vars[vi]->index(vi);
1456 n_node--;
1457 e->del_edge();
1458 e->unlink();
1459
1460 } else if (delall) {
1461 GECODE_ME_CHECK(x[vrn->index()].nq(home, v->val));
1462 vrn->noe--;
1463 v->noe--;
1464 e->del_edge();
1465 e->unlink();
1466 }
1467 }
1468 v->cap(UBC,0);
1469 v->cap(LBC,0);
1470 v->maxlow(0);
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();
1475
1476 } else if (v->kcount() > 0) {
1477 v->kcount(0);
1478 }
1479 }
1480 }
1481 for (int i = n_var; i--; )
1482 vars[i]->index(i);
1483
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);
1488 vals[i]->maxlow(0);
1489 }
1490 vals[i]->index(n_var + i);
1491 }
1492
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)) {
1497 GECODE_ME_CHECK(x[i].nq(home, e->getVal()->val));
1498 } else {
1499 e->free(bc);
1500 }
1501 }
1502 }
1503 }
1504 return ES_OK;
1505 }
1506
1507 template<class Card> template<BC bc>
1508 inline ExecStatus
1510 int card_match = 0;
1511 // find an initial matching in O(n*d)
1512 // greedy algorithm
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++;
1517 }
1518
1519 Region r;
1520 switch (bc) {
1521 case LBC:
1522 if (card_match < sum_min) {
1524
1525 // find failed nodes
1526 for (int i = n_val; i--; )
1527 if (!vals[i]->matched(LBC))
1528 free.push(vals[i]);
1529
1530 while (!free.empty()) {
1531 ValNode* v = free.pop();
1532 while (!v->matched(LBC))
1533 if (augmenting_path<LBC>(v))
1534 card_match++;
1535 else
1536 break;
1537 }
1538
1539 return (card_match >= sum_min) ? ES_OK : ES_FAILED;
1540 } else {
1541 return ES_OK;
1542 }
1543 break;
1544 case UBC:
1545 if (card_match < n_var) {
1547
1548 // find failed nodes
1549 for (int i = n_var; i--; )
1550 if (!vars[i]->matched(UBC))
1551 free.push(vars[i]);
1552
1553 while (!free.empty()) {
1554 VarNode* v = free.pop();
1555 if (!v->matched(UBC) && augmenting_path<UBC>(v))
1556 card_match++;
1557 }
1558
1559 return (card_match >= n_var) ? ES_OK : ES_FAILED;
1560 } else {
1561 return ES_OK;
1562 }
1563 break;
1564 default: GECODE_NEVER;
1565 }
1567 return ES_FAILED;
1568 }
1569
1570
1571 template<class Card> template<BC bc>
1572 forceinline void
1574 Region r;
1575 NodeStack ns(r,n_node);
1576 BitSet visited(r,static_cast<unsigned int>(n_node));
1577
1578 switch (bc) {
1579 case LBC:
1580 // after a maximum matching on the value nodes there still can be
1581 // free value nodes, hence we have to consider ALL nodes whether
1582 // they are the starting point of an even alternating path in G
1583 for (int i = n_var; i--; )
1584 if (!vars[i]->matched(LBC)) {
1585 ns.push(vars[i]);
1586 visited.set(static_cast<unsigned int>(vars[i]->index()));
1587 }
1588 for (int i = n_val; i--; )
1589 if (!vals[i]->matched(LBC)) {
1590 ns.push(vals[i]);
1591 visited.set(static_cast<unsigned int>(vals[i]->index()));
1592 }
1593 break;
1594 case UBC:
1595 // clearly, after a maximum matching on the x variables
1596 // corresponding to a set cover on x there are NO free var nodes
1597 for (int i = n_val; i--; )
1598 if (!vals[i]->matched(UBC)) {
1599 ns.push(vals[i]);
1600 visited.set(static_cast<unsigned int>(vals[i]->index()));
1601 }
1602 break;
1603 default: GECODE_NEVER;
1604 }
1605
1606 while (!ns.empty()) {
1607 Node* node = ns.pop();
1608 if (node->type()) {
1609 // ValNode
1610 ValNode* vln = static_cast<ValNode*>(node);
1611
1612 for (Edge* cur = vln->first(); cur != nullptr; cur = cur->vnext()) {
1613 VarNode* mate = cur->getVar();
1614 switch (bc) {
1615 case LBC:
1616 if (cur->matched(LBC)) {
1617 // mark the edge
1618 cur->use(LBC);
1619 if (!visited.get(static_cast<unsigned int>(mate->index()))) {
1620 ns.push(mate);
1621 visited.set(static_cast<unsigned int>(mate->index()));
1622 }
1623 }
1624 break;
1625 case UBC:
1626 if (!cur->matched(UBC)) {
1627 // mark the edge
1628 cur->use(UBC);
1629 if (!visited.get(static_cast<unsigned int>(mate->index()))) {
1630 ns.push(mate);
1631 visited.set(static_cast<unsigned int>(mate->index()));
1632 }
1633 }
1634 break;
1635 default: GECODE_NEVER;
1636 }
1637 }
1638
1639 } else {
1640 // VarNode
1641 VarNode* vrn = static_cast<VarNode*>(node);
1642
1643 switch (bc) {
1644 case LBC:
1645 // after LBC-matching we can follow every unmatched edge
1646 for (Edge* cur = vrn->first(); cur != nullptr; cur = cur->next()) {
1647 ValNode* mate = cur->getVal();
1648 if (!cur->matched(LBC)) {
1649 cur->use(LBC);
1650 if (!visited.get(static_cast<unsigned int>(mate->index()))) {
1651 ns.push(mate);
1652 visited.set(static_cast<unsigned int>(mate->index()));
1653 }
1654 }
1655 }
1656 break;
1657 case UBC:
1658 // after UBC-matching we can only follow a matched edge
1659 {
1660 Edge* cur = vrn->get_match(UBC);
1661 if (cur != nullptr) {
1662 cur->use(UBC);
1663 ValNode* mate = cur->getVal();
1664 if (!visited.get(static_cast<unsigned int>(mate->index()))) {
1665 ns.push(mate);
1666 visited.set(static_cast<unsigned int>(mate->index()));
1667 }
1668 }
1669 }
1670 break;
1671 default: GECODE_NEVER;
1672 }
1673 }
1674 }
1675 }
1676
1677 template<class Card> template<BC bc>
1678 void
1680 BitSet& inscc, BitSet& in_unfinished, int dfsnum[],
1681 NodeStack& roots, NodeStack& unfinished,
1682 int& count) {
1683 count++;
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));
1688
1689 unfinished.push(v);
1690 roots.push(v);
1691 for (Edge* e = v->first(); e != nullptr; e = e->next(v->type())) {
1692 bool m;
1693 switch (bc) {
1694 case LBC:
1695 m = v->type() ? e->matched(LBC) : !e->matched(LBC);
1696 break;
1697 case UBC:
1698 m = v->type() ? !e->matched(UBC) : e->matched(UBC);
1699 break;
1700 default: GECODE_NEVER;
1701 }
1702 if (m) {
1703 Node* w = e->getMate(v->type());
1704 int w_index = w->index();
1705
1706 assert(w_index < n_node);
1707 if (!inscc.get(static_cast<unsigned int>(w_index))) {
1708 // w is an uncompleted scc
1709 w->inedge(e);
1710 dfs<bc>(w, inscc, in_unfinished, dfsnum,
1711 roots, unfinished, count);
1712 } else if (in_unfinished.get(static_cast<unsigned int>(w_index))) {
1713 // even alternating cycle found mark the edge closing the cycle,
1714 // completing the scc
1715 e->use(bc);
1716 // if w belongs to an scc we detected earlier
1717 // merge components
1718 assert(roots.top()->index() < n_node);
1719 while (dfsnum[roots.top()->index()] > dfsnum[w_index]) {
1720 roots.pop();
1721 }
1722 }
1723 }
1724 }
1725
1726 if (v == roots.top()) {
1727 while (v != unfinished.top()) {
1728 // w belongs to the scc with root v
1729 Node* w = unfinished.top();
1730 w->inedge()->use(bc);
1731 in_unfinished.clear(static_cast<unsigned int>(w->index()));
1732 unfinished.pop();
1733 }
1734 assert(v == unfinished.top());
1735 in_unfinished.clear(static_cast<unsigned int>(v_index));
1736 roots.pop();
1737 unfinished.pop();
1738 }
1739 }
1740
1741 template<class Card> template<BC bc>
1742 forceinline void
1744 Region r;
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);
1748
1749 for (int i = n_node; i--; )
1750 dfsnum[i]=0;
1751
1752 int count = 0;
1753 NodeStack roots(r,n_node);
1754 NodeStack unfinished(r,n_node);
1755
1756 for (int i = n_var; i--; )
1757 dfs<bc>(vars[i], inscc, in_unfinished, dfsnum,
1758 roots, unfinished, count);
1759 }
1760
1761 template<class Card>
1762 forceinline void*
1763 VarValGraph<Card>::operator new(size_t t, Space& home) {
1764 return home.ralloc(t);
1765 }
1766
1767}}}
1768
1769// STATISTICS: int-prop
1770
Class for edges in the variable-value-graph.
Definition dom-sup.hpp:264
void use(BC bc)
Update.
Definition dom-sup.hpp:851
void free(BC bc)
Mark the edge as unused.
Definition dom-sup.hpp:858
Edge * vprev(void) const
return the pointer to the previous edge incident on v
Definition dom-sup.hpp:901
Edge * vnext(void) const
return the pointer to the next edge incident on v
Definition dom-sup.hpp:885
void del_edge(void)
Mark the edge as deleted during synchronization.
Definition dom-sup.hpp:978
Edge ** prev_ref(void)
return the reference to the previous edge incident on x
Definition dom-sup.hpp:897
bool deleted(void) const
return whether the edge has been deleted from the graph
Definition dom-sup.hpp:989
void match(BC bc)
Match the edge.
Definition dom-sup.hpp:959
void unmatch(BC bc)
Unmatch the edge and the incident nodes.
Definition dom-sup.hpp:933
Edge ** vprev_ref(void)
return the reference to the previous edge incident on v
Definition dom-sup.hpp:905
Edge * prev(void) const
return the pointer to the previous edge incident on x
Definition dom-sup.hpp:893
void unlink(void)
Unlink the edge from the linked list of edges.
Definition dom-sup.hpp:808
void insert_edge(void)
Insert the edge again.
Definition dom-sup.hpp:983
Edge ** vnext_ref(void)
return the reference to the next edge incident on v
Definition dom-sup.hpp:889
Edge(void)
Default constructor.
Definition dom-sup.hpp:299
ValNode * getVal(void) const
return the pointer to the value node v of this edge
Definition dom-sup.hpp:919
Node * getMate(bool t) const
return pointer to x if t = true otherwise return v
Definition dom-sup.hpp:925
bool matched(BC bc) const
return whether the edge is matched
Definition dom-sup.hpp:970
void reset(BC bc)
Reset the edge (free the edge, and unmatch the edge).
Definition dom-sup.hpp:954
bool used(BC bc) const
Whether the edge is used.
Definition dom-sup.hpp:865
Edge * next(void) const
return the pointer to the next edge incident on x
Definition dom-sup.hpp:872
Edge ** next_ref(void)
return the reference to the next edge incident on x
Definition dom-sup.hpp:909
VarNode * getVar(void) const
return the pointer to the variable node x of this edge
Definition dom-sup.hpp:913
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...
Definition dom-sup.hpp:876
Base class for nodes in the variable-value-graph.
Definition dom-sup.hpp:52
Edge * e
Stores all incident edges on the node.
Definition dom-sup.hpp:55
Edge * lst
Last edge.
Definition dom-sup.hpp:59
bool type(void) const
Return the type of the node (false for a variable node).
Definition dom-sup.hpp:534
Edge * last(void) const
Return pointer to the last incident edge.
Definition dom-sup.hpp:522
bool removed(void) const
check whether a node has been removed from the graph
Definition dom-sup.hpp:546
Edge * fst
First edge.
Definition dom-sup.hpp:57
Node(void)
Default constructor.
Definition dom-sup.hpp:507
int noe
stores the number of incident edges on the node
Definition dom-sup.hpp:79
NodeFlag
Flags for nodes.
Definition dom-sup.hpp:65
@ NF_M_UBC
Whether matched for UBC.
Definition dom-sup.hpp:73
@ NF_VAL
Whether node is a value node.
Definition dom-sup.hpp:69
@ NF_NONE
No flags set.
Definition dom-sup.hpp:67
@ NF_M_LBC
Whether matched for LBC.
Definition dom-sup.hpp:71
Edge * inedge(void) const
Return pointer to the node's inedge.
Definition dom-sup.hpp:538
Edge * first(void) const
Return pointer to the first incident edge.
Definition dom-sup.hpp:518
unsigned char nf
Flags for node.
Definition dom-sup.hpp:76
Edge * ie
Single incoming edge used for storing a path in the algorithms.
Definition dom-sup.hpp:61
Edge ** adj(void)
Return reference to the incident edges.
Definition dom-sup.hpp:514
int index(void) const
Get index of either variable or value.
Definition dom-sup.hpp:554
int lb
Minimal capacity of the value node.
Definition dom-sup.hpp:179
int _kidx
Index to access the value via cardinality array k.
Definition dom-sup.hpp:173
void unmatch(BC bc)
unmatch the node
Definition dom-sup.hpp:740
int kmin(void) const
return the minimal node capacity as stored in k
Definition dom-sup.hpp:701
int kbound(BC bc) const
return minimal or maximal capacity
Definition dom-sup.hpp:687
void match(BC bc)
match the node
Definition dom-sup.hpp:735
int incid_match(BC bc) const
returns the number of incident matching edges on a value node
Definition dom-sup.hpp:779
int _klb
Minimal required occurrence of the value as stored in k.
Definition dom-sup.hpp:169
int _kcount
Stores the current number of occurrences of the value.
Definition dom-sup.hpp:175
int ublow
Smallest maximal capacity of the value node.
Definition dom-sup.hpp:181
bool matched(BC bc) const
returns true if the node is matched in BC, false otherwise
Definition dom-sup.hpp:674
bool source(void) const
tests whether the node is a source
Definition dom-sup.hpp:795
int maxlow(void) const
get max cap for LBC
Definition dom-sup.hpp:642
int card_conflict(void) const
Check whether the value node is conflicting.
Definition dom-sup.hpp:662
int noc
Store numbre of conflicting matching edges.
Definition dom-sup.hpp:177
void card_conflict(int c)
Mark the value node as conflicting in case of variable cardinalities.
Definition dom-sup.hpp:651
void dec(BC bc)
decrease the node-capacity
Definition dom-sup.hpp:717
void reset(void)
node reset to original capacity values
Definition dom-sup.hpp:679
int val
Stores the value of the node.
Definition dom-sup.hpp:186
int kmax(void) const
return the maximal node capacity as stored in k
Definition dom-sup.hpp:696
void red_conflict(void)
Reduce the conflict counter.
Definition dom-sup.hpp:656
int kcount(void) const
returns the current number of occurrences of the value
Definition dom-sup.hpp:758
bool sink(void) const
tests whether the node is a sink
Definition dom-sup.hpp:788
int _kub
Maximal required occurrence of the value as stored in k.
Definition dom-sup.hpp:171
int ub
Maximal capacity of the value node.
Definition dom-sup.hpp:183
int cap(BC bc) const
return the node-capacity
Definition dom-sup.hpp:667
int kindex(void) const
returns the index in cardinality array k
Definition dom-sup.hpp:773
ValNode(void)
Default constructor.
Definition dom-sup.hpp:625
void inc(void)
increases the value counter
Definition dom-sup.hpp:753
Edge * ubm
Stores the matching edge on this node in the UBC.
Definition dom-sup.hpp:134
void match(BC bc)
Set node to matched.
Definition dom-sup.hpp:585
VarNode(void)
Default constructor.
Definition dom-sup.hpp:570
bool matched(BC bc) const
tests whether the node is matched or not
Definition dom-sup.hpp:577
void set_match(BC bc, Edge *m)
Set the pointer of the matching edge to m.
Definition dom-sup.hpp:593
Edge * get_match(BC bc) const
Return the matching edge on the node.
Definition dom-sup.hpp:610
void unmatch(BC bc)
Unmatch the node.
Definition dom-sup.hpp:601
Edge * lbm
Stores the matching edge on this node in the LBC.
Definition dom-sup.hpp:136
ExecStatus maximum_matching(void)
Compute a maximum matching M on the graph.
Definition dom-sup.hpp:1509
ExecStatus min_require(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k)
Check whether minimum requirements shrink variable domains.
Definition dom-sup.hpp:1074
void strongly_connected_components(void)
Compute possible strongly connected components of the graph.
Definition dom-sup.hpp:1743
ExecStatus narrow(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k)
Remove edges that do not belong to any maximal matching.
Definition dom-sup.hpp:1414
void dfs(Node *, BitSet &, BitSet &, int[], NodeStack &, NodeStack &, int &)
Perform depth-first search on the graph.
Definition dom-sup.hpp:1679
void free_alternating_paths(void)
Compute possible free alternating paths in the graph.
Definition dom-sup.hpp:1573
bool augmenting_path(Node *)
Test whether the current maximal matching on the graph can be augmented by an alternating path starti...
Definition dom-sup.hpp:1140
ExecStatus sync(ViewArray< IntView > &x, ViewArray< Card > &k)
Synchronization of the graph.
Definition dom-sup.hpp:1233
VarValGraph(Space &home, ViewArray< IntView > &x, ViewArray< Card > &k, int smin, int smax)
Constructor for the variable-value-graph.
Definition dom-sup.hpp:1004
Value iterator for integer views.
Definition view.hpp:94
int val(void) const
Return current value.
Handle to region.
Definition region.hpp:55
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition region.hpp:386
Computation spaces.
Definition core.hpp:1775
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
Definition core.hpp:2901
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.
Simple bitsets.
Definition bitset.hpp:45
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.
View arrays.
Definition array.hpp:255
void move_lst(int i)
Move view from position size()-1 to position i (truncate array by one).
Definition array.hpp:1236
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1156
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition macros.hpp:52
Global cardinality propagators (Counting).
BC
Bounds constraint (BC) type.
Definition dom-sup.hpp:48
Finite domain integers.
Definition lastval.hh:52
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 .
Definition aliases.hpp:163
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.
Definition dfs.hpp:73
ExecStatus
Definition core.hpp:479
@ ES_OK
Execution is okay.
Definition core.hpp:483
@ ES_FAILED
Execution has resulted in failure.
Definition core.hpp:481
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56
#define GECODE_ASSUME(p)
Assert certain property.
Definition macros.hpp:114