1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  *  Main author:
4  *     Christian Schulte <schulte@gecode.org>
5  *
6  *  Copyright:
7  *     Christian Schulte, 2012
8  *
9  *  This file is part of Gecode, the generic constraint
10  *  development environment:
11  *     http://www.gecode.org
12  *
13  *  Permission is hereby granted, free of charge, to any person obtaining
14  *  a copy of this software and associated documentation files (the
15  *  "Software"), to deal in the Software without restriction, including
16  *  without limitation the rights to use, copy, modify, merge, publish,
17  *  distribute, sublicense, and/or sell copies of the Software, and to
18  *  permit persons to whom the Software is furnished to do so, subject to
19  *  the following conditions:
20  *
21  *  The above copyright notice and this permission notice shall be
22  *  included in all copies or substantial portions of the Software.
23  *
24  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31  *
32  */
33 
34 namespace Gecode {
35 
36   /**
37    * \defgroup TaskBranchViewSel Generic view selection for brancher based on view and value selection
38    *
39    * \ingroup TaskBranchViewVal
40    */
41   //@{
42   /// Abstract class for view selection
43   template<class View_>
44   class ViewSel {
45   public:
46     /// Define the view type
47     typedef View_ View;
48     /// The corresponding variable type
49     typedef typename View::VarType Var;
50     /// \name Initialization
51     //@{
52     /// Constructor for creation
53     ViewSel(Space& home, const VarBranch<Var>& vb);
54     /// Constructor for copying during cloning
55     ViewSel(Space& home, ViewSel<View>& vs);
56     //@}
57     /// \name View selection and tie breaking
58     //@{
59     /// Select a view from \a x starting from \a s and return its position
60     virtual int select(Space& home, ViewArray<View>& x, int s) = 0;
61     /// Select a view from \a x starting from \a s and return its position
62     virtual int select(Space& home, ViewArray<View>& x, int s,
63                        BrancherFilter<View>& f) = 0;
64     /// Select a view from \a x starting from \a s and return its position
65     virtual int select(Space& home, ViewArray<View>& x, int s,
66                        BrancherNoFilter<View>& f);
67     /// Select ties from \a x starting from \a s
68     virtual void ties(Space& home, ViewArray<View>& x, int s,
69                       int* ties, int& n) = 0;
70     /// Select ties from \a x starting from \a s
71     virtual void ties(Space& home, ViewArray<View>& x, int s,
72                       int* ties, int& n,
73                       BrancherFilter<View>& f) = 0;
74     /// Select ties from \a x starting from \a s
75     virtual void ties(Space& home, ViewArray<View>& x, int s,
76                       int* ties, int& n,
77                       BrancherNoFilter<View>& f);
78     /// Break ties in \a x and update to new ties
79     virtual void brk(Space& home, ViewArray<View>& x,
80                      int* ties, int& n) = 0;
81     /// Select a view from \a x considering views with positions in \a ties
82     virtual int select(Space& home, ViewArray<View>& x,
83                        int* ties, int n) = 0;
84     //@}
85     /// \name Resource management and cloning
86     //@{
87     /// Create copy during cloning
88     virtual ViewSel<View>* copy(Space& home) = 0;
89     /// Whether dispose must always be called (that is, notice is needed)
90     virtual bool notice(void) const;
91     /// Dispose view selection
92     virtual void dispose(Space& home);
93     /// Unused destructor
94     virtual ~ViewSel(void);
95     //@}
96     /// \name Memory management
97     //@{
98     /// Allocate memory from space
99     static void* operator new(size_t s, Space& home);
100     /// Return memory to space
101     static void operator delete(void* p, Space& home);
102     /// Needed for exceptions
103     static void operator delete(void* p);
104     //@}
105   };
106 
107   /// Select the first unassigned view
108   template<class View>
109   class ViewSelNone : public ViewSel<View> {
110   protected:
111     typedef typename ViewSel<View>::Var Var;
112   public:
113     /// \name Initialization
114     //@{
115     /// Constructor for creation
116     ViewSelNone(Space& home, const VarBranch<Var>& vb);
117     /// Constructor for copying during cloning
118     ViewSelNone(Space& home, ViewSelNone<View>& vs);
119     //@}
120     /// \name View selection and tie breaking
121     //@{
122     /// Select a view from \a x starting at \a s and return its position
123     virtual int select(Space& home, ViewArray<View>& x, int s);
124     /// Select a view from \a x starting at \a s and return its position
125     virtual int select(Space& home, ViewArray<View>& x, int s,
126                        BrancherFilter<View>& f);
127     /// Select ties from \a x starting at \a s
128     virtual void ties(Space& home, ViewArray<View>& x, int s,
129                       int* ties, int& n);
130     /// Select ties from \a x starting at \a s
131     virtual void ties(Space& home, ViewArray<View>& x, int s,
132                       int* ties, int& n,
133                       BrancherFilter<View>& f);
134     /// Break ties in \a x and update to new ties
135     virtual void brk(Space& home, ViewArray<View>& x,
136                      int* ties, int& n);
137     /// Select a view from \a x considering view with positions in \a ties
138     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
139     //@}
140     /// \name Resource management and cloning
141     //@{
142     /// Create copy during cloning
143     virtual ViewSel<View>* copy(Space& home);
144     //@}
145   };
146 
147   /// Select a view randomly
148   template<class View>
149   class ViewSelRnd : public ViewSel<View> {
150   protected:
151     typedef typename ViewSel<View>::Var Var;
152     /// The random number generator used
153     Rnd r;
154   public:
155     /// \name Initialization
156     //@{
157     /// Constructor for creation
158     ViewSelRnd(Space& home, const VarBranch<Var>& vb);
159     /// Constructor for copying during cloning
160     ViewSelRnd(Space& home, ViewSelRnd<View>& vs);
161     //@}
162     /// \name View selection and tie breaking
163     //@{
164     /// Select a view from \a x starting from \a s and return its position
165     virtual int select(Space& home, ViewArray<View>& x, int s);
166     /// Select a view from \a x starting from \a s and return its position
167     virtual int select(Space& home, ViewArray<View>& x, int s,
168                        BrancherFilter<View>& f);
169     /// Select ties from \a x starting from \a s
170     virtual void ties(Space& home, ViewArray<View>& x, int s,
171                       int* ties, int& n);
172     /// Select ties from \a x starting from \a s
173     virtual void ties(Space& home, ViewArray<View>& x, int s,
174                       int* ties, int& n,
175                       BrancherFilter<View>& f);
176     /// Break ties in \a x and update to new ties
177     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
178     /// Select a view from \a x considering view with positions in \a ties
179     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
180     //@}
181     /// \name Resource management and cloning
182     //@{
183     /// Create copy during cloning
184     virtual ViewSel<View>* copy(Space& home);
185     //@}
186   };
187 
188   /// Choose views with smaller merit values
189   class ChooseMin {
190   public:
191     /// Return true if \a a is better than \a b
192     template<class Val>
193     bool operator ()(Val a, Val b) const;
194   };
195 
196   /// Choose views with larger merit values
197   class ChooseMax {
198   public:
199     /// Return true if \a a is better than \a b
200     template<class Val>
201     bool operator ()(Val a, Val b) const;
202   };
203 
204   /// Choose view according to merit
205   template<class Choose, class Merit>
206   class ViewSelChoose : public ViewSel<typename Merit::View> {
207   protected:
208     typedef typename ViewSel<typename Merit::View>::Var Var;
209     typedef typename ViewSel<typename Merit::View>::View View;
210     /// Type of merit
211     typedef typename Merit::Val Val;
212     /// How to choose
213     Choose c;
214     /// The merit object used
215     Merit m;
216   public:
217     /// \name Initialization
218     //@{
219     /// Constructor for creation
220     ViewSelChoose(Space& home, const VarBranch<Var>& vb);
221     /// Constructor for copying during cloning
222     ViewSelChoose(Space& home, ViewSelChoose<Choose,Merit>& vs);
223     //@}
224     /// \name View selection and tie breaking
225     //@{
226     /// Select a view from \a x starting from \a s and return its position
227     virtual int select(Space& home, ViewArray<View>& x, int s);
228     /// Select a view from \a x starting from \a s and return its position
229     virtual int select(Space& home, ViewArray<View>& x, int s,
230                        BrancherFilter<View>& f);
231     /// Select ties from \a x starting from \a s
232     virtual void ties(Space& home, ViewArray<View>& x, int s,
233                       int* ties, int& n);
234     /// Select ties from \a x starting from \a s
235     virtual void ties(Space& home, ViewArray<View>& x, int s,
236                       int* ties, int& n,
237                       BrancherFilter<View>& f);
238     /// Break ties in \a x and update to new ties
239     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
240     /// Select a view from \a x considering views with positions in \a ties
241     virtual int select(Space& home, ViewArray<View>& x, int* ties, int n);
242     //@}
243     /// \name Resource management and cloning
244     //@{
245     /// Whether dispose must always be called (that is, notice is needed)
246     virtual bool notice(void) const;
247     /// Delete view selection
248     virtual void dispose(Space& home);
249     //@}
250   };
251 
252 
253   /// Choose view according to merit taking tie-break limit into account
254   template<class Choose, class Merit>
255   class ViewSelChooseTbl : public ViewSelChoose<Choose,Merit> {
256   protected:
257     typedef typename ViewSelChoose<Choose,Merit>::Val Val;
258     typedef typename ViewSelChoose<Choose,Merit>::View View;
259     typedef typename ViewSelChoose<Choose,Merit>::Var Var;
260     using ViewSelChoose<Choose,Merit>::c;
261     using ViewSelChoose<Choose,Merit>::m;
262     /// Tie-break limit function
263     SharedData<BranchTbl> tbl;
264   public:
265     /// \name Initialization
266     //@{
267     /// Constructor for initialization
268     ViewSelChooseTbl(Space& home, const VarBranch<Var>& vb);
269     /// Constructor for copying during cloning
270     ViewSelChooseTbl(Space& home, ViewSelChooseTbl<Choose,Merit>& vs);
271     //@}
272     /// \name View selection and tie breaking
273     //@{
274     /// Select ties from \a x starting from \a s
275     virtual void ties(Space& home, ViewArray<View>& x, int s,
276                       int* ties, int& n);
277     /// Select ties from \a x starting from \a s
278     virtual void ties(Space& home, ViewArray<View>& x, int s,
279                       int* ties, int& n,
280                       BrancherFilter<View>& f);
281     /// Break ties in \a x and update to new ties
282     virtual void brk(Space& home, ViewArray<View>& x, int* ties, int& n);
283     //@}
284     /// \name Resource management and cloning
285     //@{
286     /// Whether dispose must always be called (that is, notice is needed)
287     virtual bool notice(void) const;
288     /// Delete view selection
289     virtual void dispose(Space& home);
290     //@}
291   };
292 
293   /// Select view with least merit
294   template<class Merit>
295   class ViewSelMin : public ViewSelChoose<ChooseMin,Merit> {
296     typedef typename ViewSelChoose<ChooseMin,Merit>::View View;
297     typedef typename ViewSelChoose<ChooseMin,Merit>::Var Var;
298   public:
299     /// \name Initialization
300     //@{
301     /// Constructor for initialization
302     ViewSelMin(Space& home, const VarBranch<Var>& vb);
303     /// Constructor for copying during cloning
304     ViewSelMin(Space& home, ViewSelMin<Merit>& vs);
305     //@}
306     /// \name Resource management and cloning
307     //@{
308     /// Create copy during cloning
309     virtual ViewSel<View>* copy(Space& home);
310     //@}
311   };
312 
313   /// Select view with least merit taking tie-break limit into account
314   template<class Merit>
315   class ViewSelMinTbl : public ViewSelChooseTbl<ChooseMin,Merit> {
316     typedef typename ViewSelChooseTbl<ChooseMin,Merit>::View View;
317     typedef typename ViewSelChooseTbl<ChooseMin,Merit>::Var Var;
318   public:
319     /// \name Initialization
320     //@{
321     /// Constructor for initialization
322     ViewSelMinTbl(Space& home, const VarBranch<Var>& vb);
323     /// Constructor for copying during cloning
324     ViewSelMinTbl(Space& home, ViewSelMinTbl<Merit>& vs);
325     //@}
326     /// \name Resource management and cloning
327     //@{
328     /// Create copy during cloning
329     virtual ViewSel<View>* copy(Space& home);
330     //@}
331   };
332 
333   /// Select view with largest merit
334   template<class Merit>
335   class ViewSelMax : public ViewSelChoose<ChooseMax,Merit> {
336     typedef typename ViewSelChoose<ChooseMax,Merit>::View View;
337     typedef typename ViewSelChoose<ChooseMax,Merit>::Var Var;
338   public:
339     /// \name Initialization
340     //@{
341     /// Constructor for initialization
342     ViewSelMax(Space& home, const VarBranch<Var>& vb);
343     /// Constructor for copying during cloning
344     ViewSelMax(Space& home, ViewSelMax<Merit>& vs);
345     //@}
346     /// \name Resource management and cloning
347     //@{
348     /// Create copy during cloning
349     virtual ViewSel<View>* copy(Space& home);
350     //@}
351   };
352 
353   /// Select view with largest merit taking tie-break limit into account
354   template<class Merit>
355   class ViewSelMaxTbl : public ViewSelChooseTbl<ChooseMax,Merit> {
356     typedef typename ViewSelChooseTbl<ChooseMax,Merit>::View View;
357     typedef typename ViewSelChooseTbl<ChooseMax,Merit>::Var Var;
358   public:
359     /// \name Initialization
360     //@{
361     /// Constructor for initialization
362     ViewSelMaxTbl(Space& home, const VarBranch<Var>& vb);
363     /// Constructor for copying during cloning
364     ViewSelMaxTbl(Space& home, ViewSelMaxTbl<Merit>& vs);
365     //@}
366     /// \name Resource management and cloning
367     //@{
368     /// Create copy during cloning
369     virtual ViewSel<View>* copy(Space& home);
370     //@}
371   };
372   //@}
373 
374 
375   template<class View>
376   forceinline
ViewSel(Space &,const VarBranch<Var> &)377   ViewSel<View>::ViewSel(Space&, const VarBranch<Var>&) {}
378   template<class View>
379   forceinline
ViewSel(Space &,ViewSel<View> &)380   ViewSel<View>::ViewSel(Space&, ViewSel<View>&) {}
381   template<class View>
382   int
select(Space &,ViewArray<View> &,int,BrancherNoFilter<View> &)383   ViewSel<View>::select(Space&, ViewArray<View>&, int,
384                         BrancherNoFilter<View>&) {
385     GECODE_NEVER;
386     return 0;
387   }
388   template<class View>
389   void
ties(Space &,ViewArray<View> &,int,int *,int &,BrancherNoFilter<View> &)390   ViewSel<View>::ties(Space&, ViewArray<View>&, int,
391                       int*, int&,
392                       BrancherNoFilter<View>&) {
393     GECODE_NEVER;
394   }
395   template<class View>
396   bool
notice(void) const397   ViewSel<View>::notice(void) const {
398     return false;
399   }
400   template<class View>
401   void
dispose(Space &)402   ViewSel<View>::dispose(Space&) {}
403   template<class View>
~ViewSel(void)404   ViewSel<View>::~ViewSel(void) {}
405   template<class View>
406   forceinline void
operator delete(void *)407   ViewSel<View>::operator delete(void*) {}
408   template<class View>
409   forceinline void
operator delete(void *,Space &)410   ViewSel<View>::operator delete(void*, Space&) {}
411   template<class View>
412   forceinline void*
operator new(size_t s,Space & home)413   ViewSel<View>::operator new(size_t s, Space& home) {
414     return home.ralloc(s);
415   }
416 
417 
418 
419   template<class View>
420   forceinline
ViewSelNone(Space & home,const VarBranch<Var> & vb)421   ViewSelNone<View>::ViewSelNone(Space& home, const VarBranch<Var>& vb)
422       : ViewSel<View>(home,vb) {}
423   template<class View>
424   forceinline
ViewSelNone(Space & home,ViewSelNone<View> & vs)425   ViewSelNone<View>::ViewSelNone(Space& home, ViewSelNone<View>& vs)
426     : ViewSel<View>(home,vs) {}
427   template<class View>
428   int
select(Space &,ViewArray<View> &,int s)429   ViewSelNone<View>::select(Space&, ViewArray<View>&, int s) {
430     return s;
431   }
432   template<class View>
433   int
select(Space &,ViewArray<View> &,int s,BrancherFilter<View> &)434   ViewSelNone<View>::select(Space&, ViewArray<View>&, int s,
435                             BrancherFilter<View>&) {
436     return s;
437   }
438   template<class View>
439   void
ties(Space &,ViewArray<View> & x,int s,int * ties,int & n)440   ViewSelNone<View>::ties(Space&, ViewArray<View>& x, int s,
441                           int* ties, int& n) {
442     int j=0; ties[j++]=s;
443     for (int i=s+1; i<x.size(); i++)
444       if (!x[i].assigned())
445         ties[j++]=i;
446     n=j;
447     assert(n > 0);
448   }
449   template<class View>
450   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n,BrancherFilter<View> & f)451   ViewSelNone<View>::ties(Space& home, ViewArray<View>& x, int s,
452                           int* ties, int& n,
453                           BrancherFilter<View>& f) {
454     int j=0; ties[j++]=s;
455     for (int i=s+1; i<x.size(); i++)
456       if (!x[i].assigned() && f(home,x[i],i))
457         ties[j++]=i;
458     n=j;
459     assert(n > 0);
460   }
461   template<class View>
462   void
brk(Space &,ViewArray<View> &,int *,int &)463   ViewSelNone<View>::brk(Space&, ViewArray<View>&, int*, int&) {
464     // Nothing needs to be done
465   }
466   template<class View>
467   int
select(Space &,ViewArray<View> &,int * ties,int)468   ViewSelNone<View>::select(Space&, ViewArray<View>&, int* ties, int) {
469     return ties[0];
470   }
471   template<class View>
472   ViewSel<View>*
copy(Space & home)473   ViewSelNone<View>::copy(Space& home) {
474     return new (home) ViewSelNone<View>(home,*this);
475   }
476 
477 
478   template<class View>
479   forceinline
ViewSelRnd(Space & home,const VarBranch<Var> & vb)480   ViewSelRnd<View>::ViewSelRnd(Space& home, const VarBranch<Var>& vb)
481       : ViewSel<View>(home,vb), r(vb.rnd()) {}
482   template<class View>
483   forceinline
ViewSelRnd(Space & home,ViewSelRnd<View> & vs)484   ViewSelRnd<View>::ViewSelRnd(Space& home, ViewSelRnd<View>& vs)
485       : ViewSel<View>(home,vs), r(vs.r) {}
486   template<class View>
487   int
select(Space &,ViewArray<View> & x,int s)488   ViewSelRnd<View>::select(Space&, ViewArray<View>& x, int s) {
489     unsigned int n=1;
490     int j=s;
491     for (int i=s+1; i<x.size(); i++)
492       if (!x[i].assigned()) {
493         n++;
494         if (r(n) == 0U)
495           j=i;
496       }
497     return j;
498   }
499   template<class View>
500   int
select(Space & home,ViewArray<View> & x,int s,BrancherFilter<View> & f)501   ViewSelRnd<View>::select(Space& home, ViewArray<View>& x, int s,
502                            BrancherFilter<View>& f) {
503     unsigned int n=1;
504     int j=s;
505     for (int i=s+1; i<x.size(); i++)
506       if (!x[i].assigned() && f(home,x[i],i)) {
507         n++;
508         if (r(n) == 0U)
509           j=i;
510       }
511     return j;
512   }
513   template<class View>
514   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n)515   ViewSelRnd<View>::ties(Space& home, ViewArray<View>& x, int s,
516                          int* ties, int& n) {
517     n=1; ties[0] = select(home,x,s);
518   }
519   template<class View>
520   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n,BrancherFilter<View> &)521   ViewSelRnd<View>::ties(Space& home, ViewArray<View>& x, int s,
522                          int* ties, int& n,
523                          BrancherFilter<View>&) {
524     n=1; ties[0] = select(home,x,s);
525   }
526   template<class View>
527   void
brk(Space &,ViewArray<View> &,int * ties,int & n)528   ViewSelRnd<View>::brk(Space&, ViewArray<View>&, int* ties, int& n) {
529     ties[0] = ties[static_cast<int>(r(static_cast<unsigned int>(n)))];
530     n=1;
531   }
532   template<class View>
533   int
select(Space &,ViewArray<View> &,int * ties,int n)534   ViewSelRnd<View>::select(Space&, ViewArray<View>&, int* ties, int n) {
535     return ties[static_cast<int>(r(static_cast<unsigned int>(n)))];
536   }
537   template<class View>
538   ViewSel<View>*
copy(Space & home)539   ViewSelRnd<View>::copy(Space& home) {
540     return new (home) ViewSelRnd<View>(home,*this);
541   }
542 
543 
544   template<class Val>
545   forceinline bool
operator ()(Val a,Val b) const546   ChooseMin::operator ()(Val a, Val b) const {
547     return a < b;
548   }
549   template<class Val>
550   forceinline bool
operator ()(Val a,Val b) const551   ChooseMax::operator ()(Val a, Val b) const {
552     return a > b;
553   }
554 
555 
556   template<class Choose, class Merit>
557   forceinline
ViewSelChoose(Space & home,const VarBranch<Var> & vb)558   ViewSelChoose<Choose,Merit>::ViewSelChoose(Space& home, const VarBranch<Var>& vb)
559     : ViewSel<View>(home,vb), m(home,vb) {}
560 
561   template<class Choose, class Merit>
562   forceinline
ViewSelChoose(Space & home,ViewSelChoose<Choose,Merit> & vs)563   ViewSelChoose<Choose,Merit>::ViewSelChoose(Space& home,
564                                              ViewSelChoose<Choose,Merit>& vs)
565     : ViewSel<View>(home,vs), m(home,vs.m) {}
566 
567   template<class Choose, class Merit>
568   int
select(Space & home,ViewArray<View> & x,int s)569   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x, int s) {
570     // Consider x[s] as the so-far best view
571     int b_i = s;
572     Val b_m = m(home,x[s],s);
573     // Scan all non-assigned views from s+1 onwards
574     for (int i=s+1; i<x.size(); i++)
575       if (!x[i].assigned()) {
576         Val mxi = m(home,x[i],i);
577         if (c(mxi,b_m)) {
578           b_i = i; b_m = mxi;
579         }
580       }
581     return b_i;
582   }
583 
584   template<class Choose, class Merit>
585   int
select(Space & home,ViewArray<View> & x,int s,BrancherFilter<View> & f)586   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x, int s,
587                                       BrancherFilter<View>& f) {
588     // Consider x[s] as the so-far best view
589     int b_i = s;
590     Val b_m = m(home,x[s],s);
591     // Scan all non-assigned views from s+1 onwards
592     for (int i=s+1; i<x.size(); i++)
593       if (!x[i].assigned() && f(home,x[i],i)) {
594         Val mxi = m(home,x[i],i);
595         if (c(mxi,b_m)) {
596           b_i = i; b_m = mxi;
597         }
598       }
599     return b_i;
600   }
601 
602   template<class Choose, class Merit>
603   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n)604   ViewSelChoose<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s,
605                                     int* ties, int& n) {
606     // Consider x[s] as the so-far best view and record as tie
607     Val b = m(home,x[s],s);
608     int j=0; ties[j++]=s;
609     for (int i=s+1; i<x.size(); i++)
610       if (!x[i].assigned()) {
611         Val mxi = m(home,x[i],i);
612         if (c(mxi,b)) {
613           // Found a better one, reset all ties and record
614           j=0; ties[j++]=i; b=mxi;
615         } else if (mxi == b) {
616           // Found a tie, record
617           ties[j++]=i;
618         }
619       }
620     n=j;
621     // There must be at least one tie, of course!
622     assert(n > 0);
623   }
624 
625   template<class Choose, class Merit>
626   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n,BrancherFilter<View> & f)627   ViewSelChoose<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s,
628                                     int* ties, int& n,
629                                     BrancherFilter<View>& f) {
630     // Consider x[s] as the so-far best view and record as tie
631     Val b = m(home,x[s],s);
632     int j=0; ties[j++]=s;
633     for (int i=s+1; i<x.size(); i++)
634       if (!x[i].assigned() && f(home,x[i],i)) {
635         Val mxi = m(home,x[i],i);
636         if (c(mxi,b)) {
637           // Found a better one, reset all ties and record
638           j=0; ties[j++]=i; b=mxi;
639         } else if (mxi == b) {
640           // Found a tie, record
641           ties[j++]=i;
642         }
643       }
644     n=j;
645     // There must be at least one tie, of course!
646     assert(n > 0);
647   }
648 
649   template<class Choose, class Merit>
650   void
brk(Space & home,ViewArray<View> & x,int * ties,int & n)651   ViewSelChoose<Choose,Merit>::brk(Space& home, ViewArray<View>& x,
652                                    int* ties, int& n) {
653     // Keep first tie in place
654     Val b = m(home,x[ties[0]],ties[0]);
655     int j=1;
656     // Scan remaining ties
657     for (int i=1; i<n; i++) {
658       Val mxi = m(home,x[ties[i]],ties[i]);
659       if (c(mxi,b)) {
660         // Found a better one, reset all ties
661         b=mxi; j=0; ties[j++]=ties[i];
662       } else if (mxi == b) {
663         // Found a tie and record it
664         ties[j++]=ties[i];
665       }
666     }
667     n=j;
668     // There must be at least one tie, of course!
669     assert(n > 0);
670   }
671 
672   template<class Choose, class Merit>
673   int
select(Space & home,ViewArray<View> & x,int * ties,int n)674   ViewSelChoose<Choose,Merit>::select(Space& home, ViewArray<View>& x,
675                                       int* ties, int n) {
676     int b_i = ties[0];
677     Val b_m = m(home,x[ties[0]],ties[0]);
678     for (int i=1; i<n; i++) {
679       Val mxi = m(home,x[ties[i]],ties[i]);
680       if (c(mxi,b_m)) {
681         b_i = ties[i]; b_m = mxi;
682       }
683     }
684     return b_i;
685   }
686 
687   template<class Choose, class Merit>
688   bool
notice(void) const689   ViewSelChoose<Choose,Merit>::notice(void) const {
690     return m.notice();
691   }
692 
693   template<class Choose, class Merit>
694   void
dispose(Space & home)695   ViewSelChoose<Choose,Merit>::dispose(Space& home) {
696     m.dispose(home);
697   }
698 
699 
700   template<class Choose, class Merit>
701   forceinline
ViewSelChooseTbl(Space & home,const VarBranch<Var> & vb)702   ViewSelChooseTbl<Choose,Merit>::ViewSelChooseTbl(Space& home,
703                                                    const VarBranch<Var>& vb)
704     : ViewSelChoose<Choose,Merit>(home,vb), tbl(vb.tbl()) {
705     if (!tbl())
706       throw InvalidFunction("ViewSelChooseTbl::ViewSelChooseTbl");
707   }
708 
709   template<class Choose, class Merit>
710   forceinline
ViewSelChooseTbl(Space & home,ViewSelChooseTbl<Choose,Merit> & vs)711   ViewSelChooseTbl<Choose,Merit>::ViewSelChooseTbl
712   (Space& home, ViewSelChooseTbl<Choose,Merit>& vs)
713     : ViewSelChoose<Choose,Merit>(home,vs), tbl(vs.tbl) {
714   }
715 
716   template<class Choose, class Merit>
717   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n)718   ViewSelChooseTbl<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s,
719                                        int* ties, int& n) {
720     // Find the worst and best merit value
721     Val w = m(home,x[s],s);
722     Val b = w;
723     for (int i=s+1; i<x.size(); i++)
724       if (!x[i].assigned()) {
725         Val mxi = m(home,x[i],i);
726         if (c(mxi,b))
727           b=mxi;
728         else if (c(w,mxi))
729           w=mxi;
730       }
731     // Compute tie-break limit
732     GECODE_VALID_FUNCTION(tbl());
733     double l = tbl()(home,static_cast<double>(w),static_cast<double>(b));
734     // If the limit is not better than the worst merit, everything is a tie
735     if (!c(l,static_cast<double>(w))) {
736       int j=0;
737       for (int i=s; i<x.size(); i++)
738         if (!x[i].assigned())
739           ties[j++]=i;
740       n=j;
741     } else {
742       // The limit is not allowed to better than the best merit value
743       if (c(l,static_cast<double>(b)))
744         l = static_cast<double>(b);
745       // Record all ties that are not worse than the limit merit value
746       int j=0;
747       for (int i=s; i<x.size(); i++)
748         if (!x[i].assigned() && !c(l,static_cast<double>(m(home,x[i],i))))
749           ties[j++]=i;
750       n=j;
751     }
752     // There will be at least one tie (the best will qualify, of course)
753     assert(n > 0);
754   }
755 
756   template<class Choose, class Merit>
757   void
ties(Space & home,ViewArray<View> & x,int s,int * ties,int & n,BrancherFilter<View> & f)758   ViewSelChooseTbl<Choose,Merit>::ties(Space& home, ViewArray<View>& x, int s,
759                                        int* ties, int& n,
760                                        BrancherFilter<View>& f) {
761     // Find the worst and best merit value
762     assert(f(home,x[s],s));
763     Val w = m(home,x[s],s);
764     Val b = w;
765     for (int i=s+1; i<x.size(); i++)
766       if (!x[i].assigned() && f(home,x[i],i)) {
767         Val mxi = m(home,x[i],i);
768         if (c(mxi,b))
769           b=mxi;
770         else if (c(w,mxi))
771           w=mxi;
772       }
773     // Compute tie-break limit
774     GECODE_VALID_FUNCTION(tbl());
775     double l = tbl()(home,static_cast<double>(w),static_cast<double>(b));
776     // If the limit is not better than the worst merit, everything is a tie
777     if (!c(l,static_cast<double>(w))) {
778       int j=0;
779       for (int i=s; i<x.size(); i++)
780         if (!x[i].assigned() && f(home,x[i],i))
781           ties[j++]=i;
782       n=j;
783     } else {
784       // The limit is not allowed to better than the best merit value
785       if (c(l,static_cast<double>(b)))
786         l = static_cast<double>(b);
787       // Record all ties that are not worse than the limit merit value
788       int j=0;
789       for (int i=s; i<x.size(); i++)
790         if (!x[i].assigned() && f(home,x[i],i) &&
791             !c(l,static_cast<double>(m(home,x[i],i))))
792           ties[j++]=i;
793       n=j;
794     }
795     // There will be at least one tie (the best will qualify, of course)
796     assert(n > 0);
797   }
798 
799   template<class Choose, class Merit>
800   void
brk(Space & home,ViewArray<View> & x,int * ties,int & n)801   ViewSelChooseTbl<Choose,Merit>::brk(Space& home, ViewArray<View>& x,
802                                       int* ties, int& n) {
803     // Find the worst and best merit value
804     Val w = m(home,x[ties[0]],ties[0]);
805     Val b = w;
806     for (int i=1; i<n; i++) {
807       Val mxi = m(home,x[ties[i]],ties[i]);
808       if (c(mxi,b))
809         b=mxi;
810       else if (c(w,mxi))
811         w=mxi;
812     }
813     // Compute tie-break limit
814     GECODE_VALID_FUNCTION(tbl());
815     double l = tbl()(home,static_cast<double>(w),static_cast<double>(b));
816     // If the limit is not better than the worst merit, everything is a tie
817     // and no breaking is required
818     if (c(l,static_cast<double>(w))) {
819       // The limit is not allowed to better than the best merit value
820       if (c(l,static_cast<double>(b)))
821         l = static_cast<double>(b);
822       // Keep all ties that are not worse than the limit merit value
823       int j=0;
824       for (int i=0; i<n; i++)
825         if (!c(l,static_cast<double>(m(home,x[ties[i]],ties[i]))))
826           ties[j++]=ties[i];
827       n=j;
828     }
829     // There will be at least one tie (the best will qualify)
830     assert(n > 0);
831   }
832   template<class Choose, class Merit>
833   bool
notice(void) const834   ViewSelChooseTbl<Choose,Merit>::notice(void) const {
835     return true;
836   }
837   template<class Choose, class Merit>
838   void
dispose(Space &)839   ViewSelChooseTbl<Choose,Merit>::dispose(Space&) {
840     tbl.~SharedData<BranchTbl>();
841   }
842 
843 
844 
845   template<class Merit>
846   forceinline
ViewSelMin(Space & home,const VarBranch<Var> & vb)847   ViewSelMin<Merit>::ViewSelMin(Space& home, const VarBranch<Var>& vb)
848     : ViewSelChoose<ChooseMin,Merit>(home,vb) {}
849 
850   template<class Merit>
851   forceinline
ViewSelMin(Space & home,ViewSelMin<Merit> & vs)852   ViewSelMin<Merit>::ViewSelMin(Space& home, ViewSelMin<Merit>& vs)
853     : ViewSelChoose<ChooseMin,Merit>(home,vs) {}
854 
855   template<class Merit>
856   ViewSel<typename ViewSelMin<Merit>::View>*
copy(Space & home)857   ViewSelMin<Merit>::copy(Space& home) {
858     return new (home) ViewSelMin<Merit>(home,*this);
859   }
860 
861 
862   template<class Merit>
863   forceinline
ViewSelMinTbl(Space & home,const VarBranch<Var> & vb)864   ViewSelMinTbl<Merit>::ViewSelMinTbl(Space& home, const VarBranch<Var>& vb)
865     : ViewSelChooseTbl<ChooseMin,Merit>(home,vb) {}
866 
867   template<class Merit>
868   forceinline
ViewSelMinTbl(Space & home,ViewSelMinTbl<Merit> & vs)869   ViewSelMinTbl<Merit>::ViewSelMinTbl(Space& home, ViewSelMinTbl<Merit>& vs)
870     : ViewSelChooseTbl<ChooseMin,Merit>(home,vs) {}
871 
872   template<class Merit>
873   ViewSel<typename ViewSelMinTbl<Merit>::View>*
copy(Space & home)874   ViewSelMinTbl<Merit>::copy(Space& home) {
875     return new (home) ViewSelMinTbl<Merit>(home,*this);
876   }
877 
878 
879 
880   template<class Merit>
881   forceinline
ViewSelMax(Space & home,const VarBranch<Var> & vb)882   ViewSelMax<Merit>::ViewSelMax(Space& home, const VarBranch<Var>& vb)
883     : ViewSelChoose<ChooseMax,Merit>(home,vb) {}
884 
885   template<class Merit>
886   forceinline
ViewSelMax(Space & home,ViewSelMax<Merit> & vs)887   ViewSelMax<Merit>::ViewSelMax(Space& home, ViewSelMax<Merit>& vs)
888     : ViewSelChoose<ChooseMax,Merit>(home,vs) {}
889 
890   template<class Merit>
891   ViewSel<typename ViewSelMax<Merit>::View>*
copy(Space & home)892   ViewSelMax<Merit>::copy(Space& home) {
893     return new (home) ViewSelMax<Merit>(home,*this);
894   }
895 
896 
897 
898   template<class Merit>
899   forceinline
ViewSelMaxTbl(Space & home,const VarBranch<Var> & vb)900   ViewSelMaxTbl<Merit>::ViewSelMaxTbl(Space& home, const VarBranch<Var>& vb)
901     : ViewSelChooseTbl<ChooseMax,Merit>(home,vb) {}
902 
903   template<class Merit>
904   forceinline
ViewSelMaxTbl(Space & home,ViewSelMaxTbl<Merit> & vs)905   ViewSelMaxTbl<Merit>::ViewSelMaxTbl(Space& home, ViewSelMaxTbl<Merit>& vs)
906     : ViewSelChooseTbl<ChooseMax,Merit>(home,vs) {}
907 
908   template<class Merit>
909   ViewSel<typename ViewSelMaxTbl<Merit>::View>*
copy(Space & home)910   ViewSelMaxTbl<Merit>::copy(Space& home) {
911     return new (home) ViewSelMaxTbl<Merit>(home,*this);
912   }
913 
914 
915 
916 }
917 
918 // STATISTICS: kernel-branch
919