Generated on Wed Nov 1 15:04:34 2006 for Gecode by doxygen 1.4.5

graphsup.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00004  *
00005  *  Copyright:
00006  *     Patrick Pekczynski, 2005
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 namespace Gecode { namespace Int { namespace GCC {
00023 
00030   enum BC {UBC = 1, LBC = 0};
00031 
00032   class Edge;
00034   class VVGNode{
00035   private:
00037     Edge* e;
00039     Edge* fst;
00041     Edge* lst;
00043     Edge* ie;
00045     bool  lm;
00047     bool  um;
00049     bool  type;
00050   public:
00052 
00053 
00054     VVGNode(void);
00056 
00057     virtual ~VVGNode(void){};
00059     void*  operator new(size_t, void*);
00060 
00062 
00063 
00064     Edge** adj(void);
00066     Edge*  first(void);
00068     Edge*  last(void);
00070     Edge*  inedge(void);
00072     bool   get_type(void);
00074     template <BC>
00075     bool   get_match_flag(void);
00077     virtual int  get_info(void) = 0;
00079     virtual bool is_matched(BC) = 0;
00080 
00082     virtual bool removed(void) = 0;
00084 
00086 
00087 
00088     void   first(Edge* p);
00090     void   last(Edge* p);
00092     void   inedge(Edge* p);
00094     void   set_type(bool t);
00096     template <BC>
00097     void   set_match_flag(bool f);
00099     virtual void set_info(int i) = 0;
00101   };
00102 
00104   class VarNode : public VVGNode{
00105   private:
00107     Edge* ubm;
00109     Edge* lbm;
00110 
00111   public:
00113     unsigned int var;
00115     unsigned int noe;
00116 
00118     unsigned int xindex;
00119 
00121 
00122 
00123     VarNode(int i, int oidx);
00125 
00127 
00128 
00129     template <BC>
00130     Edge* get_match(void);
00132     int   get_info(void);
00134     bool  is_matched(BC);
00136     template <BC>
00137     bool  matched(void);
00138 
00140     bool removed(void);
00142 
00144 
00145 
00146     void  set_info(int i);
00148     template <BC>
00149     void  set_match(Edge* m);
00151     template <BC>
00152     void  match(void);
00154     template <BC>
00155     void  unmatch(void);
00157   };
00158 
00160   class ValNode : public VVGNode{
00161   private:
00163     int _klb;
00165     int _kub;
00167     int _kidx;
00169     int _kcount;
00170 
00171 
00173     int noc;
00174 
00180     int lb;
00181     int ublow;
00188     int ub;
00189 
00190   public:
00192     int val;
00194     int idx;
00196     int noe;
00197 
00199 
00200 
00207     ValNode(int min, int max, int value, int kidx, int kshift, int count);
00209 
00211 
00212 
00214     void set_maxlow(int i);
00216     int  get_maxlow(void);
00217 
00218 
00220     void card_conflict(int c);
00222     int card_conflict(void);
00224     void red_conflict(void);
00225 
00227     bool removed(void);
00228 
00230     void inc(void);
00232     int kcount(void);
00234     template <BC>
00235     int incid_match(void);
00237     int kindex(void);
00239     int  get_info(void);
00241     template <BC>
00242     bool matched(void);
00244     bool sink(void);
00246     bool source(void);
00248     int  kmin(void);
00250     int  kmax(void);
00252     template <BC>
00253     int  kbound(void);
00254 
00256     bool is_matched(BC);
00258 
00260 
00261     void kcount(int);
00263     void kindex(int);
00265     template <BC>
00266     void dec(void);
00268     template <BC>
00269     void inc(void);
00271     template <BC>
00272     int  cap(void);
00274     template <BC>
00275     void set_cap(int c);
00277     template <BC>
00278     void match(void);
00280     template <BC>
00281     void unmatch(void);
00283     void reset(void);
00285     void set_info(int i);
00287     void set_kmin(int min);
00289     void set_kmax(int max);
00291   };
00292 
00294   class Edge{
00295   private:
00297     VarNode* x;
00299     ValNode* v;
00301     Edge* next_edge;
00303     Edge* prev_edge;
00305     Edge* next_vedge;
00307     Edge* prev_vedge;
00313     bool  mrklb;
00319     bool  mrkub;
00321     bool  um;
00323     bool  lm;
00325     bool  deleted;   // del
00326 
00327   public:
00329 
00330 
00334     Edge(VarNode* x, ValNode* v);
00336     void* operator new(size_t, void*);
00338 
00340 
00341 
00348     template <BC>
00349     bool used(void);
00351     template <BC>
00352     bool matched(void);
00354     bool is_deleted(void);
00360     Edge*    next(bool t) const;
00362     Edge*    next(void) const;
00364     Edge*    prev(void) const;
00366     Edge*    vnext(void) const;
00368     Edge*    vprev(void) const;
00370     VarNode* getVar(void);
00372     ValNode* getVal(void);
00377     VVGNode* getMate(bool t);
00379 
00381 
00382 
00383     template <BC>
00384     void use(void);
00386     template <BC>
00387     void free(void);
00393     template <BC>
00394     void reset(void);
00396     template <BC>
00397     void match(void);
00399     template <BC>
00400     void unmatch(void);
00402     template <BC>
00403     void unmatch(bool t);
00405     void unlink(void);
00407     void del_edge(void);
00409     void insert_edge(void);
00411     Edge**   next_ref(void);
00413     Edge**   prev_ref(void);
00415     Edge**   vnext_ref(void);
00417     Edge**   vprev_ref(void);
00419   };
00420 
00422   inline std::ostream&
00423   operator<<(std::ostream& os, VarNode* v) {
00424     os << v->var<<":{";
00425     for (Edge* e = v->first(); e != NULL; e = e->next()) {
00426       os << e->getVal()->val<<",";
00427     }
00428     os << "}(";
00429     os << v->xindex << ") ";
00430     return os;
00431   }
00432 
00434   inline std::ostream&
00435   operator<<(std::ostream& os, ValNode* v) {
00436     os << v->val<<":{";
00437     for (Edge* e = v->first(); e != NULL; e = e->vnext()) {
00438       os << e->getVar()->var<<",";
00439     }
00440     os << "} ";
00441     return os;
00442   }
00443 
00448   template <class View, class Card, bool isView>
00449   class VarValGraph{
00450   private:
00452     bool fail;
00454     char* mem;
00456     ViewArray<View>& x;
00458     ViewArray<View>& y;
00460     ViewArray<Card>& k;
00462     VarNode** vars;
00470     ValNode** vals;           // value partition    De
00472     Edge* edges;              // edges e
00474     int n_var;
00480     int n_val;
00482     int n_edge;
00484     int node_size;
00490     int sum_min;
00496     int sum_max;
00497   public:
00499 
00500     VarValGraph(ViewArray<View>&, ViewArray<View>&, ViewArray<Card>&,
00501                 int , int , int );
00503     ~VarValGraph(void);
00505 
00506 
00507 
00513     bool failed(void);
00517     void failed(bool b);
00518 
00523     bool min_require(Space* home);
00524 
00533     bool sync(void);
00534 
00536     void print_graph(void);
00538     template <BC>
00539     void print_matching(void);
00541     void print_match(void);
00542 
00544     void print_edges(void);
00545 
00547     void* operator new(size_t t);
00549     void operator delete(void* p);      
00550 
00558     template <BC>
00559     bool narrow(Space*);
00560 
00567     template <BC>
00568     bool maximum_matching(void);
00569 
00571     template <BC>
00572     void free_alternating_paths(void);
00574     template <BC>
00575     void strongly_connected_components(void);
00581     template <BC>
00582     bool augmenting_path(VVGNode*);
00583 
00584   protected:
00591     template <BC>
00592     void dfs(VVGNode*,
00593              bool[], bool[], int[],
00594              Support::StaticStack<VVGNode*>&,
00595              Support::StaticStack<VVGNode*>&,
00596              int&);
00597 
00599   };
00600 
00601   forceinline
00602   VVGNode::VVGNode(void){} //no-op
00603 
00604   forceinline void*
00605   VVGNode::operator new(size_t n, void* p){
00606     return p;
00607   }
00608 
00609   forceinline Edge**
00610   VVGNode::adj(void){
00611     return &e;
00612   }
00613 
00614   forceinline  Edge*
00615   VVGNode::first(void){
00616     return fst;
00617   }
00618 
00619   forceinline Edge*
00620   VVGNode::last(void){
00621     return lst;
00622   }
00623 
00624   forceinline void
00625   VVGNode::first(Edge* p){
00626     fst = p;
00627   }
00628 
00629   forceinline void
00630   VVGNode::last(Edge* p){
00631     lst = p;
00632   }
00633 
00634   forceinline bool
00635   VVGNode::get_type(void){
00636     return type;
00637   }
00638 
00639   forceinline void
00640   VVGNode::set_type(bool b){
00641     type = b;
00642   }
00643 
00644   forceinline Edge*
00645   VVGNode::inedge(void){
00646     return ie;
00647   }
00648 
00649   forceinline void
00650   VVGNode::inedge(Edge* p){
00651     ie = p;
00652   }
00653 
00654   template <BC direction>
00655   forceinline void
00656   VVGNode::set_match_flag(bool b){
00657     if (direction == UBC) {
00658       um = b;
00659     } else {
00660       lm = b;
00661     }
00662   }
00663 
00664   template <BC direction>
00665   forceinline bool
00666   VVGNode::get_match_flag(void){
00667     if (direction == UBC) {
00668       return um;
00669     } else {
00670       return lm;
00671     }
00672   }
00673 
00674 
00676 
00677   forceinline bool
00678   VarNode::removed(void) {
00679     return noe == 0;
00680   }
00681 
00682 
00683 
00684   forceinline
00685   VarNode::VarNode(int x, int orig_idx) :
00686     ubm(NULL), lbm(NULL), var(x), noe(0), xindex(orig_idx){
00687     first(NULL);
00688     last(NULL);
00689     inedge(NULL);
00690     unmatch<LBC>();
00691     unmatch<UBC>();
00692     set_type(false);
00693   }
00694 
00695   forceinline bool
00696   VarNode::is_matched(BC d) {
00697     if (d == UBC) {
00698       return matched<UBC>();
00699     } else {
00700       return matched<LBC>();
00701     }
00702   }
00703 
00704   template <BC direction>
00705   forceinline bool
00706   VarNode::matched(void){
00707     return get_match_flag<direction>();
00708   }
00709 
00710   template <BC direction>
00711   forceinline void
00712   VarNode::match(void){
00713     set_match_flag<direction>(true);
00714   }
00715 
00716   template <BC direction>
00717   forceinline void
00718   VarNode::unmatch(void){
00719     set_match_flag<direction>(false);
00720     set_match<direction>(NULL);
00721   }
00722 
00723   template <BC direction>
00724   forceinline void
00725   VarNode::set_match(Edge* p){
00726     if (direction == UBC) {
00727       ubm = p;
00728     } else {
00729       lbm = p;
00730     }
00731   }
00732 
00733   template <BC direction>
00734   forceinline Edge*
00735   VarNode::get_match(void){
00736     if (direction == UBC) {
00737       return ubm;
00738     } else {
00739       return lbm;
00740     }
00741   }
00742 
00743   forceinline void
00744   VarNode::set_info(int i){
00745     var = i;
00746   }
00747 
00748   forceinline int
00749   VarNode::get_info(void){
00750     return var;
00751   }
00752 
00754 
00755   forceinline void
00756   ValNode::set_maxlow(int i){
00757     assert(i >= lb);
00758     ublow = i;
00759   }
00760 
00761   forceinline int
00762   ValNode::get_maxlow(void) {
00763     if (_klb == _kub) {
00764       assert(ublow == lb);
00765     }
00766 
00767     return ublow;
00768   }
00769 
00770 
00771   forceinline void
00772   ValNode::card_conflict(int c){
00773     noc = c;
00774   }
00775 
00776   forceinline void
00777   ValNode::red_conflict(void){
00778     noc--;
00779     assert(noc >= 0);
00780   }
00781 
00782   forceinline int
00783   ValNode::card_conflict(void){
00784     return noc;
00785   }
00786 
00787   forceinline bool
00788   ValNode::removed(void) {
00789     return noe == 0;
00790   }
00791 
00792   forceinline bool
00793   ValNode::is_matched(BC d) {
00794     if (d == UBC) {
00795       return matched<UBC>();
00796     } else {
00797       return ublow == 0;
00798     }
00799   }
00800 
00801   forceinline void
00802   ValNode::reset(void){
00803     lb = _klb;
00804     ublow = _kub;
00805     ub = _kub;
00806     noe = 0;
00807   }
00808 
00809   template <BC direction>
00810   forceinline int
00811   ValNode::kbound(void){
00812     if (direction == UBC) {
00813       return _kub;
00814     } else {
00815       return _klb;
00816     }
00817   }
00818 
00819   forceinline int
00820   ValNode::kmax(void){
00821     return _kub;
00822   }
00823 
00824   forceinline int
00825   ValNode::kmin(void){
00826     return _klb;
00827   }
00828 
00829   forceinline void
00830   ValNode::set_kmin(int klb){
00831     _klb = klb;
00832   }
00833 
00834   forceinline void
00835   ValNode::set_kmax(int kub){
00836     _kub = kub;
00837   }
00838 
00839   template <BC direction>
00840   forceinline int
00841   ValNode::cap(void){
00842     if (direction == UBC) {
00843       return ub;
00844     } else {
00845       return lb;
00846     }
00847   }
00848 
00849   template <BC direction>
00850   forceinline void
00851   ValNode::dec(void){
00852     if (direction == UBC) {
00853       ub--;
00854     } else {
00855       lb--;
00856       ublow--;
00857     }
00858   }
00859 
00860   template <BC direction>
00861   forceinline void
00862   ValNode::inc(void){
00863     if (direction == UBC) {
00864       ub++;
00865     } else {
00866       lb++;
00867       ublow++;
00868     }
00869   }
00870 
00871   template <BC direction>
00872   forceinline void
00873   ValNode::match(void){
00874     dec<direction>();
00875   }
00876 
00877   template <BC direction>
00878   forceinline void
00879   ValNode::unmatch(void){
00880     inc<direction>();
00881   }
00882 
00883   template <BC direction>
00884   forceinline bool
00885   ValNode::matched(void){
00886     return ( cap<direction>() == 0);
00887   }
00888 
00889   forceinline
00890   ValNode::ValNode(int min, int max, int value,
00891                    int kidx, int kshift, int count) :
00892     _klb(min), _kub(max), _kidx(kidx), _kcount(count),
00893     noc(0),
00894     lb(min), ublow(max), ub(max),
00895     val(value), idx(kshift), noe(0) {
00896     first(NULL);
00897     last(NULL);
00898     inedge(NULL);
00899     Edge** vadjacent = adj();
00900     *vadjacent = NULL;
00901     set_type(true);
00902   }
00903 
00904   template<BC direction>
00905   forceinline void
00906   ValNode::set_cap(int c){
00907     if (direction == UBC) {
00908       ub = c;
00909     } else {
00910       lb = c;
00911 //       ublow = c;
00912     }
00913   }
00914 
00915   forceinline void
00916   ValNode::set_info(int i){
00917     idx = i;
00918   }
00919 
00920   forceinline int
00921   ValNode::get_info(void){
00922     return idx;
00923   }
00924 
00925   forceinline void
00926   ValNode::inc(void) {
00927     _kcount++;
00928   }
00929 
00930   forceinline int
00931   ValNode::kcount(void) {
00932     return _kcount;
00933   }
00934 
00935   forceinline void
00936   ValNode::kcount(int c) {
00937     _kcount = c;
00938   }
00939 
00940   forceinline void
00941   ValNode::kindex(int i){
00942     _kidx = i;
00943   }
00944 
00945   forceinline int
00946   ValNode::kindex(void){
00947     return _kidx;
00948   }
00949 
00951   template <BC direction>
00952   forceinline int
00953   ValNode::incid_match(void){
00954     if (direction == LBC) {
00955       // std::cout << "LBC: "<< _kub <<"-"<<ublow <<"+"<<_kcount<<"\n";
00956       return _kub - ublow + _kcount;
00957     } else {
00958       // std::cout << "UBC: "<< _kub <<"-"<<ub <<"+"<<_kcount<<"\n";
00959       return _kub - ub + _kcount;
00960     }
00961   }
00962 
00963 
00964   forceinline bool
00965   ValNode::sink(void){
00966     // there are only incoming edges
00967     // in case of the UBC-matching
00968     bool is_sink = false;
00969     is_sink = (_kub - ub == noe);
00970     return is_sink;
00971   }
00972 
00973   forceinline bool
00974   ValNode::source(void){
00975     // there are only incoming edges
00976     // in case of the UBC-matching
00977     bool is_sink = false;
00978     is_sink = (_klb - lb == noe);
00979     return is_sink;
00980   }
00981 
00984   inline std::ostream&
00985   operator<<(std::ostream& os, Edge* e){
00986     if (e== NULL) {
00987       os << "(N)";
00988     } else {
00989       os << "e("<<e->getVar()->var<<","<<e->getVal()->val<<")";
00990     }
00991     return os;
00992   }
00993 
00994 
00995   forceinline void
00996   Edge::unlink(void){
00997     // unlink from variable side
00998     Edge* p = prev_edge;
00999     Edge* n = next_edge;
01000 
01001     if (p != NULL) {
01002       Edge** pnext = p->next_ref();
01003       *pnext = n;
01004     }
01005 
01006     if (n != NULL) {
01007       Edge** nprev = n->prev_ref();
01008       *nprev = p;
01009     }
01010 
01011     if (this == x->first()) {
01012       Edge** ref = x->adj();
01013       *ref = n;
01014       x->first(n);
01015     }
01016 
01017     if (this == x->last()) {
01018       x->last(p);
01019     }
01020 
01021     // unlink from value side
01022     Edge* pv = prev_vedge;
01023     Edge* nv = next_vedge;
01024 
01025     if (pv != NULL) {
01026       Edge** pvnext = pv->vnext_ref();
01027       *pvnext = nv;
01028     }
01029 
01030     if (nv != NULL) {
01031       Edge** nvprev = nv->vprev_ref();
01032       *nvprev = pv;
01033     }
01034 
01035     if (this == v->first()) {
01036       Edge** ref = v->adj();
01037       *ref = nv;
01038       v->first(nv);
01039     }
01040 
01041     if (this == v->last()) {
01042       v->last(pv);
01043     }
01044   }
01045 
01046   forceinline
01047   Edge::Edge(VarNode* var, ValNode* val) :
01048     x(var), v(val),
01049     next_edge(NULL), prev_edge(NULL),
01050     next_vedge(NULL), prev_vedge(NULL),
01051     mrklb(false), mrkub(false),
01052     um(false), lm(false), deleted(false) {};
01053 
01054   forceinline void*
01055   Edge::operator new(size_t, void* p){ //why is there no argument?
01056     return p;
01057   }
01058 
01059   template <BC direction>
01060   forceinline void
01061   Edge::use(void){
01062     if (direction == UBC) {
01063       mrkub = true;
01064     } else {
01065       mrklb = true;
01066     }
01067   }
01068 
01069   template <BC direction>
01070   forceinline void
01071   Edge::free(void){
01073     if (direction == UBC) {
01074       mrkub = false;
01075     } else {
01076       mrklb = false;
01077     }
01078   }
01079 
01080   template <BC direction>
01081   forceinline void
01082   Edge::reset(void){
01083     this->free<direction>();
01084     this->unmatch<direction>();
01085   }
01086 
01087   template <BC direction>
01088   forceinline bool
01089   Edge::used(void){
01090     if (direction == UBC){
01091       return mrkub;
01092     } else {
01093       return mrklb;
01094     }
01095   }
01096 
01097   forceinline Edge*
01098   Edge::next(void) const{
01099     return next_edge;
01100   }
01101 
01102   forceinline Edge*
01103   Edge::next(bool t) const{
01104     if (t) {
01105       return next_vedge;
01106     } else {
01107       return next_edge;
01108     }
01109   }
01110 
01111   forceinline Edge*
01112   Edge::vnext(void) const{
01113     return next_vedge;
01114   }
01115 
01116   forceinline Edge**
01117   Edge::vnext_ref(void) {
01118     return &next_vedge;
01119   }
01120 
01121   forceinline Edge*
01122   Edge::prev(void) const{
01123     return prev_edge;
01124   }
01125 
01126   forceinline Edge**
01127   Edge::prev_ref(void) {
01128     return &prev_edge;
01129   }
01130 
01131   forceinline Edge*
01132   Edge::vprev(void) const{
01133     return prev_vedge;
01134   }
01135 
01136   forceinline Edge**
01137   Edge::vprev_ref(void) {
01138     return &prev_vedge;
01139   }
01140 
01141   forceinline Edge**
01142   Edge::next_ref(void){
01143     return &next_edge;
01144   }
01145   forceinline VarNode*
01146   Edge::getVar(void){
01147     assert(x != NULL);
01148     return x;
01149   }
01150 
01151   forceinline ValNode*
01152   Edge::getVal(void){
01153     assert(v != NULL);
01154     return v;
01155   }
01156 
01157   forceinline VVGNode*
01158   Edge::getMate(bool type){
01159     if (type) {
01160       return x;
01161     } else {
01162       return v;
01163     }
01164   }
01165 
01166   template <BC direction>
01167   forceinline void
01168   Edge::unmatch(void){
01169     if (direction == UBC) {
01170       um = false;
01171     } else {
01172       lm = false;
01173     }
01174     x->unmatch<direction>();
01175     v->unmatch<direction>();
01176   }
01177 
01178   template <BC direction>
01179   forceinline void
01180   Edge::unmatch(bool node){
01181     if (direction == UBC) {
01182       um = false;
01183     } else {
01184       lm = false;
01185     }
01186     if (node) {
01187       v->template unmatch<direction>();
01188     } else {
01189       x->template unmatch<direction>();
01190     }
01191   }
01192 
01193   template <BC direction>
01194   forceinline void
01195   Edge::match(void){
01196     if (direction == UBC) {
01197       um = true;
01198       x->template match<direction>();
01199       x->template set_match<direction>(this);
01200       v->template match<direction>();
01201     } else {
01202       lm = true;
01203       x->template match<direction>();
01204       x->template set_match<direction>(this);
01205       assert(x->template matched<direction>());
01206       v->template match<direction>();
01207 //       assert(v->template matched<direction>());
01208     }
01209   }
01210 
01211   template <BC direction>
01212   forceinline bool
01213   Edge::matched(void){
01214     if (direction == UBC) {
01215       return um;
01216     } else {
01217       return lm;
01218     }
01219   }
01220 
01221   forceinline void
01222   Edge::del_edge(void){
01223     deleted = true;
01224   }
01225 
01226   forceinline void
01227   Edge::insert_edge(void){
01228     deleted = false;
01229   }
01230 
01231 
01232   forceinline bool
01233   Edge::is_deleted(void){
01234     return deleted;
01235   }
01236 
01250   template <class View, class Card, bool isView>
01251   VarValGraph<View, Card, isView>::VarValGraph(ViewArray<View>& xref,
01252                                                ViewArray<View>& yref,
01253                                                ViewArray<Card>& kref,
01254                                                int noe,
01255                                                int smin, int smax)
01256     : fail(false),
01257       x(xref),
01258       y(yref),
01259       k(kref),
01260       n_var(x.size()),
01261       n_val(k.size()),
01262       n_edge(noe),
01263       node_size(n_var + n_val),
01264       sum_min(smin),
01265       sum_max(smax) {
01266 
01267     //memory allocation
01268     size_t  edge_size      = sizeof(Edge)     * n_edge;
01269     size_t  var_size       = sizeof(VarNode)  * n_var;
01270     size_t  var_ptr_size   = sizeof(VarNode*) * n_var;
01271     size_t  val_size       = sizeof(ValNode)  * n_val;
01272     size_t  val_ptr_size   = sizeof(ValNode*) * n_val;
01273     size_t  size           = edge_size + var_size + var_ptr_size +
01274       val_size + val_ptr_size;
01275 
01276     mem      = reinterpret_cast<char*>
01277       (Memory::malloc(size));
01278     edges    = reinterpret_cast<Edge*>
01279       (mem);
01280     VarNode* vars_ptr = reinterpret_cast<VarNode*>
01281       (mem + edge_size);
01282     ValNode* vals_ptr = reinterpret_cast<ValNode*>
01283       (mem + edge_size + var_size);
01284     vars     = reinterpret_cast<VarNode**>
01285       (mem + edge_size + var_size + val_size);
01286     vals     = reinterpret_cast<ValNode**>
01287       (mem + edge_size + var_size + val_size + var_ptr_size);
01288 
01289     for (int i = n_val; i--; ){
01290       int kmi = k[i].min();
01291       int kma = k[i].max();
01292       int kc  = k[i].counter();
01293       if (kc != kma) {
01294         if (kmi >= kc) {
01295           kmi -=kc;
01296           assert(kmi >=0);
01297         } else {
01298           kmi = 0;
01299         }
01300         kma -= kc;
01301         assert (kma > 0);
01302         vals[i] = new (vals_ptr + i)
01303           ValNode(kmi, kma, k[i].card(), i, i + n_var, kc);
01304       } else {
01305         vals[i] = new (vals_ptr + i)
01306           ValNode(0, 0, k[i].card(), i, i + n_var, kc);
01307       }
01308     }
01309 
01310     for (int i = n_var; i--; ){
01311 
01312       vars[i]          = new (vars_ptr + i) VarNode(i, i);
01313       VarNode* vrn     = vars[i];
01314       // get the space for the edges of the varnode
01315       Edge** xadjacent = vrn->adj();
01316 
01317       ViewValues<View> xiter(x[i]);
01318       int j = 0;
01319       for (; xiter(); ++xiter){
01320         int v = xiter.val();
01321         // get the correct index for the value
01322         while(vals[j]->val < v){        
01323           j++;
01324         }
01325         ValNode* vln = vals[j];
01326         *xadjacent = new (edges) Edge(vars_ptr + i, vals_ptr + j);
01327         vrn->noe++;
01328         if (vrn->first() == NULL) {
01329           vrn->first(*xadjacent);
01330         }
01331         Edge* oldprev  = vrn->last();
01332         vrn->last(*xadjacent);
01333         Edge** newprev = vrn->last()->prev_ref();
01334         *newprev       = oldprev;
01335         
01336         if (vln->first() == NULL) {
01337           vln->first(*xadjacent);
01338           vln->last(*xadjacent);
01339           vln->noe++;
01340         } else {
01341           Edge* old      = vln->first();
01342           vln->first(*xadjacent);
01343           Edge** newnext = vln->first()->vnext_ref();
01344           *newnext       = old;
01345           Edge** setprev = old->vprev_ref();
01346           *setprev       = vln->first();
01347           vln->noe++;
01348         }
01349         edges++;
01350         xadjacent = (*xadjacent)->next_ref();
01351       }         
01352       *xadjacent = NULL;
01353     }
01354   }
01355 
01356   template <class View, class Card, bool isView>
01357   forceinline bool
01358   VarValGraph<View, Card, isView>::failed(void){
01359     return fail;
01360   }
01361 
01362   template <class View, class Card, bool isView>
01363   forceinline void
01364   VarValGraph<View, Card, isView>::failed(bool b){
01365     fail = b;
01366   }
01367 
01368 
01369 
01370   template <class View, class Card, bool isView>
01371   inline bool
01372   VarValGraph<View, Card, isView>::min_require(Space* home){
01373     bool modified = false;
01374     for (int i = n_val; i--; ) {
01375       ValNode* vln = vals[i];
01376       if (vln->noe > 0) {
01377         if (k[i].min() == vln->noe) {
01378           // all variable nodes reachable from vln should be equal to vln->val
01379           for (Edge* e = vln->first(); e != NULL; e = e->vnext()) {
01380             VarNode* vrn = e->getVar();
01381             int vi = vrn->get_info();
01382             for (Edge* f = vrn->first(); f != NULL; f = f->next()) {
01383               if (f != e) {
01384                 ValNode* w = f->getVal();
01385                 w->noe--;
01386                 vrn->noe--;
01387                 f->del_edge();
01388                 f->unlink();
01389               }
01390             }
01391             assert(vrn->noe == 1);
01392             modified |= x[vi].modified();
01393 
01394             x[vi].eq(home, vln->val);
01395             vars[vi] = vars[--n_var];
01396             vars[vi]->set_info(vi);
01397 
01398             int n = x.size();
01399             x[vi] = x[--n];
01400             //      x[vi].index(vi);
01401             x.size(n);
01402 
01403             node_size--;
01404             vln->noe--;
01405           }
01406         
01407 
01408           int vidx = vln->kindex();
01409           if (isView)
01410             k[vidx].eq(home, k[vidx].min());
01411 
01412           k[vidx].counter(k[vidx].min());
01413           modified |= k[vidx].modified();
01414         
01415           vln->template set_cap<UBC>(0);
01416           vln->template set_cap<LBC>(0);
01417           vln->set_maxlow(0);
01418 
01419           if (sum_min && sum_min >= k[vidx].min()) {
01420             sum_min -= k[vidx].min();
01421           }
01422           assert(sum_min >=0);
01423 
01424           if (sum_max && sum_max >= k[vidx].max()) {
01425             sum_max -= k[vidx].max();
01426           }
01427           assert(sum_max >=0);
01428         }
01429       } else {
01430         vals[i]->template set_cap<UBC>(0);
01431         vals[i]->template set_cap<LBC>(0);
01432         vals[i]->set_maxlow(0);
01433         vals[i]->set_kmax(0);
01434         vals[i]->set_kmin(0);
01435 
01436       }
01437 
01438       if (isView) {
01439         if (k[i].counter() == 0) {
01440           ModEvent klq = k[i].lq(home, vals[i]->noe);
01441           if (me_failed(klq)) {
01442             failed(true);
01443           }
01444         }
01445         modified |= k[i].modified() && k[i].max() != vals[i]->noe;
01446       }
01447     }
01448 
01449     for (int i = n_val; i--; ) {
01450       vals[i]->set_info(n_var + i);
01451     }
01452 
01453     return modified;
01454   }
01455 
01456   template <class View, class Card, bool isView>
01457   inline bool
01458   VarValGraph<View, Card, isView>::sync(void){
01459     GECODE_AUTOARRAY(VVGNode*, re, node_size);
01460     int n_re = 0;
01461 
01462     // synchronize cardinality variables
01463     if (isView) {
01464       for (int i = n_val; i--; ) {
01465         ValNode* v  = vals[i];
01466         int inc_ubc = v->template incid_match<UBC>();
01467         int inc_lbc = v->template incid_match<LBC>();
01468         if (v->noe == 0) {
01469           inc_ubc = 0;
01470           inc_lbc = 0;
01471         }
01472         int rm = v->kmax() - k[i].max();
01473         // the cardinality bounds have been modified
01474         if (k[i].max() < v->kmax() || k[i].min() > v->kmin()) {
01475           if (k[i].max() != k[i].counter() || k[i].max() == 0) {
01476             // update the bounds
01477             v->set_kmax(k[i].max());
01478             v->set_kmin(k[i].min());
01479 
01480             //everything is fine
01481             if (inc_ubc <= k[i].max()) {
01482               // adjust capacities
01483               v->template set_cap<UBC>(k[i].max() - (inc_ubc));
01484               v->set_maxlow(k[i].max() - (inc_lbc));
01485               if (v->kmin() == v->kmax()) {
01486                 v->template set_cap<LBC>(k[i].max() - (inc_lbc));
01487               }
01488             } else {
01489               // set cap to max and resolve conflicts on view side
01490               // set to full capacity for later rescheduling
01491               if (v->template cap<UBC>()) {
01492                 v->template set_cap<UBC>(k[i].max());
01493               }
01494               v->set_maxlow(k[i].max() - (inc_lbc));
01495               if (v->kmin() == v->kmax()) {
01496                 v->template set_cap<LBC>(k[i].max() - (inc_lbc));
01497               }
01498               v->card_conflict(rm);
01499             }
01500           }
01501         }
01502         if (inc_lbc < k[i].min() && v->noe > 0) {
01503         
01504           v->template set_cap<LBC>(k[i].min() - inc_lbc);
01505           re[n_re] = v;
01506           n_re++;
01507         }
01508       }
01509 
01510       for (int i = n_var; i--; ) {
01511         Edge* mub = vars[i]->template get_match<UBC>();
01512         if (mub != NULL) {
01513           ValNode* vu = mub->getVal();
01514           if (! (vars[i]->noe == 1) ) {
01515             if (vu->card_conflict()) {
01516               vu->red_conflict();
01517               mub->template unmatch<UBC>(vars[i]->get_type());
01518               re[n_re] = vars[i];
01519               n_re++;
01520             }
01521           }
01522         }
01523       }
01524     }
01525 
01526     // go on with synchronization
01527     assert(x.size() == n_var);
01528     for (int i = n_var; i--; ) {
01529 
01530       VarNode* vrn = vars[i];
01531       if(x[i].size() != vrn->noe){
01532         // if the variable is already assigned
01533         if (x[i].assigned()) {
01534           int  v = x[i].val();
01535           ValNode* rv = NULL;
01536           int rv_idx  = 0;
01537           Edge* mub = vrn->template get_match<UBC>();
01538           if (mub != NULL) {
01539             if (v != mub->getVal()->val) {
01540               mub->template unmatch<UBC>();
01541               re[n_re] = vars[i];
01542               n_re++;
01543             }
01544           }
01545 
01546           Edge* mlb = vrn->template get_match<LBC>();
01547           if (mlb != NULL) {
01548             ValNode* vln = mlb->getVal();
01549             if (v != vln->val) {
01550               mlb->template unmatch<LBC>();
01551               int nom = vln->template incid_match<LBC>();
01552               // less values than required
01553               bool cond = nom < vln->kmin();
01554               if (cond) {
01555                 re[n_re] = vln;
01556                 n_re++;         
01557               }
01558             }
01559           }
01560         
01561           for (Edge* e = vrn->first(); e != NULL; e = e->next()){
01562             ValNode* vln = e->getVal();
01563             if (vln->val != v) {
01564               vrn->noe--;
01565               e->getVal()->noe--;
01566               e->del_edge();
01567               e->unlink();
01568             } else {
01569               rv = e->getVal();
01570               rv_idx = rv->kindex();
01571             }
01572           }
01573         } else {
01574         
01575           // delete the edge
01576           ViewValues<View> xiter(x[i]);
01577           Edge*  mub = vrn->template get_match<UBC>();
01578           Edge*  mlb = vrn->template get_match<LBC>();
01579           Edge** p   = vrn->adj();
01580           Edge*  e   = *p;
01581           do {
01582             // search the edge that has to be deleted
01583             while (e != NULL && e->getVal()->val < xiter.val()) {
01584               // Skip edge
01585               e->getVal()->noe--;
01586               vrn->noe--;
01587               e->del_edge();
01588               e->unlink();
01589               e = e ->next();
01590               *p = e;
01591             }
01592 
01593             assert(xiter.val() == e->getVal()->val);
01594 
01595             // This edge must be kept
01596             e->template free<UBC>();
01597             e->template free<LBC>();
01598             ++xiter;
01599             p = e->next_ref();
01600             e = e->next();
01601           } while (xiter());
01602           *p = NULL;
01603           while (e) {
01604             e->getVar()->noe--;
01605             e->getVal()->noe--;
01606             e->del_edge();
01607             e->unlink();        
01608             e = e->next();
01609           }
01610 
01611           if (mub != NULL){
01612             if (mub->is_deleted()) {
01613               mub->template unmatch<UBC>();
01614               re[n_re] = vars[i];
01615               n_re++;
01616             }
01617           }
01618 
01619           //lower bound matching can be zero
01620           if (mlb != NULL) {
01621             if (mlb->is_deleted()) {
01622               ValNode* vln = mlb->getVal();
01623               mlb->template unmatch<LBC>();
01624               int nom   = vln->template incid_match<LBC>();
01625               bool cond = nom < vln->kmin();
01626               if (cond) {
01627                 re[n_re] = vln;
01628                 n_re++;
01629               }
01630             }
01631           }
01632         }
01633       }
01634       vars[i]->set_info(i);
01635     }
01636 
01637     for (int i = n_val; i--; ) {
01638       if (k[i].min() > vals[i]->noe && k[i].counter() == 0) {
01639         failed(true);
01640         return false;
01641       }
01642       vals[i]->set_info(n_var + i);
01643     }
01644 
01645     if (n_re == 0) {
01646       // no repair needed
01647       return true;
01648     } else {
01649       // start repair
01650 
01651       bool repaired = true;
01652       while (n_re ) {
01653         n_re--;
01654         assert(re[n_re] != NULL);
01655         if (!(re[n_re]->removed())) {
01656           if (!(re[n_re]->get_type())) {
01657             VarNode* vrn = reinterpret_cast<VarNode*> (re[n_re]);
01658             if (!vrn->template matched<UBC>()) {
01659               repaired &= augmenting_path<UBC>(vrn);
01660             }
01661           } else {
01662             assert(re[n_re]->get_type());
01663             ValNode* vln = reinterpret_cast<ValNode*> (re[n_re]);
01664             while(!vln->template matched<LBC>()) {
01665               repaired &= augmenting_path<LBC>(vln);
01666               if (!repaired) {
01667                 break;
01668               }
01669             }
01670           }
01671         }
01672       }
01673       return repaired;
01674     }
01675   }
01676 
01677   template <class View, class Card, bool isView> template <BC direction>
01678   inline bool
01679   VarValGraph<View, Card, isView>::narrow(Space* home){
01680 
01681     bool shared  = false;
01682     for (int i = n_var; i--; ) {
01683       VarNode* vrn = vars[i];
01684       if (vrn->noe == 1) {
01685         Edge* e = vrn->first();
01686         shared |= x[i].modified();
01687         ValNode* v = e->getVal();
01688         e->template free<direction>();  
01689         x[i].eq(home, v->val);
01690         v->inc();
01691       }
01692     }
01693     for (int i = n_val; i--; ) {
01694       ValNode* v = vals[i];
01695       if (isView) {
01696         if (k[i].counter() == 0) {
01697           ModEvent klq = k[i].lq(home, v->noe);
01698           if (me_failed(klq)) {
01699             failed(true);
01700             return false;
01701           }
01702         }
01703       }
01704 
01705       if (v->noe > 0) {
01706 
01707         if (isView) {
01708           ModEvent klq = k[i].lq(home, v->noe);
01709           if (me_failed(klq)) {
01710             failed(true);
01711             return false;
01712           }
01713         }
01714         
01715         // If the maximum number of occurences of a value is reached
01716         // it cannot be consumed by another view
01717         
01718         if (v->kcount() == v->kmax()) {
01719           int vidx = v->kindex();
01720 
01721           k[i].counter(v->kcount());
01722                   // std::cout << "eq on : " << v->val<<"\n";
01723           if (isView) {
01724             if (!k[i].assigned()) {
01725               ModEvent me = k[i].eq(home, k[i].counter());
01726               if (me_failed(me)) {
01727                 failed(true);
01728                 return false;
01729               }
01730             }
01731           }
01732 
01733           bool delall = false;
01734           if (v->card_conflict() &&
01735               v->noe > v->kmax()) {
01736             delall = true;
01737 
01738           }
01739         
01740           for (Edge* e = v->last(); e != NULL; e = e->vprev()) {
01741             VarNode* vrn = e->getVar();
01742             if (vrn->noe == 1) {
01743               vrn->noe--;
01744               v->noe--;
01745               int vi= vrn->get_info();
01746 
01747               int n = x.size();
01748               x[vi] = x[--n];
01749               //              x[vi].index(vi);
01750               x.size(n);
01751 
01752               vars[vi] = vars[--n_var];
01753               vars[vi]->set_info(vi);
01754               node_size--;
01755               e->del_edge();
01756               e->unlink();
01757 
01758             } else {
01759               if (delall) {
01760                 x[vrn->get_info()].nq(home, v->val);
01761                 vrn->noe--;
01762                 v->noe--;
01763                 e->del_edge();
01764                 e->unlink();
01765               }
01766             }
01767           }
01768           v->template set_cap<UBC>(0);
01769           v->template set_cap<LBC>(0);
01770           v->set_maxlow(0);
01771           if (sum_min && sum_min >= k[vidx].min()) {
01772             sum_min -= k[vidx].min();
01773           }
01774           assert(sum_min >=0);
01775 
01776           if (sum_max && sum_max >= k[vidx].max()) {
01777             sum_max -= k[vidx].max();
01778           }
01779           assert(sum_max >=0);
01780 
01781         } else {
01782           int cur = v->kcount();
01783           if (cur > 0) {
01784             v->kcount(0);
01785           }
01786         }
01787       }
01788     }
01789     for (int i = n_var; i--; )
01790       vars[i]->set_info(i);
01791 
01792     for (int i = n_val; i--; ) {
01793       if (vals[i]->noe == 0) {
01794         vals[i]->template set_cap<UBC>(0);
01795         vals[i]->template set_cap<LBC>(0);
01796         vals[i]->set_maxlow(0);
01797       }
01798       vals[i]->set_info(n_var + i);
01799     }
01800 
01801     for (int i = n_var; i--; )
01802       if (vars[i]->noe > 1)
01803         for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
01804           bool keepedge = false;
01805           keepedge =  (e->template matched<direction>() ||
01806                        e->template used<direction>());
01807           if (!keepedge) {
01808             ValNode* v = e->getVal();
01809             shared |= x[i].modified();
01810             x[i].nq(home, v->val);
01811           } else {
01812             e->template free<direction>();      
01813           }
01814         }
01815     return shared;
01816   }
01817 
01818   template <class View, class Card, bool isView>  template <BC direction>
01819   inline bool
01820   VarValGraph<View, Card, isView>::maximum_matching(void){
01821 
01822     int required_size = 0;
01823     int card_match    = 0;
01824 
01825     if (direction == UBC) {
01826       required_size = n_var;
01827     } else {
01828       required_size = sum_min;
01829     }
01830 
01831     // find an intial matching in O(n*d)
01832     // greedy algorithm
01833 
01834     for (int i = n_val; i--; ){
01835       ValNode* vln = vals[i];
01836       for (Edge* e = vln->first(); e != NULL ; e = e->vnext()) {
01837         VarNode* vrn = e->getVar();
01838         if (!vrn->template matched<direction>() &&
01839             !vln->template matched<direction>()) {
01840           e->template match<direction>();
01841           card_match++;
01842         }
01843       }
01844     }
01845 
01846     if (card_match < required_size) {
01847       if (direction == LBC) {
01848         // collect free value nodes
01849         GECODE_AUTOARRAY(ValNode*, free, n_val);
01850         int f = 0;
01851         // find failed nodes
01852         for (int i = n_val; i--; ) {
01853           ValNode* vln = vals[i];
01854           if (!vln->template matched<direction>()) {
01855             free[f++] = vln;
01856           }
01857         }
01858 
01859         for (int i = 0; i < f; i++) {
01860           while(!free[i]->template matched<direction>()) {
01861             if (augmenting_path<direction>(free[i])) {
01862               card_match++;
01863             } else {
01864               break;
01865             }
01866           }
01867         }
01868       } else {
01869         GECODE_AUTOARRAY(VarNode*, free, n_var);
01870         int f = 0;
01871         // find failed nodes
01872         for (int i = n_var; i--; ) {
01873           VarNode* vrn = vars[i];
01874           if (!vrn->template matched<direction>()) {
01875             free[f++] = vrn;
01876           }
01877         }
01878         
01879         for (int i = 0; i < f; i++) {
01880           if (!free[i]->template matched<direction>()) {
01881             if (augmenting_path<direction>(free[i])) {
01882               card_match++;
01883             }
01884           }
01885         }
01886       }
01887     }
01888     return (card_match >= required_size);
01889   }
01890 
01891   template <class View, class Card, bool isView> template<BC direction>
01892   inline bool
01893   VarValGraph<View, Card, isView>::augmenting_path(VVGNode* v){
01894     Support::StaticStack<VVGNode*> ns(node_size);
01895     GECODE_AUTOARRAY(bool, visited, node_size);
01896     GECODE_AUTOARRAY(Edge*, start, node_size);
01897 
01898     // augmenting path starting in a free var node
01899     assert(!v->is_matched(direction));
01900 
01901     // keep track of the nodes that have already been visited
01902     VVGNode* sn = v;
01903 
01904     // mark the start partition
01905     bool sp = sn->get_type();
01906 
01907     // nodes in sp only follow free edges
01908     // nodes in V - sp only follow matched edges
01909 
01910     for (int i = node_size; i--; ){
01911       visited[i] = false;
01912     }
01913 
01914     for (int i = node_size; i--; ){
01915       if (i >= n_var) {
01916         vals[i - n_var]->inedge(NULL);
01917         start[i]   = vals[i - n_var]->first();
01918       } else {
01919         vars[i]->inedge(NULL);
01920         start[i]   = vars[i]->first();
01921       }
01922     }
01923 
01924     v->inedge(NULL);
01925     ns.push(v);
01926     visited[v->get_info()] = true;
01927     while (!ns.empty()) {
01928       VVGNode* v = ns.top();
01929       Edge* e = NULL;
01930       if (v->get_type() == sp) {
01931         // follow next free edge
01932         e = start[v->get_info()];       
01933         while (e != NULL && e->template matched<direction>()) {
01934           e = e->next(v->get_type());
01935         }
01936       } else {
01937         e = start[v->get_info()];       
01938         while (e != NULL && !e->template matched<direction>()) {
01939           e = e->next(v->get_type());
01940         }
01941         start[v->get_info()] = e;
01942       }
01943       if (e != NULL) {
01944         start[v->get_info()] = e->next(v->get_type());
01945         VVGNode* w = e->getMate(v->get_type());
01946         if (!visited[w->get_info()]) {
01947           // unexplored path
01948           if (!w->is_matched(direction) && w->get_type() != sp) {
01949             if (v->inedge() != NULL) {
01950               // augmenting path of length l > 1
01951               e->template match<direction>();
01952               break;
01953             } else {
01954               // augmenting path of length l = 1
01955               e->template match<direction>();
01956               ns.pop();
01957               return true;
01958             }
01959           } else {
01960             w->inedge(e);
01961             visited[w->get_info()] = true;
01962             // find matching edge m incident with w
01963             ns.push(w);
01964           }
01965         }
01966       } else {
01967         // tried all outgoing edges without finding an augmenting path
01968         ns.pop();
01969       }
01970     }
01971 
01972     bool pathfound = false;
01973     if (!ns.empty()) {
01974       pathfound = true;
01975     }
01976 
01977     while (!ns.empty()) {
01978       VVGNode* t = ns.top();
01979       if (t != sn) {
01980         Edge* in   = t->inedge();
01981         if (t->get_type() != sp) {
01982           assert(in != NULL);
01983           in->template match<direction>();
01984         } else {
01985           // avoid defects
01986           if (!sp) {
01987             in->template unmatch<direction>(!sp);
01988           } else {
01989             in->template unmatch<direction>();
01990           }
01991         }
01992         ns.pop();
01993       } else {
01994         ns.pop();
01995       }
01996     }
01997     return pathfound;
01998   }
01999 
02000   template <class View, class Card, bool isView> template<BC direction>
02001   inline void
02002   VarValGraph<View, Card, isView>::free_alternating_paths(void){
02003     Support::StaticStack<VVGNode*> ns(node_size);
02004     GECODE_AUTOARRAY(bool, visited, node_size);
02005     // keep track of the nodes that have already been visited
02006     for (int i = node_size; i--; ){
02007       visited[i] = false;
02008     }
02009 
02010     if (direction == LBC) {
02011       // after a maximum matching on the value nodes there still can be
02012       // free value nodes, hence we have to consider ALL nodes whether
02013       // they are the starting point of an even alternating path in G
02014       for (int i = n_var; i--; ){
02015         if(!vars[i]->is_matched(LBC)){
02016           // unmatched var-node
02017           ns.push(vars[i]);
02018           visited[vars[i]->get_info()] = true;
02019         }
02020       }
02021       for (int i = n_val; i--; ){
02022         if(!vals[i]->is_matched(LBC)){
02023           // unmatched val-node
02024           ns.push(vals[i]);
02025           visited[vals[i]->get_info()] = true;
02026         }
02027       }
02028 
02029     } else {
02030       // clearly, after a maximum matching on the x variables
02031       // corresponding to a set cover on x there are NO free var nodes
02032       //       std::cout << "alt_path for ubm: \n";
02033       // after  max_match_ub there can only be free val-nodes
02034       for (int i = n_val; i--; ){
02035         if(!vals[i]->is_matched(UBC)){
02036           // still capacities left
02037           ns.push(vals[i]);
02038           visited[vals[i]->get_info()] = true;
02039         }
02040       }
02041     }
02042 
02043     while(!ns.empty()){
02044       VVGNode* node = ns.top();
02045       ns.pop();
02046       if (node->get_type()) {
02047         // ValNode
02048         ValNode* vln  = reinterpret_cast<ValNode*> (node);
02049         for (Edge* cur = vln->first(); cur != NULL; cur = cur->vnext()){
02050           VarNode* mate = cur->getVar();
02051           bool follow = false;
02052           switch (direction) {
02053             // edges in M_l are directed from values to variables
02054           case LBC: {
02055             follow = cur->template matched<direction>();
02056             break;
02057           }
02058           case UBC: {
02059             follow = !cur->template matched<direction>();
02060             break;
02061           default: GECODE_NEVER;
02062           }
02063           }
02064           if (follow) {
02065             // mark the edge
02066             cur->template use<direction>();
02067             if (!visited[mate->get_info()]) {
02068               ns.push(mate);
02069               visited[mate->get_info()] = true;
02070             }
02071           }
02072         }
02073       } else {
02074         // VarNode
02075         VarNode* vrn = reinterpret_cast<VarNode*> (node);
02076         switch (direction) {
02077           // after LBC-matching we can follow every unmatched edge
02078         case LBC: {     
02079           for (Edge* cur = vrn->first(); cur != NULL; cur = cur->next()){
02080             ValNode* mate = cur->getVal();
02081             if (!cur->template matched<LBC>()) {
02082               cur->template use<LBC>();
02083               if (!visited[mate->get_info()]) {
02084                 ns.push(mate);
02085                 visited[mate->get_info()] = true;
02086               }
02087             }
02088           }
02089           break;
02090         }
02091           // after ub-matching we can only follow a matched edge
02092         case UBC: {
02093           Edge* cur = vrn->template get_match<UBC>();
02094           if (cur != NULL) {
02095             cur->template use<UBC>();
02096             ValNode* mate = cur->getVal();
02097             if (!visited[mate->get_info()]) {
02098               ns.push(mate);
02099               visited[mate->get_info()] = true;
02100             }
02101           }
02102           break;
02103         }
02104         default: GECODE_NEVER;
02105         }
02106       }
02107     }
02108   }
02109 
02110   template <class View, class Card, bool isView> template <BC direction>
02111   inline void
02112   VarValGraph<View, Card, isView>::dfs(VVGNode* v,
02113                                        bool inscc[],
02114                                        bool in_unfinished[],
02115                                        int dfsnum[],
02116                                        Support::StaticStack<VVGNode*>& roots,
02117                                        Support::StaticStack<VVGNode*>& unfinished,
02118                                        int& count){
02119     count++;
02120     int v_index            = v->get_info();
02121     dfsnum[v_index]        = count;
02122     inscc[v_index]         = true;
02123     in_unfinished[v_index] = true;
02124 
02125     unfinished.push(v);
02126     roots.push(v);
02127     for (Edge* e = v->first(); e != NULL; e = e->next(v->get_type())) {
02128       bool condition = false;
02129       // LBC-matching
02130       if (direction == LBC) {
02131         // ValNode
02132         if (v->get_type()) {
02133           condition = e->template matched<LBC>();
02134         } else {
02135           condition = !e->template matched<LBC>();
02136         }
02137         // UBC - matching
02138       } else {
02139         if (v->get_type()) {
02140           // in an upper bound matching a valnode only can follow unmatched edges
02141           condition = !e->template matched<UBC>();
02142         } else {
02143           condition = e->template matched<UBC>();
02144         }
02145       }
02146       if (condition) {
02147         VVGNode* w = e->getMate(v->get_type());
02148         int w_index = w->get_info();
02149 
02150         assert(w_index < node_size);
02151         if (!inscc[w_index]) {
02152           // w is an uncompleted scc
02153           w->inedge(e);
02154           dfs<direction>(w, inscc, in_unfinished, dfsnum,
02155                          roots, unfinished, count);
02156         } else {
02157           if (in_unfinished[w_index]) {
02158             // even alternating cycle found mark the edge closing the cycle,
02159             // completing the scc
02160             e->template use<direction>();
02161             // if w belongs to an scc we detected earlier
02162             // merge components
02163             assert(roots.top()->get_info() < node_size);
02164             while (dfsnum[roots.top()->get_info()] > dfsnum[w_index]) {
02165               roots.pop();
02166             }
02167           }
02168         }
02169       }
02170     }
02171 
02172     if (v == roots.top()) {
02173       while (v != unfinished.top()) {
02174         // w belongs to the scc with root v
02175         VVGNode* w = unfinished.top();
02176         Edge* ie = w->inedge();
02177         ie->template use<direction>();
02178         in_unfinished[w->get_info()] = false;
02179         unfinished.pop();
02180       }
02181       assert(v == unfinished.top());
02182       in_unfinished[v_index] = false;
02183       roots.pop();
02184       unfinished.pop();
02185     }
02186   }
02187 
02188   template <class View, class Card, bool isView> template <BC direction>
02189   inline void
02190   VarValGraph<View, Card, isView>::strongly_connected_components(void){
02191     GECODE_AUTOARRAY(bool, inscc, node_size);
02192     GECODE_AUTOARRAY(bool, in_unfinished,  node_size);
02193     GECODE_AUTOARRAY(int,  dfsnum, node_size);
02194 
02195     for (int i = node_size; i--; ) {
02196       inscc[i]         = false;
02197       in_unfinished[i] = false;
02198       dfsnum[i]        = 0;
02199     }
02200 
02201     int count = 0;
02202     Support::StaticStack<VVGNode*> roots(node_size);
02203     Support::StaticStack<VVGNode*> unfinished(node_size);
02204 
02205     for (int i = n_var; i--; ) {
02206       dfs<direction>(vars[i], inscc, in_unfinished, dfsnum,
02207                      roots, unfinished, count);
02208     }
02209   }
02210 
02211 
02212   template <class View, class Card, bool isView>
02213   void
02214   VarValGraph<View, Card, isView>::print_match(void) {
02215     print_matching<UBC>();
02216     print_matching<LBC>();
02217   }
02218 
02219 
02220   template <class View, class Card, bool isView>
02221   void
02222   VarValGraph<View, Card, isView>::print_edges(void) {
02223     for (int i = 0; i < n_var; i++) {
02224       std::cout << vars[i]->var<<": ";
02225       for (Edge* e = vars[i]->first(); e != NULL; e = e->next()) {
02226         bool ml = e->template matched<LBC>();
02227         bool ul = e->template used<LBC>();
02228         bool mu = e->template matched<UBC>();
02229         bool uu = e->template used<UBC>();
02230         bool condition = (ml || ul || mu || uu);
02231         if (ml) {
02232           std::cout << e->getVal()->val<<" mL, ";
02233         }
02234         if (ul) {
02235           std::cout << e->getVal()->val<<" uL, ";
02236         }
02237         if (mu) {
02238           std::cout << e->getVal()->val<<" mU, ";
02239         }
02240         if (uu) {
02241           std::cout << e->getVal()->val<<" uU, ";
02242         }
02243         if (!condition) {
02244           std::cout << e->getVal()->val<<" x ";
02245         }
02246       }
02247       std::cout <<"\n";
02248     }
02249     std::cout <<"\n";
02250   }
02251 
02252   // for debugging purposes
02253   template <class View, class Card, bool isView> template <BC direction>
02254   void
02255   VarValGraph<View, Card, isView>::print_matching(void) {
02256     if (direction == UBC) {
02257       std::cout << "UBM - check:\n";
02258     } else {
02259       std::cout << "LBM - check:\n";
02260     }
02261 
02262     for (int i = 0; i < n_var; i++ ){
02263       std::cout << vars[i]->var <<"  ";
02264       if (vars[i]->template matched<direction>()) {
02265         if (vars[i]->template get_match<direction>() == NULL) {
02266           std::cout << "N  ";
02267         } else {
02268           std::cout << vars[i]->template get_match<direction>() << " ";
02269           std::cout << vars[i]->template get_match<direction>()->getVal()->val << "  ";
02270         }
02271       }
02272       std::cout << " <==" << vars[i] <<"\n";
02273     }
02274     std::cout <<"\n";
02275 
02276     for (int i = 0; i < n_val; i++ ){
02277       if (vals[i]->template matched<direction>()) {
02278         std::cout << "X  ";
02279       } else {
02280         std::cout << "-  ";
02281       }
02282       std::cout << vals[i]->template cap<direction>()  << "  ";
02283       std::cout << vals[i]->get_maxlow()  << "  ";
02284       std::cout << vals[i]->val  << "  <==";
02285       for (Edge* e = vals[i]->first(); e != NULL; e = e->vnext()) {
02286         if (e->template matched<direction>()) {
02287           std::cout << e->getVar()->var << ",";
02288         }
02289       }
02290       std::cout <<"\n";
02291     }
02292     std::cout <<"\n";
02293   }
02294 
02295   template <class View, class Card, bool isView>
02296   void
02297   VarValGraph<View, Card, isView>::print_graph(void) {
02298     std::cout << "Graph-size = "<<node_size<<" ";
02299     std::cout << "sum_min ="<<sum_min << " & "
02300               << "sum_max ="<<sum_max << "\n";
02301     std::cout << "X-Partition: \n";
02302     for (int i = 0; i < n_var; i++) {
02303       VarNode* vrn = vars[i];
02304       std::cout << "X("<<vars[i]->get_info()<<") ";
02305       std::cout << "["<<vrn->xindex <<"]";
02306       std::cout << "|"<<vrn->noe <<"|";
02307       std::cout << "{";
02308       for (Edge* e = vrn->first(); e != NULL; e = e->next()){
02309         assert(e != NULL);
02310         assert(e->getVal() != NULL);
02311         std::cout << e->getVal()->val<<",";
02312       }
02313       std::cout <<"}\t";
02314       std::cout << "F"<<vrn->first() << ", L" << vrn->last() << " ";
02315       std::cout <<"\n";
02316     }
02317     std::cout <<"\n";
02318 
02319     std::cout << "V-Partition: \n";
02320     for (int i = 0; i < n_val; i++) {
02321       ValNode* vln = vals[i];
02322       std::cout << vln->val <<" ";
02323       std::cout << "V(" << i << ") ";
02324       std::cout << "k(" << vln->kmin() << "," <<vln->kmax() << ") ";
02325       std::cout << "c(" << vln->template cap<LBC>() << ","
02326                 << vln->template cap<UBC>() << ") ";
02327       std::cout << "ublow: "<<vln->get_maxlow() <<" ";
02328       std::cout << "|"<<vln->noe <<"|";
02329       std::cout << "{";
02330       if (vln->noe == 0 || vln->first() == NULL) {
02331         std::cout << "EMPTY";
02332       } else {
02333         for(Edge* c = vln->first(); c != NULL; c = c->vnext()){
02334           assert(c != NULL);
02335           assert(c->getVar() != NULL);
02336           std::cout << c->getVar()->var << ",";
02337         }
02338       }
02339       std::cout <<"}\t";
02340       std::cout <<"\t";
02341       if (vln->noe == 0 || vln->first() == NULL) {
02342         std::cout <<"no-ptr";
02343       } else {
02344         std::cout << "F"<<vln->first() << ", L" <<vln->last() << " ";
02345       }
02346       std::cout <<"\n";
02347     }
02348     std::cout <<"\n";
02349   }
02350 
02351 
02352   template <class View, class Card, bool isView>
02353   forceinline
02354   VarValGraph<View, Card, isView>::~VarValGraph(void){
02355     Memory::free(mem);
02356   }
02357 
02358   template <class View, class Card, bool isView>
02359   forceinline void*
02360   VarValGraph<View, Card, isView>::operator new(size_t t){
02361     return Memory::malloc(t);
02362   }
02363 
02364   template <class View, class Card, bool isView>
02365   forceinline void
02366   VarValGraph<View, Card, isView>::operator delete(void* p){
02367     Memory::free(p);
02368   }
02369 
02370 
02371 }}}
02372 
02373 // STATISTICS: int-prop
02374 
02375