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