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

narrowing.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00004  *
00005  *  Copyright:
00006  *     Patrick Pekczynski, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */     
00021 
00022 #include "gecode/support/static-stack.hh"
00023 
00024 namespace Gecode { namespace Int { namespace Sortedness {
00025 
00042   template<class View, class Tuple>
00043   forceinline void
00044   computesccs(Space* home,
00045               ViewArray<Tuple>& xz,
00046               ViewArray<View>& y,
00047               int phi[],
00048               SccComponent sinfo[],
00049               int scclist[]) {
00050 
00051     // number of sccs is bounded by xs (number of x-nodes)
00052     int xs = xz.size();
00053     Support::StaticStack<int> cs(xs);
00054 
00055     //select an y node from the graph
00056     for (int j = 0; j < xs; j++) {
00057       int yjmin      = y[j].min();    // the processed min
00058       while (!cs.empty() && xz[phi[sinfo[cs.top()].rightmost]][0].max() < yjmin) {
00059         // the topmost scc cannot "reach" y_j or a node to the right of it
00060         cs.pop();
00061       }
00062 
00063       // a component has the form C(y-Node, matching x-Node)
00064       // C is a minimal scc in the oriented intersection graph
00065       // we only store y_j-Node, since \phi(j) gives the matching X-node
00066       int i     = phi[j];
00067       int ximin = xz[i][0].min();
00068       while (!cs.empty() && ximin <= y[sinfo[cs.top()].rightmost].max()) {
00069         // y_j can "reach" cs.top() ,
00070         // i.e. component c can reach component cs.top()
00071         // merge c and cs.top() into new component
00072         int top = cs.top();
00073         // connecting
00074         sinfo[sinfo[j].leftmost].left        = top;
00075         sinfo[top].right                     = sinfo[j].leftmost;
00076         // moving leftmost
00077         sinfo[j].leftmost                    = sinfo[top].leftmost;
00078         // moving rightmost
00079         sinfo[sinfo[top].leftmost].rightmost = j;
00080         cs.pop();
00081       }
00082       cs.push(j);
00083     }
00084     cs.reset();
00085 
00086 
00087     // now we mark all components with the respective scc-number
00088     // labeling is bound by O(k) which is bound by O(n)
00089 
00090     for (int i = 0; i < xs; i++) {
00091       if (sinfo[i].left == i) { // only label variables in sccs
00092         int scc = sinfo[i].rightmost;
00093         int z   = i;
00094         //bound by the size of the largest scc = k
00095         while (sinfo[z].right != z) {
00096           sinfo[z].rightmost   = scc;
00097           scclist[phi[z]]      = scc;
00098           z                    = sinfo[z].right;
00099         }
00100         sinfo[z].rightmost     = scc;
00101         scclist[phi[z]]        = scc;
00102       }
00103     }
00104   }
00105 
00121   template<class View, class Tuple, bool Perm>
00122   forceinline bool
00123   narrow_domx(Space* home,
00124               ViewArray<Tuple>& xz,
00125               ViewArray<View>& y,
00126               int tau[],
00127               int phi[],
00128               int scclist[],
00129               SccComponent sinfo[],
00130               bool& nofix) {
00131 
00132     int xs        = xz.size();
00133 
00134     // For every x node
00135     for (int i = 0; i < xs; i++) {
00136 
00137       int xmin = xz[i][0].min();
00138       /*
00139        * take the scc-list for the current x node
00140        * start from the leftmost reachable y node of the scc
00141        * and check which Y node in the scc is
00142        * really the rightmost node intersecting x, i.e.
00143        * search for the greatest lower bound of x
00144        */
00145       int start = sinfo[scclist[i]].leftmost;
00146       while (y[start].max() < xmin) {
00147         start = sinfo[start].right;
00148       }
00149         
00150       if (Perm) {
00151         // start is the leftmost-position for x_i
00152         // that denotes the lower bound on p_i
00153 
00154         ModEvent me_plb = xz[i][1].gq(home, start);
00155         if (me_failed(me_plb)) {
00156           return false;
00157         }
00158         nofix |= (me_modified(me_plb) && start != xz[i][1].min());
00159       }
00160 
00161       ModEvent me_lb = xz[i][0].gq(home, y[start].min());
00162       if (me_failed(me_lb)) {
00163         return false;
00164       }
00165       nofix |= (me_modified(me_lb) &&
00166                 y[start].min() != xz[i][0].min());
00167         
00168       int ptau = tau[xs - 1 - i];
00169       int xmax = xz[ptau][0].max();
00170       /*
00171        * take the scc-list for the current x node
00172        * start from the rightmost reachable node and check which
00173        * y node in the scc is
00174        * really the rightmost node intersecting x, i.e.
00175        * search for the smallest upper bound of x
00176        */
00177       start = sinfo[scclist[ptau]].rightmost;
00178       while (y[start].min() > xmax) {
00179         start = sinfo[start].left;
00180       }
00181 
00182       if (Perm) {
00183         //start is the rightmost-position for x_i
00184         //that denotes the upper bound on p_i
00185         ModEvent me_pub = xz[ptau][1].lq(home, start);
00186         if (me_failed(me_pub)) {
00187           return false;
00188         }
00189         nofix |= (me_modified(me_pub) && start != xz[ptau][1].max());
00190       }
00191 
00192       ModEvent me_ub = xz[ptau][0].lq(home, y[start].max());
00193       if (me_failed(me_ub)) {
00194         return false;
00195       }
00196       nofix |= (me_modified(me_ub) &&
00197                 y[start].max() != xz[ptau][0].max());
00198     }
00199     return true;
00200   }
00201 
00212   template<class View, class Tuple, bool Perm>
00213   forceinline bool
00214   narrow_domy(Space* home,
00215               ViewArray<Tuple>& xz,
00216               ViewArray<View>& y,
00217               int phi[],
00218               int phiprime[],
00219               bool& nofix) {
00220 
00221     int xs = xz.size();
00222     for (int i = xs; i--; ) {
00223       ModEvent me_lb = y[i].gq(home, xz[phiprime[i]][0].min());
00224       if (me_failed(me_lb)) {
00225         return false;
00226       }
00227       nofix |= (me_modified(me_lb) &&
00228                 xz[phiprime[i]][0].min() != y[i].min());
00229 
00230       ModEvent me_ub = y[i].lq(home, xz[phi[i]][0].max());
00231       if (me_failed(me_ub)) {
00232         return false;
00233       }
00234       nofix |= (me_modified(me_ub) &&
00235                 xz[phi[i]][0].max() != y[i].max());
00236     }
00237     return true;
00238   }
00239 
00240 }}}
00241 
00242 // STATISTICS: int-prop
00243