this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 * Guido Tack <tack@gecode.org>
6 *
7 * Contributing authors:
8 * Kevin Leo <kevin.leo@monash.edu>
9 * Maxim Shishmarev <maxim.shishmarev@monash.edu>
10 *
11 * Copyright:
12 * Kevin Leo, 2017
13 * Christian Schulte, 2002
14 * Maxim Shishmarev, 2017
15 * Guido Tack, 2004
16 *
17 * This file is part of Gecode, the generic constraint
18 * development environment:
19 * http://www.gecode.org
20 *
21 * Permission is hereby granted, free of charge, to any person obtaining
22 * a copy of this software and associated documentation files (the
23 * "Software"), to deal in the Software without restriction, including
24 * without limitation the rights to use, copy, modify, merge, publish,
25 * distribute, sublicense, and/or sell copies of the Software, and to
26 * permit persons to whom the Software is furnished to do so, subject to
27 * the following conditions:
28 *
29 * The above copyright notice and this permission notice shall be
30 * included in all copies or substantial portions of the Software.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 *
40 */
41
42#ifndef GECODE_SEARCH_HH
43#define GECODE_SEARCH_HH
44
45#include <initializer_list>
46
47#include <gecode/kernel.hh>
48
49/*
50 * Configure linking
51 *
52 */
53#if !defined(GECODE_STATIC_LIBS) && \
54 (defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER))
55
56#ifdef GECODE_BUILD_SEARCH
57#define GECODE_SEARCH_EXPORT __declspec( dllexport )
58#else
59#define GECODE_SEARCH_EXPORT __declspec( dllimport )
60#endif
61
62#else
63
64#ifdef GECODE_GCC_HAS_CLASS_VISIBILITY
65#define GECODE_SEARCH_EXPORT __attribute__ ((visibility("default")))
66#else
67#define GECODE_SEARCH_EXPORT
68#endif
69
70#endif
71
72// Configure auto-linking
73#ifndef GECODE_BUILD_SEARCH
74#define GECODE_LIBRARY_NAME "Search"
75#include <gecode/support/auto-link.hpp>
76#endif
77
78
79namespace Gecode { namespace Search {
80
81 /// %Sequential search engine implementations
82 namespace Sequential {}
83
84 /// %Parallel search engine implementations
85 namespace Parallel {}
86
87 /// %Meta search engine implementations
88 namespace Meta {}
89
90 namespace Meta {
91
92 /// %Sequential meta search engine implementations
93 namespace Sequential {}
94
95 /// %Parallel meta search engine implementations
96 namespace Parallel {}
97
98 }
99
100
101 /**
102 * \brief %Search configuration
103 *
104 * \ingroup TaskModelSearch
105 */
106 namespace Config {
107 /// Whether engines create a clone when being initialized
108 const bool clone = true;
109 /// Number of threads to use
110 const double threads = 1.0;
111
112 /// Create a clone after every \a c_d commits (commit distance)
113 const unsigned int c_d = 8;
114 /// Create a clone during recomputation if distance is greater than \a a_d (adaptive distance)
115 const unsigned int a_d = 2;
116
117 /// Minimal number of open nodes for stealing
118 const unsigned int steal_limit = 3;
119 /// Initial delay in milliseconds for all but first worker thread
120 const unsigned int initial_delay = 5;
121
122 /// Default discrepancy limit for LDS
123 const unsigned int d_l = 5;
124
125 /// Base for geometric restart sequence
126 const double base = 1.5;
127 /// Size of a slice in a portfolio and scale factor for restarts(in number of failures)
128 const unsigned int slice = 250;
129
130 /// Depth limit for no-good generation during search
131 const unsigned int nogoods_limit = 128;
132
133 /// Default port for CPProfiler
134 const unsigned int cpprofiler_port = 6565U;
135 }
136
137}}
138
139#include <gecode/search/exception.hpp>
140
141namespace Gecode { namespace Search {
142
143 /**
144 * \brief %Search engine statistics
145 * \ingroup TaskModelSearch
146 */
147 class Statistics : public StatusStatistics {
148 public:
149 /// Number of failed nodes in search tree
150 unsigned long long int fail;
151 /// Number of nodes expanded
152 unsigned long long int node;
153 /// Maximum depth of search stack
154 unsigned long int depth;
155 /// Number of restarts
156 unsigned long int restart;
157 /// Number of no-goods posted
158 unsigned long int nogood;
159 /// Initialize
160 Statistics(void);
161 /// Reset
162 void reset(void);
163 /// Return sum with \a s
164 Statistics operator +(const Statistics& s);
165 /// Increment by statistics \a s
166 Statistics& operator +=(const Statistics& s);
167 };
168
169}}
170
171#include <gecode/search/statistics.hpp>
172
173namespace Gecode { namespace Search {
174
175 class WrapTraceRecorder;
176 class TraceRecorder;
177 class EdgeTraceRecorder;
178
179}}
180
181#include <string>
182#include <sstream>
183
184namespace Gecode {
185
186 /// Support for tracing search
187 class SearchTracer {
188 friend class Search::WrapTraceRecorder;
189 friend class Search::TraceRecorder;
190 friend class Search::EdgeTraceRecorder;
191 public:
192 /// Which type of engine
193 enum EngineType {
194 DFS = 0, ///< Engine is a DFS engine
195 BAB = 1, ///< Engine is a BAB engine
196 LDS = 2, ///< Engine is a LDS engine
197 RBS = 3, ///< Engine is a RBS engine
198 PBS = 4, ///< Engine is a PBS engine
199 AOE = 5 ///< Unspecified engine (any other engine)
200 };
201 /// Information about an engine
202 class EngineInfo {
203 protected:
204 /// The engine type
205 EngineType _type;
206 /// First worker or engine
207 unsigned int _fst;
208 /// Last worker or engine
209 unsigned int _lst;
210 public:
211 /// Do not initialize
212 EngineInfo(void);
213 /// Initialize
214 EngineInfo(EngineType et, unsigned int fst, unsigned int lst);
215 /// \name Engine type information
216 //@{
217 /// Return engine type
218 EngineType type(void) const;
219 /// Return whether engine is a meta engine
220 bool meta(void) const;
221 //@}
222 /// \name Information for basic (non-meta) engines
223 //@{
224 /// Return id of first worker
225 unsigned int wfst(void) const;
226 /// Return id of last worker plus one
227 unsigned int wlst(void) const;
228 /// Return number of workers
229 unsigned int workers(void) const;
230 //@}
231 /// \name Information for meta engines
232 //@{
233 /// Return id of first engine
234 unsigned int efst(void) const;
235 /// Return id of last engine
236 unsigned int elst(void) const;
237 /// Return number of engines
238 unsigned int engines(void) const;
239 //@}
240 };
241 /// Edge information
242 class EdgeInfo {
243 protected:
244 /// The parent worker id (edge does not exist if UINT_MAX)
245 unsigned int _wid;
246 /// The parent node id
247 unsigned int _nid;
248 /// Number of alternative
249 unsigned int _a;
250 /// String corresponding to alternative
251 std::string _s;
252 public:
253 /// Initialize
254 void init(unsigned int wid, unsigned int nid, unsigned int a);
255 /// Initialize
256 void init(unsigned int wid, unsigned int nid, unsigned int a,
257 const Space& s, const Choice & c);
258 /// Invalidate edge information (for stealing)
259 void invalidate(void);
260 /// Initialize as non existing
261 EdgeInfo(void);
262 /// Initialize
263 EdgeInfo(unsigned int wid, unsigned int nid, unsigned int a);
264 /// Test whether edge actually exists
265 operator bool(void) const;
266 /// Return parent worker id
267 unsigned int wid(void) const;
268 /// Return parent node id
269 unsigned int nid(void) const;
270 /// Return number of alternative
271 unsigned int alternative(void) const;
272 /// Return string for alternative
273 std::string string(void) const;
274 };
275 /// Node type
276 enum NodeType {
277 SOLVED = 0, /// A solution node
278 FAILED = 1, /// A failed node
279 BRANCH = 2 /// A branch node
280 };
281 /// Node information
282 class NodeInfo {
283 protected:
284 /// The node type
285 NodeType _nt;
286 /// The worker id
287 unsigned int _wid;
288 /// The node id
289 unsigned int _nid;
290 /// The corresponding space
291 const Space& _s;
292 /// The corresponding choice (nullptr if type is not BRANCH)
293 const Choice* _c;
294 public:
295 /// Initialize node info
296 NodeInfo(NodeType nt,
297 unsigned int wid, unsigned int nid,
298 const Space& s, const Choice* c = nullptr);
299 /// Return node type
300 NodeType type(void) const;
301 /// Return worker id
302 unsigned int wid(void) const;
303 /// Return node id
304 unsigned int nid(void) const;
305 /// Return corresponding space
306 const Space& space(void) const;
307 /// Return corresponding choice
308 const Choice& choice(void) const;
309 };
310 private:
311 /// Mutex for serialized access
312 Support::Mutex m;
313 /// Number of pending engine and workers calls
314 unsigned int pending;
315 /// Number of engines
316 unsigned int n_e;
317 /// Number of workers
318 unsigned int n_w;
319 /// Number of active workers (for termination)
320 unsigned int n_active;
321 /// The engines
322 Support::DynamicArray<EngineInfo,Heap> es;
323 /// Mapping of workers to engines
324 Support::DynamicArray<unsigned int,Heap> w2e;
325 /// Register new engine
326 void engine(EngineType t, unsigned int n);
327 /// Register new worker
328 void worker(unsigned int& wid, unsigned int& eid);
329 /// Deregister a worker
330 void worker(void);
331 /// \name Unsynchronized internal calls
332 //{@
333 /// The engine with id \a eid goes to a next round (restart or next iteration in LDS)
334 void _round(unsigned int eid);
335 /// The engine skips an edge
336 void _skip(const EdgeInfo& ei);
337 /// The engine creates a new node with information \a ei and \a ni
338 void _node(const EdgeInfo& ei, const NodeInfo& ni);
339 //@}
340 public:
341 /// Initialize
342 SearchTracer(void);
343 /// \name Engine information
344 //@{
345 /// Return number of workers
346 unsigned int workers(void) const;
347 /// Return number of engines
348 unsigned int engines(void) const;
349 /// Provide access to engine with id \a eid
350 const EngineInfo& engine(unsigned int eid) const;
351 /// Return the engine id of a worker with id \a wid
352 unsigned int eid(unsigned int wid) const;
353 //@}
354 /// \name Trace event functions
355 //@{
356 /// The search engine initializes
357 virtual void init(void) = 0;
358 /// The engine with id \a eid goes to a next round (restart or next iteration in LDS)
359 virtual void round(unsigned int eid) = 0;
360 /// The engine skips an edge
361 virtual void skip(const EdgeInfo& ei) = 0;
362 /// The engine creates a new node with information \a ei and \a ni
363 virtual void node(const EdgeInfo& ei, const NodeInfo& ni) = 0;
364 /// All workers are done
365 virtual void done(void) = 0;
366 //@}
367 /// Delete
368 virtual ~SearchTracer(void);
369 };
370
371 class GECODE_SEARCH_EXPORT StdSearchTracer : public SearchTracer {
372 protected:
373 /// Output stream to use
374 std::ostream& os;
375 /// Map engine type to string
376 static const char* t2s[EngineType::AOE + 1];
377 public:
378 /// Initialize with output stream \a os
379 StdSearchTracer(std::ostream& os = std::cerr);
380 /// The search engine initializes
381 virtual void init(void);
382 /// The engine with id \a eid goes to a next round (restart or next iteration in LDS)
383 virtual void round(unsigned int eid);
384 /// The engine skips an edge
385 virtual void skip(const EdgeInfo& ei);
386 /// The engine creates a new node with information \a ei and \a ni
387 virtual void node(const EdgeInfo& ei, const NodeInfo& ni);
388 /// All workers are done
389 virtual void done(void);
390 /// Delete
391 virtual ~StdSearchTracer(void);
392 /// Default tracer (printing to std::cerr)
393 static StdSearchTracer def;
394 };
395
396}
397
398#include <gecode/search/tracer.hpp>
399#include <gecode/search/trace-recorder.hpp>
400
401#ifdef GECODE_HAS_CPPROFILER
402
403namespace Gecode {
404
405 /// Code that is specific to the CPProfiler
406 namespace CPProfiler {}
407
408}
409
410namespace Gecode { namespace CPProfiler {
411
412 /// The actual connector to the CPProfiler
413 class Connector;
414
415}}
416
417namespace Gecode {
418
419 /// Class to record search trace info for CPProfiler
420 class GECODE_SEARCH_EXPORT CPProfilerSearchTracer : public SearchTracer {
421 public:
422 /// Class to send solution information to CPProfiler
423 class GECODE_SEARCH_EXPORT GetInfo : public HeapAllocated {
424 public:
425 /// Initialize
426 GetInfo(void);
427 /// Return info for a space
428 virtual std::string getInfo(const Space& home) const = 0;
429 /// Delete
430 virtual ~GetInfo(void);
431 };
432 private:
433 /// Connector to connect to running instnace of CPProfiler
434 CPProfiler::Connector* connector;
435 /// Execution id to be displayed by CPProfiler
436 int execution_id;
437 /// Name of script being traced
438 std::string name;
439 /// Number of the current restart
440 int restart;
441 /// Send solution information to CPProfiler
442 const GetInfo* pgi;
443 public:
444 /// Initialize
445 CPProfilerSearchTracer(int eid, std::string name,
446 unsigned int port = Search::Config::cpprofiler_port,
447 const GetInfo* pgi = nullptr);
448 /// The search engine initializes
449 virtual void init(void);
450 /// The engine with id \a eid goes to a next round (restart or next iteration in LDS)
451 virtual void round(unsigned int eid);
452 /// The engine skips an edge
453 virtual void skip(const EdgeInfo& ei);
454 /// The engine creates a new node with information \a ei and \a ni
455 virtual void node(const EdgeInfo& ei, const NodeInfo& ni);
456 /// All workers are done
457 virtual void done(void);
458 /// Delete
459 virtual ~CPProfilerSearchTracer(void);
460 };
461
462}
463
464#endif
465
466namespace Gecode { namespace Search {
467
468 /**
469 * \brief Base class for cutoff generators for restart-based meta engine
470 * \ingroup TaskModelSearch
471 */
472 class GECODE_SEARCH_EXPORT Cutoff : public HeapAllocated {
473 public:
474 /// \name Constructors and member functions
475 //@{
476 /// Default constructor
477 Cutoff(void);
478 /// Return the current cutoff value
479 virtual unsigned long long int operator ()(void) const = 0;
480 /// Increment and return the next cutoff value
481 virtual unsigned long long int operator ++(void) = 0;
482 /// Destructor
483 virtual ~Cutoff(void);
484 //@}
485 /// \name Predefined cutoff generators
486 //@{
487 /// Create generator for constant sequence with constant \a s
488 static Cutoff*
489 constant(unsigned long long int scale=Config::slice);
490 /// Create generator for linear sequence scaled by \a scale
491 static Cutoff*
492 linear(unsigned long long int scale=Config::slice);
493 /** Create generator for geometric sequence scaled by
494 * \a scale using base \a base
495 */
496 static Cutoff*
497 geometric(unsigned long long int scale=Config::slice,
498 double base=Config::base);
499 /// Create generator for luby sequence with scale-factor \a scale
500 static Cutoff*
501 luby(unsigned long long int scale=Config::slice);
502 /** Create generator for random sequence with seed \a seed that
503 * generates values between \a min and \a max with \a n steps
504 * between the extreme values.
505 */
506 static Cutoff*
507 rnd(unsigned int seed,
508 unsigned long long int min, unsigned long long int max,
509 unsigned long long int n);
510 /// Append cutoff values from \a c2 after \a n values from \a c1
511 static Cutoff*
512 append(Cutoff* c1, unsigned long long int n, Cutoff* c2);
513 /// Merge cutoff values from \a c1 with values from \a c2
514 static Cutoff*
515 merge(Cutoff* c1, Cutoff* c2);
516 /// Create generator that repeats \a n times each cutoff value from \a c
517 static Cutoff*
518 repeat(Cutoff* c, unsigned long long int n);
519 //@}
520 };
521
522 /**
523 * \brief Cutoff generator for constant sequence
524 * \ingroup TaskModelSearch
525 */
526 class GECODE_SEARCH_EXPORT CutoffConstant : public Cutoff {
527 protected:
528 /// Constant
529 unsigned long long int c;
530 public:
531 /// Constructor
532 CutoffConstant(unsigned long long int c);
533 /// Return the current cutoff value
534 virtual unsigned long long int operator ()(void) const;
535 /// Increment and return the next cutoff value
536 virtual unsigned long long int operator ++(void);
537 };
538
539 /**
540 * \brief Cutoff generator for linear sequence
541 * \ingroup TaskModelSearch
542 */
543 class GECODE_SEARCH_EXPORT CutoffLinear : public Cutoff {
544 protected:
545 /// Scale factor
546 unsigned long long int scale;
547 /// Next number in sequence
548 unsigned long long int n;
549 public:
550 /// Constructor
551 CutoffLinear(unsigned long long int scale);
552 /// Return the current cutoff value
553 virtual unsigned long long int operator ()(void) const;
554 /// Increment and return the next cutoff value
555 virtual unsigned long long int operator ++(void);
556 };
557
558 /**
559 * \brief Cutoff generator for the Luby sequence
560 * \ingroup TaskModelSearch
561 */
562 class GECODE_SEARCH_EXPORT CutoffLuby : public Cutoff {
563 protected:
564 /// Iteration number
565 unsigned long long int i;
566 /// Scale factor
567 unsigned long long int scale;
568 /// Number of pre-computed luby values
569 static const unsigned long long int n_start = 63U;
570 /// Precomputed luby-values
571 static unsigned long int start[n_start];
572 /// Compute binary logarithm of \a i
573 static unsigned long long int log(unsigned long long int i);
574 /// Compute Luby number for step \a i
575 static unsigned long long int luby(unsigned long long int i);
576 public:
577 /// Constructor
578 CutoffLuby(unsigned long long int scale);
579 /// Return the current cutoff value
580 virtual unsigned long long int operator ()(void) const;
581 /// Increment and return the next cutoff value
582 virtual unsigned long long int operator ++(void);
583 };
584
585 /**
586 * \brief Cutoff generator for the geometric sequence
587 * \ingroup TaskModelSearch
588 */
589 class GECODE_SEARCH_EXPORT CutoffGeometric : public Cutoff {
590 protected:
591 /// Current cutoff value
592 double n;
593 /// Scale factor
594 double scale;
595 /// Base
596 double base;
597 public:
598 /// Constructor
599 CutoffGeometric(unsigned long long int scale, double base);
600 /// Return the current cutoff value
601 virtual unsigned long long int operator ()(void) const;
602 /// Increment and return the next cutoff value
603 virtual unsigned long long int operator ++(void);
604 };
605
606 /**
607 * \brief Cutoff generator for the random sequence
608 * \ingroup TaskModelSearch
609 */
610 class GECODE_SEARCH_EXPORT CutoffRandom : public Cutoff {
611 protected:
612 /// Random number generator
613 Support::RandomGenerator rnd;
614 /// Minimum cutoff value
615 unsigned long long int min;
616 /// Random values
617 unsigned long long int n;
618 /// Step size
619 unsigned long long int step;
620 /// Current value
621 unsigned long long int cur;
622 public:
623 /// Constructor
624 CutoffRandom(unsigned int seed,
625 unsigned long long int min, unsigned long long int max,
626 unsigned long long int n);
627 /// Return the current cutoff value
628 virtual unsigned long long int operator ()(void) const;
629 /// Increment and return the next cutoff value
630 virtual unsigned long long int operator ++(void);
631 };
632
633 /**
634 * \brief Cutoff generator appending two cutoff generators
635 * \ingroup TaskModelSearch
636 */
637 class GECODE_SEARCH_EXPORT CutoffAppend : public Cutoff {
638 protected:
639 /// First cutoff generators
640 Cutoff* c1;
641 /// Second cutoff generators
642 Cutoff* c2;
643 /// How many number to take from the first
644 unsigned long long int n;
645 public:
646 /// Constructor
647 CutoffAppend(Cutoff* c1, unsigned long long int n, Cutoff* c2);
648 /// Return the current cutoff value
649 virtual unsigned long long int operator ()(void) const;
650 /// Increment and return the next cutoff value
651 virtual unsigned long long int operator ++(void);
652 /// Destructor
653 virtual ~CutoffAppend(void);
654 };
655
656 /**
657 * \brief Cutoff generator merging two cutoff generators
658 * \ingroup TaskModelSearch
659 */
660 class GECODE_SEARCH_EXPORT CutoffMerge : public Cutoff {
661 protected:
662 /// First cutoff generator
663 Cutoff* c1;
664 /// Second cutoff generator
665 Cutoff* c2;
666 public:
667 /// Constructor
668 CutoffMerge(Cutoff* c1, Cutoff* c2);
669 /// Return the current cutoff value
670 virtual unsigned long long int operator ()(void) const;
671 /// Increment and return the next cutoff value
672 virtual unsigned long long int operator ++(void);
673 /// Destructor
674 virtual ~CutoffMerge(void);
675 };
676
677 /**
678 * \brief Cutoff generator that repeats a cutoff from another cutoff generator
679 * \ingroup TaskModelSearch
680 */
681 class GECODE_SEARCH_EXPORT CutoffRepeat : public Cutoff {
682 protected:
683 /// Actual cutoff generator
684 Cutoff* c;
685 // Current cutoff
686 unsigned long long int cutoff;
687 // Iteration
688 unsigned long long int i;
689 // Number of repetitions
690 unsigned long long int n;
691 public:
692 /// Constructor
693 CutoffRepeat(Cutoff* c, unsigned long long int n);
694 /// Return the current cutoff value
695 virtual unsigned long long int operator ()(void) const;
696 /// Increment and return the next cutoff value
697 virtual unsigned long long int operator ++(void);
698 /// Destructor
699 virtual ~CutoffRepeat(void);
700 };
701
702}}
703
704#include <gecode/search/cutoff.hpp>
705
706namespace Gecode { namespace Search {
707
708 class Stop;
709
710 /**
711 * \brief %Search engine options
712 *
713 * Defines options for search engines. Not all search engines might
714 * honor all option values.
715 *
716 * - \a c_d as minimal recomputation distance: this guarantees that
717 * a path between two nodes in the search tree for which copies are
718 * stored has at least length \a c_d. That is, in order to recompute
719 * a node in the search tree, \a c_d recomputation steps are needed.
720 * The minimal recomputation distance yields a guarantee on saving
721 * memory compared to full copying: it stores \a c_d times less nodes
722 * than full copying.
723 * - \a a_d as adaptive recomputation distance: when a node needs to be
724 * recomputed and the path is longer than \a a_d, an intermediate copy
725 * is created (approximately in the middle of the path) to speed up
726 * future recomputation. Note that small values of \a a_d can increase
727 * the memory consumption considerably.
728 *
729 * Full copying corresponds to a maximal recomputation distance
730 * \a c_d of 1.
731 *
732 * All recomputation performed is based on batch recomputation: batch
733 * recomputation performs propagation only once for an entire path
734 * used in recomputation.
735 *
736 * The number of threads to be used is controlled by a double \f$n\f$
737 * (assume that \f$m\f$ is the number of processing units available). If
738 * \f$1 \leq n\f$, \f$n\f$ threads are chosen (of course with rounding).
739 * If \f$n \leq -1\f$, then \f$m + n\f$ threads are
740 * chosen (all but \f$-n\f$ processing units get a thread). If \f$n\f$
741 * is zero, \f$m\f$ threads are chosen. If \f$0<n<1\f$,
742 * \f$n \times m\f$ threads are chosen. If \f$-1 <n<0\f$,
743 * \f$(1+n)\times m\f$ threads are chosen.
744 *
745 * \ingroup TaskModelSearch
746 */
747 class Options {
748 public:
749 /// Whether engines create a clone when being initialized
750 bool clone;
751 /// Number of threads to use
752 double threads;
753 /// Create a clone after every \a c_d commits (commit distance)
754 unsigned int c_d;
755 /// Create a clone during recomputation if distance is greater than \a a_d (adaptive distance)
756 unsigned int a_d;
757 /// Discrepancy limit (for LDS)
758 unsigned int d_l;
759 /// Number of assets (engines) in a portfolio
760 unsigned int assets;
761 /// Size of a slice in a portfolio (in number of failures)
762 unsigned int slice;
763 /// Depth limit for extraction of no-goods
764 unsigned int nogoods_limit;
765 /// Stop object for stopping search
766 Stop* stop;
767 /// Cutoff for restart-based search
768 Cutoff* cutoff;
769 /// Tracer object for tracing search
770 SearchTracer* tracer;
771 /// Default options
772 GECODE_SEARCH_EXPORT static const Options def;
773 /// Initialize with default values
774 Options(void);
775 /// Expand with real number of threads
776 GECODE_SEARCH_EXPORT Options
777 expand(void) const;
778 };
779
780}}
781
782#include <gecode/search/options.hpp>
783
784namespace Gecode { namespace Search {
785
786 /**
787 * \defgroup TaskModelSearchStop Stop-objects for stopping search
788 * \ingroup TaskModelSearch
789 *
790 * Allows to specify various criteria when a search engine should
791 * stop exploration. Only exploration but neither recomputation
792 * nor propagation will be interrupted.
793 *
794 */
795
796 /**
797 * \brief Base-class for %Stop-object
798 * \ingroup TaskModelSearchStop
799 */
800 class GECODE_SEARCH_EXPORT Stop : public HeapAllocated {
801 public:
802 /// \name Constructors and member functions
803 //@{
804 /// Default constructor
805 Stop(void);
806 /// Stop search, if returns true
807 virtual bool stop(const Statistics& s, const Options& o) = 0;
808 /// Destructor
809 virtual ~Stop(void);
810 //@}
811 /// \name Predefined stop objects
812 //@{
813 /// Stop if node limit \a l has been exceeded
814 static Stop* node(unsigned long long int l);
815 /// Stop if failure limit \a l has been exceeded
816 static Stop* fail(unsigned long long int l);
817 /// Stop if time limit \a l (in milliseconds) has been exceeded
818 static Stop* time(double l);
819 //@}
820 };
821
822 /**
823 * \brief %Stop-object based on number of nodes
824 *
825 * The number of nodes reported (by the statistics) is the
826 * number since the engine started exploration. It is not the
827 * number since the last stop!
828 * \ingroup TaskModelSearchStop
829 */
830 class GECODE_SEARCH_EXPORT NodeStop : public Stop {
831 protected:
832 /// Node limit
833 unsigned long long int l;
834 public:
835 /// Stop if node limit \a l is exceeded
836 NodeStop(unsigned long long int l);
837 /// Return current limit
838 unsigned long long int limit(void) const;
839 /// Set current limit to \a l nodes
840 void limit(unsigned long long int l);
841 /// Return true if node limit is exceeded
842 virtual bool stop(const Statistics& s, const Options& o);
843 };
844
845 /**
846 * \brief %Stop-object based on number of failures
847 *
848 * The number of failures reported (by the statistics) is the
849 * number since the engine started exploration. It is not the
850 * number since the last stop!
851 * \ingroup TaskModelSearchStop
852 */
853 class GECODE_SEARCH_EXPORT FailStop : public Stop {
854 protected:
855 /// Failure limit
856 unsigned long long int l;
857 public:
858 /// Stop if failure limit \a l is exceeded
859 FailStop(unsigned long long int l);
860 /// Return current limit
861 unsigned long long int limit(void) const;
862 /// Set current limit to \a l failures
863 void limit(unsigned long long int l);
864 /// Return true if failure limit is exceeded
865 virtual bool stop(const Statistics& s, const Options& o);
866 };
867
868 /**
869 * \brief %Stop-object based on time
870 * \ingroup TaskModelSearchStop
871 */
872 class GECODE_SEARCH_EXPORT TimeStop : public Stop {
873 protected:
874 /// Time when execution should stop
875 Support::Timer t;
876 /// Current limit in milliseconds
877 double l;
878 public:
879 /// Stop if search exceeds \a l milliseconds (from creation of this object)
880 TimeStop(double l);
881 /// Return current limit in milliseconds
882 double limit(void) const;
883 /// Set current limit to \a l milliseconds
884 void limit(double l);
885 /// Reset time to zero
886 void reset(void);
887 /// Return true if time limit is exceeded
888 virtual bool stop(const Statistics& s, const Options& o);
889 };
890
891}}
892
893#include <gecode/search/stop.hpp>
894
895namespace Gecode { namespace Search {
896
897 /**
898 * \brief %Search engine implementation interface
899 */
900 class GECODE_SEARCH_EXPORT Engine : public HeapAllocated {
901 public:
902 /// Return next solution (nullptr, if none exists or search has been stopped)
903 virtual Space* next(void) = 0;
904 /// Return statistics
905 virtual Statistics statistics(void) const = 0;
906 /// Check whether engine has been stopped
907 virtual bool stopped(void) const = 0;
908 /// Constrain future solutions to be better than \a b (raises exception)
909 virtual void constrain(const Space& b);
910 /// Reset engine to restart at space \a s (does nothing)
911 virtual void reset(Space* s);
912 /// Return no-goods (the no-goods are empty)
913 virtual NoGoods& nogoods(void);
914 /// Destructor
915 virtual ~Engine(void);
916 };
917
918}}
919
920#include <gecode/search/engine.hpp>
921
922namespace Gecode { namespace Search {
923
924 /// Base-class for search engines
925 template<class T>
926 class Base : public HeapAllocated {
927 template<class, class>
928 friend Engine* build(Space*, const Options&);
929 template<class, template<class> class>
930 friend Engine* build(Space*, const Options&);
931 protected:
932 /// The actual search engine
933 Engine* e;
934 /// Constructor
935 Base(Engine* e = nullptr);
936 public:
937 /// Return next solution (nullptr, if none exists or search has been stopped)
938 virtual T* next(void);
939 /// Return statistics
940 virtual Statistics statistics(void) const;
941 /// Check whether engine has been stopped
942 virtual bool stopped(void) const;
943 /// Destructor
944 virtual ~Base(void);
945 private:
946 /// Disallow copy constructor
947 Base(const Base&);
948 /// Disallow assigment operator
949 Base& operator =(const Base&);
950 };
951
952}}
953
954#include <gecode/search/base.hpp>
955
956namespace Gecode { namespace Search {
957
958 /// Build an engine of type \a E for a script \a T
959 template<class T, class E>
960 Engine* build(Space* s, const Options& opt);
961 /// Build a parametric engine of type \a E for a script \a T
962 template<class T, template<class> class E>
963 Engine* build(Space* s, const Options& opt);
964
965 /// A class for building search engines
966 class GECODE_SEARCH_EXPORT Builder : public HeapAllocated {
967 protected:
968 /// Stored and already expanded options
969 Options opt;
970 /// Whether engine to be built is a best solution search engine
971 const bool b;
972 public:
973 /// Initialize with options \a opt and \a best solution search support
974 Builder(const Options& opt, bool best);
975 /// Provide access to options
976 Options& options(void);
977 /// Provide access to options
978 const Options& options(void) const;
979 /// Whether engine is a best solution search engine
980 bool best(void) const;
981 /// Build an engine according to stored options for \a s
982 virtual Engine* operator() (Space* s) const = 0;
983 /// Destructor
984 virtual ~Builder(void);
985 };
986
987}}
988
989#include <gecode/search/build.hpp>
990
991namespace Gecode {
992
993 /// Type for a search engine builder
994 typedef Search::Builder* SEB;
995
996}
997
998#include <gecode/search/traits.hpp>
999
1000namespace Gecode {
1001
1002 /// Passing search engine builder arguments
1003 class SEBs : public ArgArray<SEB> {
1004 public:
1005 /// \name Constructors and initialization
1006 //@{
1007 /// Allocate empty array
1008 SEBs(void);
1009 /// Allocate array with \a n elements
1010 explicit SEBs(int n);
1011 /// Allocate array and copy elements from \a x
1012 SEBs(const std::vector<SEB>& x);
1013 /// Allocate array with and initialize with \a x
1014 SEBs(std::initializer_list<SEB> x);
1015 /// Allocate array and copy elements from \a first to \a last
1016 template<class InputIterator>
1017 SEBs(InputIterator first, InputIterator last);
1018 /// Initialize from primitive argument array \a a (copy elements)
1019 SEBs(const ArgArray<SEB>& a);
1020 //@}
1021 };
1022
1023}
1024
1025#include <gecode/search/sebs.hpp>
1026
1027namespace Gecode {
1028
1029 /**
1030 * \brief Depth-first search engine
1031 *
1032 * This class supports depth-first search for subclasses \a T of
1033 * Space.
1034 * \ingroup TaskModelSearch
1035 */
1036 template<class T>
1037 class DFS : public Search::Base<T> {
1038 public:
1039 /// Initialize search engine for space \a s with options \a o
1040 DFS(T* s, const Search::Options& o=Search::Options::def);
1041 /// Whether engine does best solution search
1042 static const bool best = false;
1043 };
1044
1045 /// Invoke depth-first search engine for subclass \a T of space \a s with options \a o
1046 template<class T>
1047 T* dfs(T* s, const Search::Options& o=Search::Options::def);
1048
1049 /// Return a depth-first search engine builder
1050 template<class T>
1051 SEB dfs(const Search::Options& o=Search::Options::def);
1052
1053}
1054
1055#include <gecode/search/dfs.hpp>
1056
1057namespace Gecode {
1058
1059 /**
1060 * \brief Depth-first branch-and-bound search engine
1061 *
1062 * Additionally, \a s must implement a member function
1063 * \code virtual void constrain(const T& t) \endcode
1064 * Whenever exploration requires to add a constraint
1065 * to the space \a c currently being explored, the engine
1066 * executes \c c.constrain(t) where \a t is the so-far
1067 * best solution.
1068 * \ingroup TaskModelSearch
1069 */
1070 template<class T>
1071 class BAB : public Search::Base<T> {
1072 public:
1073 /// Initialize engine for space \a s and options \a o
1074 BAB(T* s, const Search::Options& o=Search::Options::def);
1075 /// Whether engine does best solution search
1076 static const bool best = true;
1077 };
1078
1079 /**
1080 * \brief Perform depth-first branch-and-bound search for subclass \a T of space \a s and options \a o
1081 *
1082 * Additionally, \a s must implement a member function
1083 * \code virtual void constrain(const T& t) \endcode
1084 * Whenever exploration requires to add a constraint
1085 * to the space \a c currently being explored, the engine
1086 * executes \c c.constrain(t) where \a t is the so-far
1087 * best solution.
1088 *
1089 * \ingroup TaskModelSearch
1090 */
1091 template<class T>
1092 T* bab(T* s, const Search::Options& o=Search::Options::def);
1093
1094 /// Return a depth-first branch-and-bound search engine builder
1095 template<class T>
1096 SEB bab(const Search::Options& o=Search::Options::def);
1097
1098}
1099
1100#include <gecode/search/bab.hpp>
1101
1102namespace Gecode {
1103
1104 /**
1105 * \brief Limited discrepancy search engine
1106 * \ingroup TaskModelSearch
1107 */
1108 template<class T>
1109 class LDS : public Search::Base<T> {
1110 public:
1111 /// Initialize engine for space \a s and options \a o
1112 LDS(T* s, const Search::Options& o=Search::Options::def);
1113 /// Whether engine does best solution search
1114 static const bool best = false;
1115 };
1116
1117 /**
1118 * \brief Invoke limited-discrepancy search for \a s as root node and options\a o
1119 * \ingroup TaskModelSearch
1120 */
1121 template<class T>
1122 T* lds(T* s, const Search::Options& o=Search::Options::def);
1123
1124 /// Return a limited discrepancy search engine builder
1125 template<class T>
1126 SEB lds(const Search::Options& o=Search::Options::def);
1127
1128}
1129
1130#include <gecode/search/lds.hpp>
1131
1132namespace Gecode {
1133
1134 /**
1135 * \brief Meta-engine performing restart-based search
1136 *
1137 * The engine uses the Cutoff sequence supplied in the options \a o to
1138 * periodically restart the search of engine \a E.
1139 *
1140 * The class \a T can implement member functions
1141 * \code virtual bool master(const MetaInfo& mi) \endcode
1142 * and
1143 * \code virtual bool slave(const MetaInfo& mi) \endcode
1144 *
1145 * Whenever exploration restarts or a solution is found, the
1146 * engine executes the functions on the master and slave
1147 * space. For more details, consult "Modeling and Programming
1148 * with Gecode".
1149 *
1150 * \ingroup TaskModelSearch
1151 */
1152 template<class T, template<class> class E = DFS>
1153 class RBS : public Search::Base<T> {
1154 using Search::Base<T>::e;
1155 public:
1156 /// Initialize engine for space \a s and options \a o
1157 RBS(T* s, const Search::Options& o);
1158 /// Whether engine does best solution search
1159 static const bool best = E<T>::best;
1160 };
1161
1162 /**
1163 * \brief Perform restart-based search
1164 *
1165 * The engine uses the Cutoff sequence supplied in the options \a o to
1166 * periodically restart the search of engine \a E.
1167 *
1168 * The class \a T can implement member functions
1169 * \code virtual bool master(const MetaInfo& mi) \endcode
1170 * and
1171 * \code virtual bool slave(const MetaInfo& mi) \endcode
1172 *
1173 * Whenever exploration restarts or a solution is found, the
1174 * engine executes the functions on the master and slave
1175 * space. For more details, consult "Modeling and Programming
1176 * with Gecode".
1177 *
1178 * \ingroup TaskModelSearch
1179 */
1180 template<class T, template<class> class E>
1181 T* rbs(T* s, const Search::Options& o);
1182
1183 /// Return a restart search engine builder
1184 template<class T, template<class> class E>
1185 SEB rbs(const Search::Options& o);
1186
1187}
1188
1189#include <gecode/search/rbs.hpp>
1190
1191namespace Gecode { namespace Search { namespace Meta {
1192
1193 /// Build a sequential engine
1194 template<class T, template<class> class E>
1195 Engine* sequential(T* master, const Search::Statistics& stat, Options& opt);
1196
1197 /// Build a sequential engine
1198 template<class T, template<class> class E>
1199 Engine* sequential(T* master, SEBs& sebs,
1200 const Search::Statistics& stat, Options& opt, bool best);
1201
1202#ifdef GECODE_HAS_THREADS
1203
1204 /// Build a parallel engine
1205 template<class T, template<class> class E>
1206 Engine* parallel(T* master, const Search::Statistics& stat, Options& opt);
1207
1208 /// Build a parallel engine
1209 template<class T, template<class> class E>
1210 Engine* parallel(T* master, SEBs& sebs,
1211 const Search::Statistics& stat, Options& opt, bool best);
1212
1213#endif
1214
1215}}}
1216
1217namespace Gecode {
1218
1219 /**
1220 * \brief Meta engine using a portfolio of search engines
1221 *
1222 * The engine will run a portfolio with a number of assets as defined
1223 * by the options \a o. The engine supports parallel execution of
1224 * assets by using the number of threads as defined by the options.
1225 *
1226 * The class \a T can implement member functions
1227 * \code virtual bool master(const MetaInfo& mi) \endcode
1228 * and
1229 * \code virtual bool slave(const MetaInfo& mi) \endcode
1230 *
1231 * When the assets are created, these functions are executed.
1232 * For more details, consult "Modeling and Programming with Gecode".
1233 *
1234 * \ingroup TaskModelSearch
1235 */
1236 template<class T, template<class> class E = DFS>
1237 class PBS : public Search::Base<T> {
1238 using Search::Base<T>::e;
1239 protected:
1240 /// The actual build function
1241 void build(T* s, SEBs& sebs, const Search::Options& o);
1242 public:
1243 /// Initialize with engines running copies of \a s with options \a o
1244 PBS(T* s, const Search::Options& o=Search::Options::def);
1245 /// Initialize with engine builders \a sebs
1246 PBS(T* s, SEBs& sebs, const Search::Options& o=Search::Options::def);
1247 /// Whether engine does best solution search
1248 static const bool best = E<T>::best;
1249 };
1250
1251 /**
1252 * \brief Run a portfolio of search engines
1253 *
1254 * The engine will run a portfolio with a number of assets as defined
1255 * by the options \a o. The engine supports parallel execution of
1256 * assets by using the number of threads as defined by the options.
1257 *
1258 * The class \a T can implement member functions
1259 * \code virtual bool master(const MetaInfo& mi) \endcode
1260 * and
1261 * \code virtual bool slave(const MetaInfo& mi) \endcode
1262 *
1263 * When the assets are created, these functions are executed.
1264 * For more details, consult "Modeling and Programming with Gecode".
1265 *
1266 * \ingroup TaskModelSearch
1267 */
1268 template<class T, template<class> class E>
1269 T* pbs(T* s, const Search::Options& o=Search::Options::def);
1270
1271 /// Return a portfolio search engine builder
1272 template<class T>
1273 SEB pbs(const Search::Options& o=Search::Options::def);
1274
1275}
1276
1277#include <gecode/search/pbs.hpp>
1278
1279#endif
1280
1281// STATISTICS: search-other