Generated on Mon Aug 25 11:35:37 2008 for Gecode by doxygen 1.5.6

graphsup.icc

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