Generated on Mon Jul 6 18:09:09 2009 for Gecode by doxygen 1.5.9

graphsup.hpp

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