00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Int { namespace GCC {
00039
00046 enum BC {UBC = 1, LBC = 0};
00047
00048 class Edge;
00050 class VVGNode {
00051 private:
00053 Edge* e;
00055 Edge* fst;
00057 Edge* lst;
00059 Edge* ie;
00061 bool lm;
00063 bool um;
00065 bool type;
00066 public:
00068
00069
00070 VVGNode(void);
00072
00073 virtual ~VVGNode(void){};
00075 void* operator new(size_t, void*);
00076
00078
00079
00080 Edge** adj(void);
00082 Edge* first(void);
00084 Edge* last(void);
00086 Edge* inedge(void);
00088 bool get_type(void);
00090 template <BC>
00091 bool get_match_flag(void);
00093 virtual int get_info(void) = 0;
00095 virtual bool is_matched(BC) = 0;
00096
00098 virtual bool removed(void) = 0;
00100
00102
00103
00104 void first(Edge* p);
00106 void last(Edge* p);
00108 void inedge(Edge* p);
00110 void set_type(bool t);
00112 template <BC>
00113 void set_match_flag(bool f);
00115 virtual void set_info(int i) = 0;
00117 };
00118
00120 class VarNode : public VVGNode {
00121 private:
00123 Edge* ubm;
00125 Edge* lbm;
00126
00127 public:
00129 int var;
00131 int noe;
00132
00134 int xindex;
00135
00137
00138
00139 VarNode(int i, int oidx);
00141
00143
00144
00145 template <BC>
00146 Edge* get_match(void);
00148 int get_info(void);
00150 bool is_matched(BC);
00152 template <BC>
00153 bool matched(void);
00154
00156 bool removed(void);
00158
00160
00161
00162 void set_info(int i);
00164 template <BC>
00165 void set_match(Edge* m);
00167 template <BC>
00168 void match(void);
00170 template <BC>
00171 void unmatch(void);
00173 };
00174
00176 class ValNode : public VVGNode {
00177 private:
00179 int _klb;
00181 int _kub;
00183 int _kidx;
00185 int _kcount;
00186
00187
00189 int noc;
00190
00196 int lb;
00197 int ublow;
00204 int ub;
00205
00206 public:
00208 int val;
00210 int idx;
00212 int noe;
00213
00215
00216
00223 ValNode(int min, int max, int value, int kidx, int kshift, int count);
00225
00227
00228
00230 void set_maxlow(int i);
00232 int get_maxlow(void);
00233
00234
00236 void card_conflict(int c);
00238 int card_conflict(void);
00240 void red_conflict(void);
00241
00243 bool removed(void);
00244
00246 void inc(void);
00248 int kcount(void);
00250 template <BC>
00251 int incid_match(void);
00253 int kindex(void);
00255 int get_info(void);
00257 template <BC>
00258 bool matched(void);
00260 bool sink(void);
00262 bool source(void);
00264 int kmin(void);
00266 int kmax(void);
00268 template <BC>
00269 int kbound(void);
00270
00272 bool is_matched(BC);
00274
00276
00277 void kcount(int);
00279 void kindex(int);
00281 template <BC>
00282 void dec(void);
00284 template <BC>
00285 void inc(void);
00287 template <BC>
00288 int cap(void);
00290 template <BC>
00291 void set_cap(int c);
00293 template <BC>
00294 void match(void);
00296 template <BC>
00297 void unmatch(void);
00299 void reset(void);
00301 void set_info(int i);
00303 void set_kmin(int min);
00305 void set_kmax(int max);
00307 };
00308
00310 class Edge{
00311 private:
00313 VarNode* x;
00315 ValNode* v;
00317 Edge* next_edge;
00319 Edge* prev_edge;
00321 Edge* next_vedge;
00323 Edge* prev_vedge;
00329 bool mrklb;
00335 bool mrkub;
00337 bool um;
00339 bool lm;
00341 bool deleted;
00342
00343 public:
00345
00346
00350 Edge(VarNode* x, ValNode* v);
00352 void* operator new(size_t, void*);
00354
00356
00357
00364 template <BC>
00365 bool used(void);
00367 template <BC>
00368 bool matched(void);
00370 bool is_deleted(void);
00376 Edge* next(bool t) const;
00378 Edge* next(void) const;
00380 Edge* prev(void) const;
00382 Edge* vnext(void) const;
00384 Edge* vprev(void) const;
00386 VarNode* getVar(void);
00388 ValNode* getVal(void);
00393 VVGNode* getMate(bool t);
00395
00397
00398
00399 template <BC>
00400 void use(void);
00402 template <BC>
00403 void free(void);
00409 template <BC>
00410 void reset(void);
00412 template <BC>
00413 void match(void);
00415 template <BC>
00416 void unmatch(void);
00418 template <BC>
00419 void unmatch(bool t);
00421 void unlink(void);
00423 void del_edge(void);
00425 void insert_edge(void);
00427 Edge** next_ref(void);
00429 Edge** prev_ref(void);
00431 Edge** vnext_ref(void);
00433 Edge** vprev_ref(void);
00435 };
00436
00437
00442 template <class View, class Card, bool isView>
00443 class VarValGraph {
00444 private:
00446 bool fail;
00448 char* mem;
00450 size_t _allocated;
00452 ViewArray<View>& x;
00454 ViewArray<View>& y;
00456 ViewArray<Card>& k;
00458 VarNode** vars;
00466 ValNode** vals;
00468 Edge* edges;
00470 int n_var;
00476 int n_val;
00478 int n_edge;
00480 int node_size;
00486 int sum_min;
00492 int sum_max;
00493 public:
00495
00496 VarValGraph(ViewArray<View>&, ViewArray<View>&, ViewArray<Card>&,
00497 int , int , int );
00499 ~VarValGraph(void);
00501 size_t allocated(void) const;
00503
00504
00510 bool failed(void) const;
00514 void failed(bool b);
00515
00520 bool min_require(Space& home);
00521
00530 bool sync(Space& home);
00531
00533 void* operator new(size_t t);
00535 void operator delete(void* p);
00536
00544 template <BC>
00545 bool narrow(Space& home);
00546
00553 template <BC>
00554 bool maximum_matching(Space& home);
00555
00557 template <BC>
00558 void free_alternating_paths(Space& home);
00560 template <BC>
00561 void strongly_connected_components(Space& home);
00567 template <BC>
00568 bool augmenting_path(Space& home, VVGNode*);
00569
00570 protected:
00577 template <BC>
00578 void dfs(VVGNode*,
00579 bool[], bool[], int[],
00580 Support::StaticStack<VVGNode*,Region>&,
00581 Support::StaticStack<VVGNode*,Region>&,
00582 int&);
00583
00585 };
00586
00587 forceinline
00588 VVGNode::VVGNode(void){}
00589
00590 forceinline void*
00591 VVGNode::operator new(size_t, void* p){
00592 return p;
00593 }
00594
00595 forceinline Edge**
00596 VVGNode::adj(void){
00597 return &e;
00598 }
00599
00600 forceinline Edge*
00601 VVGNode::first(void){
00602 return fst;
00603 }
00604
00605 forceinline Edge*
00606 VVGNode::last(void){
00607 return lst;
00608 }
00609
00610 forceinline void
00611 VVGNode::first(Edge* p){
00612 fst = p;
00613 }
00614
00615 forceinline void
00616 VVGNode::last(Edge* p){
00617 lst = p;
00618 }
00619
00620 forceinline bool
00621 VVGNode::get_type(void){
00622 return type;
00623 }
00624
00625 forceinline void
00626 VVGNode::set_type(bool b){
00627 type = b;
00628 }
00629
00630 forceinline Edge*
00631 VVGNode::inedge(void){
00632 return ie;
00633 }
00634
00635 forceinline void
00636 VVGNode::inedge(Edge* p){
00637 ie = p;
00638 }
00639
00640 template <BC direction>
00641 forceinline void
00642 VVGNode::set_match_flag(bool b){
00643 if (direction == UBC) {
00644 um = b;
00645 } else {
00646 lm = b;
00647 }
00648 }
00649
00650 template <BC direction>
00651 forceinline bool
00652 VVGNode::get_match_flag(void){
00653 if (direction == UBC) {
00654 return um;
00655 } else {
00656 return lm;
00657 }
00658 }
00659
00660
00662
00663 forceinline bool
00664 VarNode::removed(void) {
00665 return noe == 0;
00666 }
00667
00668
00669
00670 forceinline
00671 VarNode::VarNode(int x, int orig_idx) :
00672 ubm(NULL), lbm(NULL), var(x), noe(0), xindex(orig_idx){
00673 first(NULL);
00674 last(NULL);
00675 inedge(NULL);
00676 unmatch<LBC>();
00677 unmatch<UBC>();
00678 set_type(false);
00679 }
00680
00681 forceinline bool
00682 VarNode::is_matched(BC d) {
00683 if (d == UBC) {
00684 return matched<UBC>();
00685 } else {
00686 return matched<LBC>();
00687 }
00688 }
00689
00690 template <BC direction>
00691 forceinline bool
00692 VarNode::matched(void){
00693 return get_match_flag<direction>();
00694 }
00695
00696 template <BC direction>
00697 forceinline void
00698 VarNode::match(void){
00699 set_match_flag<direction>(true);
00700 }
00701
00702 template <BC direction>
00703 forceinline void
00704 VarNode::unmatch(void){
00705 set_match_flag<direction>(false);
00706 set_match<direction>(NULL);
00707 }
00708
00709 template <BC direction>
00710 forceinline void
00711 VarNode::set_match(Edge* p){
00712 if (direction == UBC) {
00713 ubm = p;
00714 } else {
00715 lbm = p;
00716 }
00717 }
00718
00719 template <BC direction>
00720 forceinline Edge*
00721 VarNode::get_match(void){
00722 if (direction == UBC) {
00723 return ubm;
00724 } else {
00725 return lbm;
00726 }
00727 }
00728
00729 forceinline void
00730 VarNode::set_info(int i){
00731 var = i;
00732 }
00733
00734 forceinline int
00735 VarNode::get_info(void){
00736 return var;
00737 }
00738
00740
00741 forceinline void
00742 ValNode::set_maxlow(int i){
00743 assert(i >= lb);
00744 ublow = i;
00745 }
00746
00747 forceinline int
00748 ValNode::get_maxlow(void) {
00749 if (_klb == _kub) {
00750 assert(ublow == lb);
00751 }
00752
00753 return ublow;
00754 }
00755
00756
00757 forceinline void
00758 ValNode::card_conflict(int c){
00759 noc = c;
00760 }
00761
00762 forceinline void
00763 ValNode::red_conflict(void){
00764 noc--;
00765 assert(noc >= 0);
00766 }
00767
00768 forceinline int
00769 ValNode::card_conflict(void){
00770 return noc;
00771 }
00772
00773 forceinline bool
00774 ValNode::removed(void) {
00775 return noe == 0;
00776 }
00777
00778 forceinline bool
00779 ValNode::is_matched(BC d) {
00780 if (d == UBC) {
00781 return matched<UBC>();
00782 } else {
00783 return ublow == 0;
00784 }
00785 }
00786
00787 forceinline void
00788 ValNode::reset(void){
00789 lb = _klb;
00790 ublow = _kub;
00791 ub = _kub;
00792 noe = 0;
00793 }
00794
00795 template <BC direction>
00796 forceinline int
00797 ValNode::kbound(void){
00798 if (direction == UBC) {
00799 return _kub;
00800 } else {
00801 return _klb;
00802 }
00803 }
00804
00805 forceinline int
00806 ValNode::kmax(void){
00807 return _kub;
00808 }
00809
00810 forceinline int
00811 ValNode::kmin(void){
00812 return _klb;
00813 }
00814
00815 forceinline void
00816 ValNode::set_kmin(int klb){
00817 _klb = klb;
00818 }
00819
00820 forceinline void
00821 ValNode::set_kmax(int kub){
00822 _kub = kub;
00823 }
00824
00825 template <BC direction>
00826 forceinline int
00827 ValNode::cap(void){
00828 if (direction == UBC) {
00829 return ub;
00830 } else {
00831 return lb;
00832 }
00833 }
00834
00835 template <BC direction>
00836 forceinline void
00837 ValNode::dec(void){
00838 if (direction == UBC) {
00839 ub--;
00840 } else {
00841 lb--;
00842 ublow--;
00843 }
00844 }
00845
00846 template <BC direction>
00847 forceinline void
00848 ValNode::inc(void){
00849 if (direction == UBC) {
00850 ub++;
00851 } else {
00852 lb++;
00853 ublow++;
00854 }
00855 }
00856
00857 template <BC direction>
00858 forceinline void
00859 ValNode::match(void){
00860 dec<direction>();
00861 }
00862
00863 template <BC direction>
00864 forceinline void
00865 ValNode::unmatch(void){
00866 inc<direction>();
00867 }
00868
00869 template <BC direction>
00870 forceinline bool
00871 ValNode::matched(void){
00872 return ( cap<direction>() == 0);
00873 }
00874
00875 forceinline
00876 ValNode::ValNode(int min, int max, int value,
00877 int kidx, int kshift, int count) :
00878 _klb(min), _kub(max), _kidx(kidx), _kcount(count),
00879 noc(0),
00880 lb(min), ublow(max), ub(max),
00881 val(value), idx(kshift), noe(0) {
00882 first(NULL);
00883 last(NULL);
00884 inedge(NULL);
00885 Edge** vadjacent = adj();
00886 *vadjacent = NULL;
00887 set_type(true);
00888 }
00889
00890 template<BC direction>
00891 forceinline void
00892 ValNode::set_cap(int c){
00893 if (direction == UBC) {
00894 ub = c;
00895 } else {
00896 lb = c;
00897
00898 }
00899 }
00900
00901 forceinline void
00902 ValNode::set_info(int i){
00903 idx = i;
00904 }
00905
00906 forceinline int
00907 ValNode::get_info(void){
00908 return idx;
00909 }
00910
00911 forceinline void
00912 ValNode::inc(void) {
00913 _kcount++;
00914 }
00915
00916 forceinline int
00917 ValNode::kcount(void) {
00918 return _kcount;
00919 }
00920
00921 forceinline void
00922 ValNode::kcount(int c) {
00923 _kcount = c;
00924 }
00925
00926 forceinline void
00927 ValNode::kindex(int i){
00928 _kidx = i;
00929 }
00930
00931 forceinline int
00932 ValNode::kindex(void){
00933 return _kidx;
00934 }
00935
00937 template <BC direction>
00938 forceinline int
00939 ValNode::incid_match(void){
00940 if (direction == LBC) {
00941
00942 return _kub - ublow + _kcount;
00943 } else {
00944
00945 return _kub - ub + _kcount;
00946 }
00947 }
00948
00949
00950 forceinline bool
00951 ValNode::sink(void){
00952
00953
00954 bool is_sink = false;
00955 is_sink = (_kub - ub == noe);
00956 return is_sink;
00957 }
00958
00959 forceinline bool
00960 ValNode::source(void){
00961
00962
00963 bool is_sink = false;
00964 is_sink = (_klb - lb == noe);
00965 return is_sink;
00966 }
00967
00968 forceinline void
00969 Edge::unlink(void){
00970
00971 Edge* p = prev_edge;
00972 Edge* n = next_edge;
00973
00974 if (p != NULL) {
00975 Edge** pnext = p->next_ref();
00976 *pnext = n;
00977 }
00978
00979 if (n != NULL) {
00980 Edge** nprev = n->prev_ref();
00981 *nprev = p;
00982 }
00983
00984 if (this == x->first()) {
00985 Edge** ref = x->adj();
00986 *ref = n;
00987 x->first(n);
00988 }
00989
00990 if (this == x->last()) {
00991 x->last(p);
00992 }
00993
00994
00995 Edge* pv = prev_vedge;
00996 Edge* nv = next_vedge;
00997
00998 if (pv != NULL) {
00999 Edge** pvnext = pv->vnext_ref();
01000 *pvnext = nv;
01001 }
01002
01003 if (nv != NULL) {
01004 Edge** nvprev = nv->vprev_ref();
01005 *nvprev = pv;
01006 }
01007
01008 if (this == v->first()) {
01009 Edge** ref = v->adj();
01010 *ref = nv;
01011 v->first(nv);
01012 }
01013
01014 if (this == v->last()) {
01015 v->last(pv);
01016 }
01017 }
01018
01019 forceinline
01020 Edge::Edge(VarNode* var, ValNode* val) :
01021 x(var), v(val),
01022 next_edge(NULL), prev_edge(NULL),
01023 next_vedge(NULL), prev_vedge(NULL),
01024 mrklb(false), mrkub(false),
01025 um(false), lm(false), deleted(false) {}
01026
01027 forceinline void*
01028 Edge::operator new(size_t, void* p){
01029 return p;
01030 }
01031
01032 template <BC direction>
01033 forceinline void
01034 Edge::use(void){
01035 if (direction == UBC) {
01036 mrkub = true;
01037 } else {
01038 mrklb = true;
01039 }
01040 }
01041
01042 template <BC direction>
01043 forceinline void
01044 Edge::free(void){
01046 if (direction == UBC) {
01047 mrkub = false;
01048 } else {
01049 mrklb = false;
01050 }
01051 }
01052
01053 template <BC direction>
01054 forceinline void
01055 Edge::reset(void){
01056 this->free<direction>();
01057 this->unmatch<direction>();
01058 }
01059
01060 template <BC direction>
01061 forceinline bool
01062 Edge::used(void){
01063 if (direction == UBC){
01064 return mrkub;
01065 } else {
01066 return mrklb;
01067 }
01068 }
01069
01070 forceinline Edge*
01071 Edge::next(void) const{
01072 return next_edge;
01073 }
01074
01075 forceinline Edge*
01076 Edge::next(bool t) const{
01077 if (t) {
01078 return next_vedge;
01079 } else {
01080 return next_edge;
01081 }
01082 }
01083
01084 forceinline Edge*
01085 Edge::vnext(void) const{
01086 return next_vedge;
01087 }
01088
01089 forceinline Edge**
01090 Edge::vnext_ref(void) {
01091 return &next_vedge;
01092 }
01093
01094 forceinline Edge*
01095 Edge::prev(void) const{
01096 return prev_edge;
01097 }
01098
01099 forceinline Edge**
01100 Edge::prev_ref(void) {
01101 return &prev_edge;
01102 }
01103
01104 forceinline Edge*
01105 Edge::vprev(void) const{
01106 return prev_vedge;
01107 }
01108
01109 forceinline Edge**
01110 Edge::vprev_ref(void) {
01111 return &prev_vedge;
01112 }
01113
01114 forceinline Edge**
01115 Edge::next_ref(void){
01116 return &next_edge;
01117 }
01118 forceinline VarNode*
01119 Edge::getVar(void){
01120 assert(x != NULL);
01121 return x;
01122 }
01123
01124 forceinline ValNode*
01125 Edge::getVal(void){
01126 assert(v != NULL);
01127 return v;
01128 }
01129
01130 forceinline VVGNode*
01131 Edge::getMate(bool type){
01132 if (type) {
01133 return x;
01134 } else {
01135 return v;
01136 }
01137 }
01138
01139 template <BC direction>
01140 forceinline void
01141 Edge::unmatch(void){
01142 if (direction == UBC) {
01143 um = false;
01144 } else {
01145 lm = false;
01146 }
01147 x->unmatch<direction>();
01148 v->unmatch<direction>();
01149 }
01150
01151 template <BC direction>
01152 forceinline void
01153 Edge::unmatch(bool node){
01154 if (direction == UBC) {
01155 um = false;
01156 } else {
01157 lm = false;
01158 }
01159 if (node) {
01160 v->template unmatch<direction>();
01161 } else {
01162 x->template unmatch<direction>();
01163 }
01164 }
01165
01166 template <BC direction>
01167 forceinline void
01168 Edge::match(void){
01169 if (direction == UBC) {
01170 um = true;
01171 x->template match<direction>();
01172 x->template set_match<direction>(this);
01173 v->template match<direction>();
01174 } else {
01175 lm = true;
01176 x->template match<direction>();
01177 x->template set_match<direction>(this);
01178 assert(x->template matched<direction>());
01179 v->template match<direction>();
01180
01181 }
01182 }
01183
01184 template <BC direction>
01185 forceinline bool
01186 Edge::matched(void){
01187 if (direction == UBC) {
01188 return um;
01189 } else {
01190 return lm;
01191 }
01192 }
01193
01194 forceinline void
01195 Edge::del_edge(void){
01196 deleted = true;
01197 }
01198
01199 forceinline void
01200 Edge::insert_edge(void){
01201 deleted = false;
01202 }
01203
01204
01205 forceinline bool
01206 Edge::is_deleted(void){
01207 return deleted;
01208 }
01209
01223 template <class View, class Card, bool isView>
01224 VarValGraph<View, Card, isView>::VarValGraph(ViewArray<View>& xref,
01225 ViewArray<View>& yref,
01226 ViewArray<Card>& kref,
01227 int noe,
01228 int smin, int smax)
01229 : fail(false),
01230 x(xref),
01231 y(yref),
01232 k(kref),
01233 n_var(x.size()),
01234 n_val(k.size()),
01235 n_edge(noe),
01236 node_size(n_var + n_val),
01237 sum_min(smin),
01238 sum_max(smax) {
01239
01240
01241 size_t edge_size = sizeof(Edge) * n_edge;
01242 size_t var_size = sizeof(VarNode) * n_var;
01243 size_t var_ptr_size = sizeof(VarNode*) * n_var;
01244 size_t val_size = sizeof(ValNode) * n_val;
01245 size_t val_ptr_size = sizeof(ValNode*) * n_val;
01246 size_t size = edge_size + var_size + var_ptr_size +
01247 val_size + val_ptr_size;
01248
01249 _allocated = size;
01250
01251 mem = static_cast<char*>
01252 (heap.ralloc(size));
01253 edges = Support::ptr_cast<Edge*>
01254 (mem);
01255 VarNode* vars_ptr = Support::ptr_cast<VarNode*>
01256 (mem + edge_size);
01257 ValNode* vals_ptr = Support::ptr_cast<ValNode*>
01258 (mem + edge_size + var_size);
01259 vars = Support::ptr_cast<VarNode**>
01260 (mem + edge_size + var_size + val_size);
01261 vals = Support::ptr_cast<ValNode**>
01262 (mem + edge_size + var_size + val_size + var_ptr_size);
01263
01264 for (int i = n_val; i--; ){
01265 int kmi = k[i].min();
01266 int kma = k[i].max();
01267 int kc = k[i].counter();
01268 if (kc != kma) {
01269 if (kmi >= kc) {
01270 kmi -=kc;
01271 assert(kmi >=0);
01272 } else {
01273 kmi = 0;
01274 }
01275 kma -= kc;
01276 assert (kma > 0);
01277 vals[i] = new (vals_ptr + i)
01278 ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
01279 } else {
01280 vals[i] = new (vals_ptr + i)
01281 ValNode(0, 0, k[i].card(), i, i + n_var, kc);
01282 }
01283 }
01284
01285 for (int i = n_var; i--; ){
01286
01287 vars[i] = new (vars_ptr + i) VarNode(i, i);
01288 VarNode* vrn = vars[i];
01289
01290 Edge** xadjacent = vrn->adj();
01291
01292 ViewValues<View> xiter(x[i]);
01293 int j = 0;
01294 for (; xiter(); ++xiter){
01295 int v = xiter.val();
01296
01297 while(vals[j]->val < v){
01298 j++;
01299 }
01300 ValNode* vln = vals[j];
01301 *xadjacent = new (edges) Edge(vars_ptr + i, vals_ptr + j);
01302 vrn->noe++;
01303 if (vrn->first() == NULL) {
01304 vrn->first(*xadjacent);
01305 }
01306 Edge* oldprev = vrn->last();
01307 vrn->last(*xadjacent);
01308 Edge** newprev = vrn->last()->prev_ref();
01309 *newprev = oldprev;
01310
01311 if (vln->first() == NULL) {
01312 vln->first(*xadjacent);
01313 vln->last(*xadjacent);
01314 vln->noe++;
01315 } else {
01316 Edge* old = vln->first();
01317 vln->first(*xadjacent);
01318 Edge** newnext = vln->first()->vnext_ref();
01319 *newnext = old;
01320 Edge** setprev = old->vprev_ref();
01321 *setprev = vln->first();
01322 vln->noe++;
01323 }
01324 edges++;
01325 xadjacent = (*xadjacent)->next_ref();
01326 }
01327 *xadjacent = NULL;
01328 }
01329 }
01330
01331 template <class View, class Card, bool isView>
01332 forceinline size_t
01333 VarValGraph<View, Card, isView>::allocated(void) const {
01334 return _allocated + sizeof(VarValGraph<View, Card, isView>);
01335 }
01336
01337 template <class View, class Card, bool isView>
01338 forceinline bool
01339 VarValGraph<View, Card, isView>::failed(void) const {
01340 return fail;
01341 }
01342
01343 template <class View, class Card, bool isView>
01344 forceinline void
01345 VarValGraph<View, Card, isView>::failed(bool b){
01346 fail = b;
01347 }
01348
01349
01350
01351 template <class View, class Card, bool isView>
01352 inline bool
01353 VarValGraph<View, Card, isView>::min_require(Space& home){
01354 bool modified = false;
01355 for (int i = n_val; i--; ) {
01356 ValNode* vln = vals[i];
01357 if (vln->noe > 0) {
01358 if (k[i].min() == vln->noe) {
01359
01360 for (Edge* e = vln->first(); e != NULL; e = e->vnext()) {
01361 VarNode* vrn = e->getVar();
01362 int vi = vrn->get_info();
01363 for (Edge* f = vrn->first(); f != NULL; f = f->next()) {
01364 if (f != e) {
01365 ValNode* w = f->getVal();
01366 w->noe--;
01367 vrn->noe--;
01368 f->del_edge();
01369 f->unlink();
01370 }
01371 }
01372 assert(vrn->noe == 1);
01373
01374 ModEvent me = x[vi].eq(home, vln->val);
01375 if (me_failed(me))
01376 failed(true);
01377 if (me_modified(me))
01378 modified = true;
01379
01380 vars[vi] = vars[--n_var];
01381 vars[vi]->set_info(vi);
01382
01383 int n = x.size();
01384 x[vi] = x[--n];
01385 x.size(n);
01386
01387 node_size--;
01388 vln->noe--;
01389 }
01390
01391
01392 int vidx = vln->kindex();
01393 if (isView) {
01394 ModEvent me = k[vidx].eq(home, k[vidx].min());
01395 if (me_failed(me))
01396 failed(true);
01397 if (me_modified(me))
01398 modified = true;
01399 }
01400
01401 k[vidx].counter(k[vidx].min());
01402
01403 vln->template set_cap<UBC>(0);
01404 vln->template set_cap<LBC>(0);
01405 vln->set_maxlow(0);
01406
01407 if (sum_min && sum_min >= k[vidx].min()) {
01408 sum_min -= k[vidx].min();
01409 }
01410 assert(sum_min >=0);
01411
01412 if (sum_max && sum_max >= k[vidx].max()) {
01413 sum_max -= k[vidx].max();
01414 }
01415 assert(sum_max >=0);
01416 }
01417 } else {
01418 vals[i]->template set_cap<UBC>(0);
01419 vals[i]->template set_cap<LBC>(0);
01420 vals[i]->set_maxlow(0);
01421 vals[i]->set_kmax(0);
01422 vals[i]->set_kmin(0);
01423
01424 }
01425
01426 if (isView) {
01427 if (k[i].counter() == 0) {
01428 ModEvent me = k[i].lq(home, vals[i]->noe);
01429 if (me_failed(me))
01430 failed(true);
01431 if (me_modified(me) && k[i].max() != vals[i]->noe)
01432 modified = true;
01433 }
01434 }
01435 }
01436
01437 for (int i = n_val; i--; )
01438 vals[i]->set_info(n_var + i);
01439
01440 return modified;
01441 }
01442
01443 template <class View, class Card, bool isView>
01444 inline bool
01445 VarValGraph<View, Card, isView>::sync(Space& home) {
01446 Region r(home);
01447 VVGNode** re = r.alloc<VVGNode*>(node_size);
01448 int n_re = 0;
01449
01450
01451 if (isView) {
01452 for (int i = n_val; i--; ) {
01453 ValNode* v = vals[i];
01454 int inc_ubc = v->template incid_match<UBC>();
01455 int inc_lbc = v->template incid_match<LBC>();
01456 if (v->noe == 0) {
01457 inc_ubc = 0;
01458 inc_lbc = 0;
01459 }
01460 int rm = v->kmax() - k[i].max();
01461
01462 if (k[i].max() < v->kmax() || k[i].min() > v->kmin()) {
01463 if (k[i].max() != k[i].counter() || k[i].max() == 0) {
01464
01465 v->set_kmax(k[i].max());
01466 v->set_kmin(k[i].min());
01467
01468
01469 if (inc_ubc <= k[i].max()) {
01470
01471 v->template set_cap<UBC>(k[i].max() - (inc_ubc));
01472 v->set_maxlow(k[i].max() - (inc_lbc));
01473 if (v->kmin() == v->kmax()) {
01474 v->template set_cap<LBC>(k[i].max() - (inc_lbc));
01475 }
01476 } else {
01477
01478
01479 if (v->template cap<UBC>()) {
01480 v->template set_cap<UBC>(k[i].max());
01481 }
01482 v->set_maxlow(k[i].max() - (inc_lbc));
01483 if (v->kmin() == v->kmax()) {
01484 v->template set_cap<LBC>(k[i].max() - (inc_lbc));
01485 }
01486 v->card_conflict(rm);
01487 }
01488 }
01489 }
01490 if (inc_lbc < k[i].min() && v->noe > 0) {
01491
01492 v->template set_cap<LBC>(k[i].min() - inc_lbc);
01493 re[n_re] = v;
01494 n_re++;
01495 }
01496 }
01497
01498 for (int i = n_var; i--; ) {
01499 Edge* mub = vars[i]->template get_match<UBC>();
01500 if (mub != NULL) {
01501 ValNode* vu = mub->getVal();
01502 if (! (vars[i]->noe == 1) ) {
01503 if (vu->card_conflict()) {
01504 vu->red_conflict();
01505 mub->template unmatch<UBC>(vars[i]->get_type());
01506 re[n_re] = vars[i];
01507 n_re++;
01508 }
01509 }
01510 }
01511 }
01512 }
01513
01514
01515 assert(x.size() == n_var);
01516 for (int i = n_var; i--; ) {
01517
01518 VarNode* vrn = vars[i];
01519 if(static_cast<int>(x[i].size()) != vrn->noe){
01520
01521 if (x[i].assigned()) {
01522 int v = x[i].val();
01523 ValNode* rv = NULL;
01524 int rv_idx = 0;
01525 Edge* mub = vrn->template get_match<UBC>();
01526 if (mub != NULL) {
01527 if (v != mub->getVal()->val) {
01528 mub->template unmatch<UBC>();
01529 re[n_re] = vars[i];
01530 n_re++;
01531 }
01532 }
01533
01534 Edge* mlb = vrn->template get_match<LBC>();
01535 if (mlb != NULL) {
01536 ValNode* vln = mlb->getVal();
01537 if (v != vln->val) {
01538 mlb->template unmatch<LBC>();
01539 int nom = vln->template incid_match<LBC>();
01540
01541 bool cond = nom < vln->kmin();
01542 if (cond) {
01543 re[n_re] = vln;
01544 n_re++;
01545 }
01546 }
01547 }
01548
01549 for (Edge* e = vrn->first(); e != NULL; e = e->next()){
01550 ValNode* vln = e->getVal();
01551 if (vln->val != v) {
01552 vrn->noe--;
01553 e->getVal()->noe--;
01554 e->del_edge();
01555 e->unlink();
01556 } else {
01557 rv = e->getVal();
01558 rv_idx = rv->kindex();
01559 }
01560 }
01561 } else {
01562
01563
01564 ViewValues<View> xiter(x[i]);
01565 Edge* mub = vrn->template get_match<UBC>();
01566 Edge* mlb = vrn->template get_match<LBC>();
01567 Edge** p = vrn->adj();
01568 Edge* e = *p;
01569 do {
01570
01571 while (e != NULL && e->getVal()->val < xiter.val()) {
01572
01573 e->getVal()->noe--;
01574 vrn->noe--;
01575 e->del_edge();
01576 e->unlink();
01577 e = e ->next();
01578 *p = e;
01579 }
01580
01581 assert(xiter.val() == e->getVal()->val);
01582
01583
01584 e->template free<UBC>();
01585 e->template free<LBC>();
01586 ++xiter;
01587 p = e->next_ref();
01588 e = e->next();
01589 } while (xiter());
01590 *p = NULL;
01591 while (e) {
01592 e->getVar()->noe--;
01593 e->getVal()->noe--;
01594 e->del_edge();
01595 e->unlink();
01596 e = e->next();
01597 }
01598
01599 if (mub != NULL){
01600 if (mub->is_deleted()) {
01601 mub->template unmatch<UBC>();
01602 re[n_re] = vars[i];
01603 n_re++;
01604 }
01605 }
01606
01607
01608 if (mlb != NULL) {
01609 if (mlb->is_deleted()) {
01610 ValNode* vln = mlb->getVal();
01611 mlb->template unmatch<LBC>();
01612 int nom = vln->template incid_match<LBC>();
01613 bool cond = nom < vln->kmin();
01614 if (cond) {
01615 re[n_re] = vln;
01616 n_re++;
01617 }
01618 }
01619 }
01620 }
01621 }
01622 vars[i]->set_info(i);
01623 }
01624
01625 for (int i = n_val; i--; ) {
01626 if (k[i].min() > vals[i]->noe && k[i].counter() == 0) {
01627 failed(true);
01628 return false;
01629 }
01630 vals[i]->set_info(n_var + i);
01631 }
01632
01633 if (n_re == 0) {
01634
01635 return true;
01636 } else {
01637
01638
01639 bool repaired = true;
01640 while (n_re ) {
01641 n_re--;
01642 assert(re[n_re] != NULL);
01643 if (!(re[n_re]->removed())) {
01644 if (!(re[n_re]->get_type())) {
01645 VarNode* vrn = static_cast<VarNode*>(re[n_re]);
01646 if (!vrn->template matched<UBC>()) {
01647 repaired &= augmenting_path<UBC>(home,vrn);
01648 }
01649 } else {
01650 assert(re[n_re]->get_type());
01651 ValNode* vln = static_cast<ValNode*>(re[n_re]);
01652 while(!vln->template matched<LBC>()) {
01653 repaired &= augmenting_path<LBC>(home,vln);
01654 if (!repaired) {
01655 break;
01656 }
01657 }
01658 }
01659 }
01660 }
01661 return repaired;
01662 }
01663 }
01664
01665 template <class View, class Card, bool isView> template <BC direction>
01666 inline bool
01667 VarValGraph<View, Card, isView>::narrow(Space& home) {
01668 bool modified = false;
01669 for (int i = n_var; i--; ) {
01670 VarNode* vrn = vars[i];
01671 if (vrn->noe == 1) {
01672 Edge* e = vrn->first();
01673 ValNode* v = e->getVal();
01674 e->template free<direction>();
01675 ModEvent me = x[i].eq(home, v->val);
01676 if (me_failed(me)) {
01677 failed(true);
01678 return false;
01679 }
01680 if (me_modified(me))
01681 modified = true;
01682 v->inc();
01683 }
01684 }
01685 for (int i = n_val; i--; ) {
01686 ValNode* v = vals[i];
01687 if (isView)
01688 if (k[i].counter() == 0) {
01689 ModEvent me = k[i].lq(home, v->noe);
01690 if (me_failed(me)) {
01691 failed(true);
01692 return false;
01693 }
01694 modified |= me_modified(me);
01695 }
01696
01697 if (v->noe > 0) {
01698
01699 if (isView) {
01700 ModEvent me = k[i].lq(home, v->noe);
01701 if (me_failed(me)) {
01702 failed(true);
01703 return false;
01704 }
01705 modified |= me_modified(me);
01706 }
01707
01708
01709
01710
01711 if (v->kcount() == v->kmax()) {
01712 int vidx = v->kindex();
01713
01714 k[i].counter(v->kcount());
01715
01716 if (isView) {
01717 if (!k[i].assigned()) {
01718 ModEvent me = k[i].eq(home, k[i].counter());
01719 if (me_failed(me)) {
01720 failed(true);
01721 return false;
01722 }
01723 modified |= me_modified(me);
01724 }
01725 }
01726
01727 bool delall = false;
01728 if (v->card_conflict() &&
01729 v->noe > v->kmax()) {
01730 delall = true;
01731
01732 }
01733
01734 for (Edge* e = v->last(); e != NULL; e = e->vprev()) {
01735 VarNode* vrn = e->getVar();
01736 if (vrn->noe == 1) {
01737 vrn->noe--;
01738 v->noe--;
01739 int vi= vrn->get_info();
01740
01741 int n = x.size();
01742 x[vi] = x[--n];
01743
01744 x.size(n);
01745
01746 vars[vi] = vars[--n_var];
01747 vars[vi]->set_info(vi);
01748 node_size--;
01749 e->del_edge();
01750 e->unlink();
01751
01752 } else {
01753 if (delall) {
01754 ModEvent me = x[vrn->get_info()].nq(home, v->val);
01755 if (me_failed(me)) {
01756 failed(true);
01757 return false;
01758 }
01759 modified |= me_modified(me);
01760 vrn->noe--;
01761 v->noe--;
01762 e->del_edge();
01763 e->unlink();
01764 }
01765 }
01766 }
01767 v->template set_cap<UBC>(0);
01768 v->template set_cap<LBC>(0);
01769 v->set_maxlow(0);
01770 if (sum_min && sum_min >= k[vidx].min()) {
01771 sum_min -= k[vidx].min();
01772 }
01773 assert(sum_min >=0);
01774
01775 if (sum_max && sum_max >= k[vidx].max()) {
01776 sum_max -= k[vidx].max();
01777 }
01778 assert(sum_max >=0);
01779
01780 } else {
01781 int cur = v->kcount();
01782 if (cur > 0) {
01783 v->kcount(0);
01784 }
01785 }
01786 }
01787 }
01788 for (int i = n_var; i--; )
01789 vars[i]->set_info(i);
01790
01791 for (int i = n_val; i--; ) {
01792 if (vals[i]->noe == 0) {
01793 vals[i]->template set_cap<UBC>(0);
01794 vals[i]->template set_cap<LBC>(0);
01795 vals[i]->set_maxlow(0);
01796 }
01797 vals[i]->set_info(n_var + i);
01798 }
01799
01800 for (int i = n_var; i--; )
01801 if (vars[i]->noe > 1)
01802 for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
01803 bool keepedge = false;
01804 keepedge = (e->template matched<direction>() ||
01805 e->template used<direction>());
01806 if (!keepedge) {
01807 ValNode* v = e->getVal();
01808 ModEvent me = x[i].nq(home, v->val);
01809 if (me_failed(me)) {
01810 failed(true);
01811 return false;
01812 }
01813 modified |= me_modified(me);
01814 } else {
01815 e->template free<direction>();
01816 }
01817 }
01818 return modified;
01819 }
01820
01821 template <class View, class Card, bool isView> template <BC direction>
01822 inline bool
01823 VarValGraph<View, Card, isView>::maximum_matching(Space& home) {
01824
01825 int required_size = 0;
01826 int card_match = 0;
01827
01828 if (direction == UBC) {
01829 required_size = n_var;
01830 } else {
01831 required_size = sum_min;
01832 }
01833
01834
01835
01836
01837 for (int i = n_val; i--; ) {
01838 ValNode* vln = vals[i];
01839 for (Edge* e = vln->first(); e != NULL ; e = e->vnext()) {
01840 VarNode* vrn = e->getVar();
01841 if (!vrn->template matched<direction>() &&
01842 !vln->template matched<direction>()) {
01843 e->template match<direction>();
01844 card_match++;
01845 }
01846 }
01847 }
01848
01849 Region r(home);
01850 if (card_match < required_size) {
01851 if (direction == LBC) {
01852
01853 ValNode** free = r.alloc<ValNode*>(n_val);
01854 int f = 0;
01855
01856 for (int i = n_val; i--; ) {
01857 ValNode* vln = vals[i];
01858 if (!vln->template matched<direction>()) {
01859 free[f++] = vln;
01860 }
01861 }
01862
01863 for (int i = 0; i < f; i++) {
01864 while(!free[i]->template matched<direction>()) {
01865 if (augmenting_path<direction>(home,free[i])) {
01866 card_match++;
01867 } else {
01868 break;
01869 }
01870 }
01871 }
01872 } else {
01873 VarNode** free = r.alloc<VarNode*>(n_var);
01874 int f = 0;
01875
01876 for (int i = n_var; i--; ) {
01877 VarNode* vrn = vars[i];
01878 if (!vrn->template matched<direction>()) {
01879 free[f++] = vrn;
01880 }
01881 }
01882
01883 for (int i = 0; i < f; i++) {
01884 if (!free[i]->template matched<direction>()) {
01885 if (augmenting_path<direction>(home,free[i])) {
01886 card_match++;
01887 }
01888 }
01889 }
01890 }
01891 }
01892 return (card_match >= required_size);
01893 }
01894
01895 template <class View, class Card, bool isView> template<BC direction>
01896 inline bool
01897 VarValGraph<View, Card, isView>::augmenting_path(Space& home, VVGNode* v) {
01898 Region r(home);
01899 Support::StaticStack<VVGNode*,Region> ns(r,node_size);
01900 bool* visited = r.alloc<bool>(node_size);
01901 Edge** start = r.alloc<Edge*>(node_size);
01902
01903
01904 assert(!v->is_matched(direction));
01905
01906
01907 VVGNode* sn = v;
01908
01909
01910 bool sp = sn->get_type();
01911
01912
01913
01914
01915 for (int i = node_size; i--; )
01916 visited[i] = false;
01917
01918 for (int i = node_size; i--; )
01919 if (i >= n_var) {
01920 vals[i - n_var]->inedge(NULL);
01921 start[i] = vals[i - n_var]->first();
01922 } else {
01923 vars[i]->inedge(NULL);
01924 start[i] = vars[i]->first();
01925 }
01926
01927 v->inedge(NULL);
01928 ns.push(v);
01929 visited[v->get_info()] = true;
01930 while (!ns.empty()) {
01931 VVGNode* v = ns.top();
01932 Edge* e = NULL;
01933 if (v->get_type() == sp) {
01934
01935 e = start[v->get_info()];
01936 while (e != NULL && e->template matched<direction>()) {
01937 e = e->next(v->get_type());
01938 }
01939 } else {
01940 e = start[v->get_info()];
01941 while (e != NULL && !e->template matched<direction>()) {
01942 e = e->next(v->get_type());
01943 }
01944 start[v->get_info()] = e;
01945 }
01946 if (e != NULL) {
01947 start[v->get_info()] = e->next(v->get_type());
01948 VVGNode* w = e->getMate(v->get_type());
01949 if (!visited[w->get_info()]) {
01950
01951 if (!w->is_matched(direction) && w->get_type() != sp) {
01952 if (v->inedge() != NULL) {
01953
01954 e->template match<direction>();
01955 break;
01956 } else {
01957
01958 e->template match<direction>();
01959 ns.pop();
01960 return true;
01961 }
01962 } else {
01963 w->inedge(e);
01964 visited[w->get_info()] = true;
01965
01966 ns.push(w);
01967 }
01968 }
01969 } else {
01970
01971 ns.pop();
01972 }
01973 }
01974
01975 bool pathfound = false;
01976 if (!ns.empty()) {
01977 pathfound = true;
01978 }
01979
01980 while (!ns.empty()) {
01981 VVGNode* t = ns.top();
01982 if (t != sn) {
01983 Edge* in = t->inedge();
01984 if (t->get_type() != sp) {
01985 assert(in != NULL);
01986 in->template match<direction>();
01987 } else {
01988
01989 if (!sp) {
01990 in->template unmatch<direction>(!sp);
01991 } else {
01992 in->template unmatch<direction>();
01993 }
01994 }
01995 ns.pop();
01996 } else {
01997 ns.pop();
01998 }
01999 }
02000 return pathfound;
02001 }
02002
02003 template <class View, class Card, bool isView> template<BC direction>
02004 inline void
02005 VarValGraph<View, Card, isView>::free_alternating_paths(Space& home) {
02006 Region r(home);
02007 Support::StaticStack<VVGNode*,Region> ns(r,node_size);
02008 bool* visited = r.alloc<bool>(node_size);
02009
02010 for (int i = node_size; i--; )
02011 visited[i] = false;
02012
02013 if (direction == LBC) {
02014
02015
02016
02017 for (int i = n_var; i--; ){
02018 if(!vars[i]->is_matched(LBC)){
02019
02020 ns.push(vars[i]);
02021 visited[vars[i]->get_info()] = true;
02022 }
02023 }
02024 for (int i = n_val; i--; ){
02025 if(!vals[i]->is_matched(LBC)){
02026
02027 ns.push(vals[i]);
02028 visited[vals[i]->get_info()] = true;
02029 }
02030 }
02031
02032 } else {
02033
02034
02035
02036
02037 for (int i = n_val; i--; ){
02038 if(!vals[i]->is_matched(UBC)){
02039
02040 ns.push(vals[i]);
02041 visited[vals[i]->get_info()] = true;
02042 }
02043 }
02044 }
02045
02046 while (!ns.empty()){
02047 VVGNode* node = ns.top();
02048 ns.pop();
02049 if (node->get_type()) {
02050
02051 ValNode* vln = static_cast<ValNode*>(node);
02052 for (Edge* cur = vln->first(); cur != NULL; cur = cur->vnext()) {
02053 VarNode* mate = cur->getVar();
02054 bool follow = false;
02055 switch (direction) {
02056
02057 case LBC:
02058 follow = cur->template matched<direction>();
02059 break;
02060 case UBC:
02061 follow = !cur->template matched<direction>();
02062 break;
02063 default: GECODE_NEVER;
02064 }
02065 if (follow) {
02066
02067 cur->template use<direction>();
02068 if (!visited[mate->get_info()]) {
02069 ns.push(mate);
02070 visited[mate->get_info()] = true;
02071 }
02072 }
02073 }
02074 } else {
02075
02076 VarNode* vrn = static_cast<VarNode*>(node);
02077 switch (direction) {
02078
02079 case LBC: {
02080 for (Edge* cur = vrn->first(); cur != NULL; cur = cur->next()){
02081 ValNode* mate = cur->getVal();
02082 if (!cur->template matched<LBC>()) {
02083 cur->template use<LBC>();
02084 if (!visited[mate->get_info()]) {
02085 ns.push(mate);
02086 visited[mate->get_info()] = true;
02087 }
02088 }
02089 }
02090 break;
02091 }
02092
02093 case UBC: {
02094 Edge* cur = vrn->template get_match<UBC>();
02095 if (cur != NULL) {
02096 cur->template use<UBC>();
02097 ValNode* mate = cur->getVal();
02098 if (!visited[mate->get_info()]) {
02099 ns.push(mate);
02100 visited[mate->get_info()] = true;
02101 }
02102 }
02103 break;
02104 }
02105 default: GECODE_NEVER;
02106 }
02107 }
02108 }
02109 }
02110
02111 template <class View, class Card, bool isView> template <BC direction>
02112 inline void
02113 VarValGraph<View, Card, isView>::dfs(VVGNode* v,
02114 bool inscc[],
02115 bool in_unfinished[],
02116 int dfsnum[],
02117 Support::StaticStack<VVGNode*,Region>& roots,
02118 Support::StaticStack<VVGNode*,Region>& unfinished,
02119 int& count){
02120 count++;
02121 int v_index = v->get_info();
02122 dfsnum[v_index] = count;
02123 inscc[v_index] = true;
02124 in_unfinished[v_index] = true;
02125
02126 unfinished.push(v);
02127 roots.push(v);
02128 for (Edge* e = v->first(); e != NULL; e = e->next(v->get_type())) {
02129 bool condition = false;
02130
02131 if (direction == LBC) {
02132
02133 if (v->get_type()) {
02134 condition = e->template matched<LBC>();
02135 } else {
02136 condition = !e->template matched<LBC>();
02137 }
02138
02139 } else {
02140 if (v->get_type()) {
02141
02142 condition = !e->template matched<UBC>();
02143 } else {
02144 condition = e->template matched<UBC>();
02145 }
02146 }
02147 if (condition) {
02148 VVGNode* w = e->getMate(v->get_type());
02149 int w_index = w->get_info();
02150
02151 assert(w_index < node_size);
02152 if (!inscc[w_index]) {
02153
02154 w->inedge(e);
02155 dfs<direction>(w, inscc, in_unfinished, dfsnum,
02156 roots, unfinished, count);
02157 } else {
02158 if (in_unfinished[w_index]) {
02159
02160
02161 e->template use<direction>();
02162
02163
02164 assert(roots.top()->get_info() < node_size);
02165 while (dfsnum[roots.top()->get_info()] > dfsnum[w_index]) {
02166 roots.pop();
02167 }
02168 }
02169 }
02170 }
02171 }
02172
02173 if (v == roots.top()) {
02174 while (v != unfinished.top()) {
02175
02176 VVGNode* w = unfinished.top();
02177 Edge* ie = w->inedge();
02178 ie->template use<direction>();
02179 in_unfinished[w->get_info()] = false;
02180 unfinished.pop();
02181 }
02182 assert(v == unfinished.top());
02183 in_unfinished[v_index] = false;
02184 roots.pop();
02185 unfinished.pop();
02186 }
02187 }
02188
02189 template <class View, class Card, bool isView> template <BC direction>
02190 inline void
02191 VarValGraph<View, Card, isView>::strongly_connected_components(Space& home) {
02192 Region r(home);
02193 bool* inscc = r.alloc<bool>(node_size);
02194 bool* in_unfinished = r.alloc<bool>(node_size);
02195 int* dfsnum = r.alloc<int>(node_size);
02196
02197 for (int i = node_size; i--; ) {
02198 inscc[i] = false;
02199 in_unfinished[i] = false;
02200 dfsnum[i] = 0;
02201 }
02202
02203 int count = 0;
02204 Support::StaticStack<VVGNode*,Region> roots(r,node_size);
02205 Support::StaticStack<VVGNode*,Region> unfinished(r,node_size);
02206
02207 for (int i = n_var; i--; )
02208 dfs<direction>(vars[i], inscc, in_unfinished, dfsnum,
02209 roots, unfinished, count);
02210 }
02211
02212 template <class View, class Card, bool isView>
02213 forceinline
02214 VarValGraph<View, Card, isView>::~VarValGraph(void){
02215 heap.rfree(mem);
02216 }
02217
02218 template <class View, class Card, bool isView>
02219 forceinline void*
02220 VarValGraph<View, Card, isView>::operator new(size_t t){
02221 return heap.ralloc(t);
02222 }
02223
02224 template <class View, class Card, bool isView>
02225 forceinline void
02226 VarValGraph<View, Card, isView>::operator delete(void* p){
02227 heap.rfree(p);
02228 }
02229
02230
02231 }}}
02232
02233
02234
02235