Generated on Fri Mar 20 15:56:16 2015 for Gecode by doxygen 1.6.3

brancher-view-sel.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main author:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2012
00008  *
00009  *  Last modified:
00010  *     $Date: 2012-10-30 07:46:12 +0100 (Tue, 30 Oct 2012) $ by $Author: tack $
00011  *     $Revision: 13166 $
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 {
00039 
00046 
00047   template<class _View>
00048   class ViewSel {
00049   public:
00051     typedef _View View;
00053     typedef typename BranchTraits<typename View::VarType>::Filter BranchFilter;
00055 
00056 
00057     ViewSel(Space& home, const VarBranch& vb);
00059     ViewSel(Space& home, bool shared, ViewSel<View>& vs);
00061 
00062 
00063 
00064     virtual int select(Space& home, ViewArray<View>& x, int s) = 0;
00066     virtual int select(Space& home, ViewArray<View>& x, int s, 
00067                        BranchFilter bf) = 0;
00069     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00070                       int* ties, int& n) = 0;
00072     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00073                       int* ties, int& n, BranchFilter bf) = 0;
00075     virtual void brk(Space& home, ViewArray<View>& x, 
00076                      int* ties, int& n) = 0;
00078     virtual int select(Space& home, ViewArray<View>& x, 
00079                        int* ties, int n) = 0;
00081 
00082 
00083 
00084     virtual ViewSel<View>* copy(Space& home, bool shared) = 0;
00086     virtual bool notice(void) const;
00088     virtual void dispose(Space& home);
00090 
00091 
00092 
00093     static void* operator new(size_t s, Space& home);
00095     static void operator delete(void* p, Space& home);
00097     static void operator delete(void* p);
00099   };
00100 
00102   template<class View>
00103   class ViewSelNone : public ViewSel<View> {
00104     typedef typename ViewSel<View>::BranchFilter BranchFilter;
00105   public:
00107 
00108 
00109     ViewSelNone(Space& home, const VarBranch& vb);
00111     ViewSelNone(Space& home, bool shared, ViewSelNone<View>& vs);
00113 
00114 
00115 
00116     virtual int select(Space& home, ViewArray<View>& x, int s);
00118     virtual int select(Space& home, ViewArray<View>& x, int s, 
00119                        BranchFilter bf);
00121     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00122                       int* ties, int& n);
00124     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00125                       int* ties, int& n,
00126                       BranchFilter bf);
00128     virtual void brk(Space& home, ViewArray<View>& x, 
00129                      int* ties, int& n);
00131     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
00133 
00134 
00135 
00136     virtual ViewSel<View>* copy(Space& home, bool shared);
00138   };
00139 
00141   template<class View>
00142   class ViewSelRnd : public ViewSel<View> {
00143     typedef typename ViewSel<View>::BranchFilter BranchFilter;
00144   protected:
00146     Rnd r;
00147   public:
00149 
00150 
00151     ViewSelRnd(Space& home, const VarBranch& vb);
00153     ViewSelRnd(Space& home, bool shared, ViewSelRnd<View>& vs);
00155 
00156 
00157 
00158     virtual int select(Space& home, ViewArray<View>& x, int s);
00160     virtual int select(Space& home, ViewArray<View>& x, int s,
00161                        BranchFilter bf);
00163     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00164                       int* ties, int& n);
00166     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00167                       int* ties, int& n, BranchFilter bf);
00169     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
00171     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
00173 
00174 
00175 
00176     virtual ViewSel<View>* copy(Space& home, bool shared);
00178   };
00179 
00181   class ChooseMin {
00182   public:
00184     template<class Val>
00185     bool operator ()(Val a, Val b) const;
00186   };
00187 
00189   class ChooseMax {
00190   public:
00192     template<class Val>
00193     bool operator ()(Val a, Val b) const;
00194   };
00195 
00197   template<class Choose, class Merit>
00198   class ViewSelChoose : public ViewSel<typename Merit::View> {
00199   protected:
00200     typedef typename ViewSel<typename Merit::View>::View View;
00201     typedef typename ViewSel<typename Merit::View>::BranchFilter BranchFilter;
00203     typedef typename Merit::Val Val;
00205     Choose c;
00207     Merit m;
00208   public:
00210 
00211 
00212     ViewSelChoose(Space& home, const VarBranch& vb);
00214     ViewSelChoose(Space& home, bool shared, ViewSelChoose<Choose,Merit>& vs);
00216 
00217 
00218 
00219     virtual int select(Space& home, ViewArray<View>& x, int s);
00221     virtual int select(Space& home, ViewArray<View>& x, int s, 
00222                        BranchFilter bf);
00224     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00225                       int* ties, int& n);
00227     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00228                       int* ties, int& n, BranchFilter bf);
00230     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
00232     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
00234 
00235 
00236 
00237     virtual bool notice(void) const;
00239     virtual void dispose(Space& home);
00241   };
00242 
00243 
00245   template<class Choose, class Merit>
00246   class ViewSelChooseTbl : public ViewSelChoose<Choose,Merit> {
00247   protected:
00248     typedef typename ViewSelChoose<Choose,Merit>::Val Val;
00249     typedef typename ViewSelChoose<Choose,Merit>::View View;
00250     typedef typename ViewSelChoose<Choose,Merit>::BranchFilter BranchFilter;
00251     using ViewSelChoose<Choose,Merit>::c;
00252     using ViewSelChoose<Choose,Merit>::m;
00254     BranchTbl tbl;
00255   public:
00257 
00258 
00259     ViewSelChooseTbl(Space& home, const VarBranch& vb);
00261     ViewSelChooseTbl(Space& home, bool shared, 
00262                      ViewSelChooseTbl<Choose,Merit>& vs); 
00264 
00265 
00266 
00267     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00268                       int* ties, int& n);
00270     virtual void ties(Space& home, ViewArray<View>& x, int s, 
00271                       int* ties, int& n, BranchFilter bf);
00273     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
00275   };
00276 
00278   template<class Merit>
00279   class ViewSelMin : public ViewSelChoose<ChooseMin,Merit> {
00280     typedef typename ViewSelChoose<ChooseMin,Merit>::View View;
00281     typedef typename ViewSelChoose<ChooseMin,Merit>::BranchFilter BranchFilter;
00282   public:
00284 
00285 
00286     ViewSelMin(Space& home, const VarBranch& vb);
00288     ViewSelMin(Space& home, bool shared, ViewSelMin<Merit>& vs);
00290 
00291 
00292 
00293     virtual ViewSel<View>* copy(Space& home, bool shared);
00295   };
00296 
00298   template<class Merit>
00299   class ViewSelMinTbl : public ViewSelChooseTbl<ChooseMin,Merit> {
00300     typedef typename ViewSelChooseTbl<ChooseMin,Merit>::View View;
00301     typedef typename ViewSelChooseTbl<ChooseMin,Merit>::BranchFilter BranchFilter;
00302   public:
00304 
00305 
00306     ViewSelMinTbl(Space& home, const VarBranch& vb);
00308     ViewSelMinTbl(Space& home, bool shared, ViewSelMinTbl<Merit>& vs);
00310 
00311 
00312 
00313     virtual ViewSel<View>* copy(Space& home, bool shared);
00315   };
00316 
00318   template<class Merit>
00319   class ViewSelMax : public ViewSelChoose<ChooseMax,Merit> {
00320     typedef typename ViewSelChoose<ChooseMax,Merit>::View View;
00321     typedef typename ViewSelChoose<ChooseMax,Merit>::BranchFilter BranchFilter;
00322   public:
00324 
00325 
00326     ViewSelMax(Space& home, const VarBranch& vb);
00328     ViewSelMax(Space& home, bool shared, ViewSelMax<Merit>& vs);
00330 
00331 
00332 
00333     virtual ViewSel<View>* copy(Space& home, bool shared);
00335   };
00336 
00338   template<class Merit>
00339   class ViewSelMaxTbl : public ViewSelChooseTbl<ChooseMax,Merit> {
00340     typedef typename ViewSelChooseTbl<ChooseMax,Merit>::View View;
00341     typedef typename ViewSelChooseTbl<ChooseMax,Merit>::BranchFilter BranchFilter;
00342   public:
00344 
00345 
00346     ViewSelMaxTbl(Space& home, const VarBranch& vb);
00348     ViewSelMaxTbl(Space& home, bool shared, ViewSelMaxTbl<Merit>& vs);
00350 
00351 
00352 
00353     virtual ViewSel<View>* copy(Space& home, bool shared);
00355   };
00357 
00358 
00359   template<class View>
00360   forceinline
00361   ViewSel<View>::ViewSel(Space&, const VarBranch&) {}
00362   template<class View>
00363   forceinline
00364   ViewSel<View>::ViewSel(Space&, bool, ViewSel<View>&) {}
00365   template<class View>
00366   bool
00367   ViewSel<View>::notice(void) const {
00368     return false;
00369   }
00370   template<class View>
00371   void
00372   ViewSel<View>::dispose(Space&) {}
00373   template<class View>
00374   forceinline void
00375   ViewSel<View>::operator delete(void*) {}
00376   template<class View>
00377   forceinline void
00378   ViewSel<View>::operator delete(void*, Space&) {}
00379   template<class View>
00380   forceinline void*
00381   ViewSel<View>::operator new(size_t s, Space& home) {
00382     return home.ralloc(s);
00383   }
00384 
00385 
00386   template<class View>
00387   forceinline
00388   ViewSelNone<View>::ViewSelNone(Space& home, const VarBranch& vb) 
00389       : ViewSel<View>(home,vb) {}
00390   template<class View>
00391   forceinline
00392   ViewSelNone<View>::ViewSelNone(Space& home, bool shared, 
00393                                  ViewSelNone<View>& vs)
00394     : ViewSel<View>(home,shared,vs) {}
00395   template<class View>
00396   int
00397   ViewSelNone<View>::select(Space&, ViewArray<View>&, int s) {
00398     return s;
00399   }
00400   template<class View>
00401   int
00402   ViewSelNone<View>::select(Space&, ViewArray<View>&, int s, BranchFilter) {
00403     return s;
00404   }
00405   template<class View>
00406   void 
00407   ViewSelNone<View>::ties(Space&, ViewArray<View>& x, int s, 
00408                           int* ties, int& n) {
00409     int j=0; ties[j++]=s;
00410     for (int i=s+1; i<x.size(); i++)
00411       if (!x[i].assigned())
00412         ties[j++]=i;
00413     n=j;
00414     assert(n > 0);
00415   }
00416   template<class View>
00417   void 
00418   ViewSelNone<View>::ties(Space& home, ViewArray<View>& x, int s, 
00419                           int* ties, int& n, BranchFilter bf) {
00420     int j=0; ties[j++]=s;
00421     for (int i=s+1; i<x.size(); i++) {
00422       typename View::VarType y(x[i].varimp());
00423       if (!x[i].assigned() && bf(home,y,i))
00424         ties[j++]=i;
00425     }
00426     n=j;
00427     assert(n > 0);
00428   }
00429   template<class View>
00430   void
00431   ViewSelNone<View>::brk(Space&, ViewArray<View>&, int*, int&) {
00432     // Nothing needs to be done
00433   }
00434   template<class View>
00435   int
00436   ViewSelNone<View>::select(Space&, ViewArray<View>&, int* ties, int) {
00437     return ties[0];
00438   }
00439   template<class View>
00440   ViewSel<View>*
00441   ViewSelNone<View>::copy(Space& home, bool shared) {
00442     return new (home) ViewSelNone<View>(home,shared,*this);
00443   }
00444 
00445 
00446   template<class View>
00447   forceinline
00448   ViewSelRnd<View>::ViewSelRnd(Space& home, const VarBranch& vb) 
00449       : ViewSel<View>(home,vb), r(vb.rnd()) {}
00450   template<class View>
00451   forceinline
00452   ViewSelRnd<View>::ViewSelRnd(Space& home, bool shared, ViewSelRnd<View>& vs)
00453       : ViewSel<View>(home,shared,vs), r(vs.r) {}
00454   template<class View>
00455   int
00456   ViewSelRnd<View>::select(Space&, ViewArray<View>& x, int s) {
00457     unsigned int n=1;
00458     int j=s;
00459     for (int i=s+1; i<x.size(); i++)
00460       if (!x[i].assigned()) {
00461         n++;
00462         if (r(n) == 0U)
00463           j=i;
00464       }
00465     return j;
00466   }
00467   template<class View>
00468   int ViewSelRnd<View>::select(Space& home, ViewArray<View>& x, int s,
00469                                BranchFilter bf) {
00470     unsigned int n=1;
00471     int j=s;
00472     for (int i=s+1; i<x.size(); i++) {
00473       typename View::VarType y(x[i].varimp());
00474       if (!x[i].assigned() && bf(home,y,i)) {
00475         n++;
00476         if (r(n) == 0U)
00477           j=i;
00478       }
00479     }
00480     return j;
00481   }
00482   template<class View>
00483   void 
00484   ViewSelRnd<View>::ties(Space& home, ViewArray<View>& x, int s, 
00485                          int* ties, int& n) {
00486     n=1; ties[0] = select(home,x,s);
00487   }
00488   template<class View>
00489   void
00490   ViewSelRnd<View>::ties(Space& home, ViewArray<View>& x, int s, 
00491                          int* ties, int& n, BranchFilter bf) {
00492     n=1; ties[0] = select(home,x,s,bf);
00493   }
00494   template<class View>
00495   void 
00496   ViewSelRnd<View>::brk(Space&, ViewArray<View>&, int* ties, int& n) {
00497     ties[0] = ties[static_cast<int>(r(static_cast<unsigned int>(n)))];
00498     n=1;
00499   }
00500   template<class View>
00501   int
00502   ViewSelRnd<View>::select(Space&, ViewArray<View>&, int* ties, int n) {
00503     return ties[static_cast<int>(r(static_cast<unsigned int>(n)))];
00504   }
00505   template<class View>
00506   ViewSel<View>*
00507   ViewSelRnd<View>::copy(Space& home, bool shared) {
00508     return new (home) ViewSelRnd<View>(home,shared,*this);
00509   }
00510 
00511 
00512   template<class Val>
00513   forceinline bool
00514   ChooseMin::operator ()(Val a, Val b) const {
00515     return a < b;
00516   }
00517   template<class Val>
00518   forceinline bool
00519   ChooseMax::operator ()(Val a, Val b) const {
00520     return a > b;
00521   }
00522 
00523 
00524   template<class Choose, class Merit>
00525   forceinline
00526   ViewSelChoose<Choose,Merit>::ViewSelChoose(Space& home, const VarBranch& vb) 
00527     : ViewSel<View>(home,vb), m(home,vb) {}
00528 
00529   template<class Choose, class Merit>
00530   forceinline
00531   ViewSelChoose<Choose,Merit>::ViewSelChoose(Space& home, bool shared, 
00532                                              ViewSelChoose<Choose,Merit>& vs) 
00533     : ViewSel<View>(home,shared,vs), m(home,shared,vs.m) {}
00534 
00535   template<class Choose, class Merit>
00536   int
00537   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x, int s) {
00538     // Consider x[s] as the so-far best view
00539     int b_i = s;
00540     Val b_m = m(home,x[s],s);
00541     // Scan all non-assigned views from s+1 onwards
00542     for (int i=s+1; i<x.size(); i++)
00543       if (!x[i].assigned()) {
00544         Val mxi = m(home,x[i],i);
00545         if (c(mxi,b_m)) {
00546           b_i = i; b_m = mxi;
00547         }
00548       }
00549     return b_i;
00550   }
00551 
00552   template<class Choose, class Merit>
00553   int 
00554   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x, int s, 
00555                                       BranchFilter bf) {
00556     // Consider x[s] as the so-far best view
00557     int b_i = s;
00558     Val b_m = m(home,x[s],s);
00559     // Scan all assigned views from s+1 onwards
00560     for (int i=s+1; i<x.size(); i++) {
00561       typename View::VarType y(x[i].varimp());
00562       if (!x[i].assigned() && bf(home,y,i)) {
00563         Val mxi = m(home,x[i],i);
00564         if (c(mxi,b_m)) {
00565           b_i = i; b_m = mxi;
00566         }
00567       }
00568     }
00569     return b_i;
00570   }
00571 
00572   template<class Choose, class Merit>
00573   void 
00574   ViewSelChoose<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s, 
00575                                     int* ties, int& n) {
00576     // Consider x[s] as the so-far best view and record as tie
00577     Val b = m(home,x[s],s);
00578     int j=0; ties[j++]=s;
00579     for (int i=s+1; i<x.size(); i++)
00580       if (!x[i].assigned()) {
00581         Val mxi = m(home,x[i],i);
00582         if (c(mxi,b)) {
00583           // Found a better one, reset all ties and record
00584           j=0; ties[j++]=i; b=mxi;
00585         } else if (mxi == b) {
00586           // Found a tie, record
00587           ties[j++]=i;
00588         }
00589       }
00590     n=j;
00591     // There must be at least one tie, of course!
00592     assert(n > 0);
00593   }
00594 
00595   template<class Choose, class Merit>
00596   void 
00597   ViewSelChoose<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s, 
00598                                     int* ties, int& n, BranchFilter bf) {
00599     // Consider x[s] as the so-far best view and record as tie
00600     Val b = m(home,x[s],s);
00601     int j=0; ties[j++]=s;
00602     for (int i=s+1; i<x.size(); i++) {
00603       typename View::VarType y(x[i].varimp());
00604       if (!x[i].assigned() && bf(home,y,i)) {
00605         Val mxi = m(home,x[i],i);
00606         if (c(mxi,b)) {
00607           // Found a better one, reset all ties and record
00608           j=0; ties[j++]=i; b=mxi;
00609         } else if (mxi == b) {
00610           // Found a tie, record
00611           ties[j++]=i;
00612         }
00613       }
00614     }
00615     n=j;
00616     // There must be at least one tie, of course!
00617     assert(n > 0);
00618   }
00619 
00620   template<class Choose, class Merit>
00621   void 
00622   ViewSelChoose<Choose,Merit>::brk(Space& home, ViewArray<View>& x, 
00623                                    int* ties, int& n) {
00624     // Keep first tie in place
00625     Val b = m(home,x[ties[0]],ties[0]);
00626     int j=1;
00627     // Scan remaining ties
00628     for (int i=1; i<n; i++) {
00629       Val mxi = m(home,x[ties[i]],ties[i]);
00630       if (c(mxi,b)) {
00631         // Found a better one, reset all ties
00632         b=mxi; j=0; ties[j++]=ties[i];
00633       } else if (mxi == b) {
00634         // Found a tie and record it
00635         ties[j++]=ties[i];
00636       }
00637     }
00638     n=j;
00639     // There must be at least one tie, of course!      
00640     assert(n > 0);
00641   }
00642 
00643   template<class Choose, class Merit>
00644   int 
00645   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x, 
00646                                       int* ties, int n) {
00647     int b_i = ties[0];
00648     Val b_m = m(home,x[ties[0]],ties[0]);
00649     for (int i=1; i<n; i++) {
00650       Val mxi = m(home,x[ties[i]],ties[i]);
00651       if (c(mxi,b_m)) {
00652         b_i = ties[i]; b_m = mxi;
00653       }
00654     }
00655     return b_i;
00656   }
00657   
00658   template<class Choose, class Merit>
00659   bool 
00660   ViewSelChoose<Choose,Merit>::notice(void) const {
00661     return m.notice();
00662   }
00663 
00664   template<class Choose, class Merit>
00665   void 
00666   ViewSelChoose<Choose,Merit>::dispose(Space& home) {
00667     m.dispose(home);
00668   }
00669 
00670 
00671   template<class Choose, class Merit>
00672   forceinline
00673   ViewSelChooseTbl<Choose,Merit>::ViewSelChooseTbl(Space& home, 
00674                                                    const VarBranch& vb) 
00675     : ViewSelChoose<Choose,Merit>(home,vb), tbl(vb.tbl()) {}
00676 
00677   template<class Choose, class Merit>
00678   forceinline
00679   ViewSelChooseTbl<Choose,Merit>::ViewSelChooseTbl
00680   (Space& home, bool shared, 
00681    ViewSelChooseTbl<Choose,Merit>& vs) 
00682     : ViewSelChoose<Choose,Merit>(home,shared,vs), tbl(vs.tbl) {}
00683 
00684   template<class Choose, class Merit>
00685   void 
00686   ViewSelChooseTbl<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s, 
00687                                        int* ties, int& n) {
00688     // Find the worst and best merit value
00689     Val w = m(home,x[s],s);
00690     Val b = w;
00691     for (int i=s+1; i<x.size(); i++)
00692       if (!x[i].assigned()) {
00693         Val mxi = m(home,x[i],i);
00694         if (c(mxi,b))
00695           b=mxi;
00696         else if (c(w,mxi))
00697           w=mxi;
00698       }
00699     // Compute tie-break limit
00700     double l = tbl(home,static_cast<double>(w),static_cast<double>(b));
00701     // If the limit is not better than the worst merit, everything is a tie
00702     if (!c(l,static_cast<double>(w))) {
00703       int j=0;
00704       for (int i=s; i<x.size(); i++)
00705         if (!x[i].assigned())
00706           ties[j++]=i;
00707       n=j;
00708     } else {
00709       // The limit is not allowed to better than the best merit value
00710       if (c(l,static_cast<double>(b)))
00711         l = static_cast<double>(b);
00712       // Record all ties that are not worse than the limit merit value
00713       int j=0;
00714       for (int i=s; i<x.size(); i++)
00715         if (!x[i].assigned() && !c(l,static_cast<double>(m(home,x[i],i))))
00716           ties[j++]=i;
00717       n=j;
00718     }
00719     // There will be at least one tie (the best will qualify, of course)
00720     assert(n > 0);
00721   }
00722 
00723   template<class Choose, class Merit>
00724   void
00725   ViewSelChooseTbl<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s, 
00726                                        int* ties, int& n, BranchFilter bf) {
00727     // Find the worst and best merit value
00728     Val w = m(home,x[s],s);
00729     Val b = w;
00730     for (int i=s+1; i<x.size(); i++) {
00731       typename View::VarType y(x[i].varimp());
00732       if (!x[i].assigned() && bf(home,y,i)) {
00733         Val mxi = m(home,x[i],i);
00734         if (c(mxi,b))
00735           b=mxi;
00736         else if (c(w,mxi))
00737           w=mxi;
00738       }
00739     }
00740     // Compute tie-break limit
00741     double l = tbl(home,static_cast<double>(w),static_cast<double>(b));
00742     // If the limit is not better than the worst merit, everything is a tie
00743     if (!c(l,static_cast<double>(w))) {
00744       int j=0;
00745       for (int i=s; i<x.size(); i++) {
00746         typename View::VarType y(x[i].varimp());
00747         if (!x[i].assigned() && bf(home,y,i)) 
00748           ties[j++]=i;
00749       }
00750       n=j;
00751     } else {
00752       // The limit is not allowed to better than the best merit value
00753       if (c(l,static_cast<double>(b)))
00754         l = static_cast<double>(b);
00755       // Record all ties that are not worse than the limit merit value
00756       int j=0;
00757       for (int i=s; i<x.size(); i++) {
00758         typename View::VarType y(x[i].varimp());
00759         if (!x[i].assigned() && bf(home,y,i) && 
00760             !c(l,static_cast<double>(m(home,x[i],i))))
00761           ties[j++]=i;
00762       }
00763       n=j;
00764       }
00765     // There will be at least one tie (the best will qualify, of course)
00766     assert(n > 0);
00767   }
00768 
00769   template<class Choose, class Merit>
00770   void
00771   ViewSelChooseTbl<Choose,Merit>::brk(Space& home, ViewArray<View>& x,
00772                                       int* ties, int& n) {
00773     // Find the worst and best merit value
00774     Val w = m(home,x[ties[0]],ties[0]);
00775     Val b = w;
00776     for (int i=1; i<n; i++) {
00777       Val mxi = m(home,x[ties[i]],ties[i]);
00778       if (c(mxi,b))
00779         b=mxi;
00780       else if (c(w,mxi))
00781         w=mxi;
00782     }
00783     // Compute tie-break limit
00784     double l = tbl(home,static_cast<double>(w),static_cast<double>(b));
00785     // If the limit is not better than the worst merit, everything is a tie
00786     // and no breaking is required
00787     if (c(l,static_cast<double>(w))) {
00788       // The limit is not allowed to better than the best merit value
00789       if (c(l,static_cast<double>(b)))
00790         l = static_cast<double>(b);
00791       // Keep all ties that are not worse than the limit merit value
00792       int j=0;
00793       for (int i=0; i<n; i++)
00794         if (!c(l,static_cast<double>(m(home,x[ties[i]],ties[i]))))
00795           ties[j++]=ties[i];
00796       n=j;
00797     }
00798     // There will be at least one tie (the best will qualify)
00799     assert(n > 0);
00800   }
00801 
00802 
00803 
00804   template<class Merit>
00805   forceinline
00806   ViewSelMin<Merit>::ViewSelMin(Space& home, const VarBranch& vb) 
00807     : ViewSelChoose<ChooseMin,Merit>(home,vb) {}
00808 
00809   template<class Merit>
00810   forceinline
00811   ViewSelMin<Merit>::ViewSelMin(Space& home, bool shared, 
00812                                 ViewSelMin<Merit>& vs) 
00813     : ViewSelChoose<ChooseMin,Merit>(home,shared,vs) {}
00814 
00815   template<class Merit>
00816   ViewSel<typename ViewSelMin<Merit>::View>* 
00817   ViewSelMin<Merit>::copy(Space& home, bool shared) {
00818     return new (home) ViewSelMin<Merit>(home,shared,*this);
00819   }
00820 
00821 
00822   template<class Merit>
00823   forceinline
00824   ViewSelMinTbl<Merit>::ViewSelMinTbl(Space& home, const VarBranch& vb) 
00825     : ViewSelChooseTbl<ChooseMin,Merit>(home,vb) {}
00826 
00827   template<class Merit>
00828   forceinline
00829   ViewSelMinTbl<Merit>::ViewSelMinTbl(Space& home, bool shared, 
00830                                       ViewSelMinTbl<Merit>& vs) 
00831     : ViewSelChooseTbl<ChooseMin,Merit>(home,shared,vs) {}
00832 
00833   template<class Merit>
00834   ViewSel<typename ViewSelMinTbl<Merit>::View>* 
00835   ViewSelMinTbl<Merit>::copy(Space& home, bool shared) {
00836     return new (home) ViewSelMinTbl<Merit>(home,shared,*this);
00837   }
00838 
00839 
00840 
00841   template<class Merit>
00842   forceinline
00843   ViewSelMax<Merit>::ViewSelMax(Space& home, const VarBranch& vb) 
00844     : ViewSelChoose<ChooseMax,Merit>(home,vb) {}
00845 
00846   template<class Merit>
00847   forceinline
00848   ViewSelMax<Merit>::ViewSelMax(Space& home, bool shared, 
00849                                 ViewSelMax<Merit>& vs) 
00850     : ViewSelChoose<ChooseMax,Merit>(home,shared,vs) {}
00851 
00852   template<class Merit>
00853   ViewSel<typename ViewSelMax<Merit>::View>* 
00854   ViewSelMax<Merit>::copy(Space& home, bool shared) {
00855     return new (home) ViewSelMax<Merit>(home,shared,*this);
00856   }
00857 
00858 
00859 
00860   template<class Merit>
00861   forceinline
00862   ViewSelMaxTbl<Merit>::ViewSelMaxTbl(Space& home, const VarBranch& vb) 
00863     : ViewSelChooseTbl<ChooseMax,Merit>(home,vb) {}
00864 
00865   template<class Merit>
00866   forceinline
00867   ViewSelMaxTbl<Merit>::ViewSelMaxTbl(Space& home, bool shared, 
00868                                       ViewSelMaxTbl<Merit>& vs) 
00869     : ViewSelChooseTbl<ChooseMax,Merit>(home,shared,vs) {}
00870 
00871   template<class Merit>
00872   ViewSel<typename ViewSelMaxTbl<Merit>::View>* 
00873   ViewSelMaxTbl<Merit>::copy(Space& home, bool shared) {
00874     return new (home) ViewSelMaxTbl<Merit>(home,shared,*this);
00875   }
00876 
00877 
00878 
00879 }
00880 
00881 // STATISTICS: kernel-branch