Skip to content

Commit c7962c6

Browse files
author
Christian Schulte
committed
Added relaxation abstraction for LNS
git-svn-id: file:///Volumes/GecodeGitMigration/gecode-svn-mirror/gecode/trunk@15218 e85b7adc-8362-4630-8c63-7469d557c915
1 parent 844eee5 commit c7962c6

15 files changed

Lines changed: 1613 additions & 126 deletions

File tree

Makefile.dep

Lines changed: 1083 additions & 114 deletions
Large diffs are not rendered by default.

Makefile.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ SEARCHHDR0 = \
267267
meta/rbs.hh meta/rbs.hpp meta/nogoods.hh meta/dead.hh \
268268
meta/sequential/pbs.hh meta/parallel/pbs.hh \
269269
meta/sequential/pbs.hpp meta/parallel/pbs.hpp \
270-
dfs.hpp bab.hpp lds.hpp rbs.hpp pbs.hpp
270+
dfs.hpp bab.hpp lds.hpp rbs.hpp pbs.hpp \
271+
relax.hh
271272

272273
SEARCHSRC = $(SEARCHSRC0:%=gecode/search/%.cpp)
273274
SEARCHHDR = gecode/search.hh $(SEARCHHDR0:%=gecode/search/%)
@@ -328,6 +329,7 @@ INTSRC0 = \
328329
arithmetic/mult.cpp \
329330
branch/view-sel.cpp branch/val-sel-commit.cpp \
330331
branch/view-values.cpp \
332+
relax.cpp \
331333
ldsb.cpp ldsb/sym-imp.cpp ldsb/sym-obj.cpp \
332334
trace.cpp trace/tracer.cpp \
333335
exception.cpp
@@ -465,6 +467,7 @@ FLOATSRC0 = \
465467
var/float.cpp arithmetic.cpp array.cpp branch.cpp rel.cpp linear.cpp \
466468
linear/post.cpp branch/activity.cpp rounding.cpp exec.cpp \
467469
branch/val-sel-commit.cpp branch/view-sel.cpp dom.cpp \
470+
relax.cpp \
468471
trace.cpp trace/tracer.cpp \
469472
exception.cpp
470473

@@ -545,6 +548,7 @@ SETSRC0 = \
545548
exec.cpp branch/activity.cpp branch/view-sel.cpp \
546549
branch/val-sel-commit.cpp branch/ngl.cpp \
547550
ldsb.cpp ldsb/sym-imp.cpp \
551+
relax.cpp \
548552
trace.cpp trace/tracer.cpp \
549553
exception.cpp
550554
SETHDR0 = \

changelog.in

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,38 @@ Date: 2015-?-?
7272
[DESCRIPTION]
7373
Gaga
7474

75+
[ENTRY]
76+
Module: float
77+
What: new
78+
Rank: minor
79+
[DESCRIPTION]
80+
Added relax() function for relaxed assignment of float variables
81+
from a previous solution, see MPG for details.
82+
83+
[ENTRY]
84+
Module: set
85+
What: new
86+
Rank: minor
87+
[DESCRIPTION]
88+
Added relax() function for relaxed assignment of set variables
89+
from a previous solution, see MPG for details.
90+
91+
[ENTRY]
92+
Module: int
93+
What: new
94+
Rank: minor
95+
[DESCRIPTION]
96+
Added relax() function for relaxed assignment of integer and
97+
Boolean variables from a previous solution, see MPG for details.
98+
99+
[ENTRY]
100+
Module: driver
101+
What: new
102+
Rank: minor
103+
[DESCRIPTION]
104+
The probability for relaxing variables in LNS can be passed with
105+
the -relax commandline option.
106+
75107
[ENTRY]
76108
Module: int
77109
What: bug

examples/photo.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
using namespace Gecode;
4343

44+
4445
/// Specifications for the photo example
4546
class PhotoSpec {
4647
public:
@@ -82,10 +83,13 @@ class Photo : public IntMinimizeScript {
8283
/// Photo specification
8384
const PhotoSpec& spec;
8485
/// Person's position on photo
85-
IntVarArray pos;
86+
IntVarArray pos;
8687
/// Number of violated preferences
87-
IntVar violations;
88-
88+
IntVar violations;
89+
/// Random number generator for LNS
90+
Rnd rnd;
91+
/// Relaxation probability
92+
double p;
8993
public:
9094
/// Branching to use for model
9195
enum {
@@ -97,7 +101,8 @@ class Photo : public IntMinimizeScript {
97101
IntMinimizeScript(opt),
98102
spec(opt.size() == 0 ? p_small : p_large),
99103
pos(*this,spec.n_names, 0, spec.n_names-1),
100-
violations(*this,0,spec.n_prefs)
104+
violations(*this,0,spec.n_prefs),
105+
rnd(opt.seed()), p(opt.relax())
101106
{
102107
// Map preferences to violation
103108
BoolVarArgs viol(spec.n_prefs);
@@ -120,10 +125,20 @@ class Photo : public IntMinimizeScript {
120125
INT_VAL_MIN());
121126
}
122127
}
123-
128+
/// Slave function for restarts
129+
bool slave(const MetaInfo& mi) {
130+
if ((mi.type() == MetaInfo::RESTART) &&
131+
(mi.restart() > 0) && (p > 0.0)) {
132+
const Photo& l = static_cast<const Photo&>(*mi.last());
133+
relax(*this, pos, l.pos, rnd, p);
134+
return false;
135+
} else {
136+
return true;
137+
}
138+
}
124139
/// Constructor for cloning \a s
125140
Photo(bool share, Photo& s) :
126-
IntMinimizeScript(share,s), spec(s.spec) {
141+
IntMinimizeScript(share,s), spec(s.spec), rnd(s.rnd), p(s.p) {
127142
pos.update(*this, share, s.pos);
128143
violations.update(*this, share, s.violations);
129144
}
@@ -154,6 +169,7 @@ main(int argc, char* argv[]) {
154169
opt.size(1);
155170
opt.iterations(10);
156171
opt.ipl(IPL_BND);
172+
opt.relax(0.7);
157173
opt.branching(Photo::BRANCH_DEGREE);
158174
opt.branching(Photo::BRANCH_NONE, "none");
159175
opt.branching(Photo::BRANCH_DEGREE, "degree");
@@ -162,6 +178,5 @@ main(int argc, char* argv[]) {
162178
return 0;
163179
}
164180

165-
166181
// STATISTICS: example-any
167182

gecode/driver.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ namespace Gecode {
395395
Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
396396
Driver::BoolOption _nogoods; ///< Whether to use no-goods
397397
Driver::UnsignedIntOption _nogoods_limit; ///< Limit for no-good extraction
398+
Driver::DoubleOption _relax; ///< Probability to relax variable
398399
Driver::BoolOption _interrupt; ///< Whether to catch SIGINT
399400
//@}
400401

@@ -548,6 +549,11 @@ namespace Gecode {
548549
/// Return depth limit for nogoods
549550
unsigned int nogoods_limit(void) const;
550551

552+
/// Set default relax probability
553+
void relax(double d);
554+
/// Return default relax probability
555+
double relax(void) const;
556+
551557
/// Set default interrupt behavior
552558
void interrupt(bool b);
553559
/// Return interrupt behavior

gecode/driver/options.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ namespace Gecode {
533533
_nogoods("-nogoods","whether to use no-goods from restarts",false),
534534
_nogoods_limit("-nogoods-limit","depth limit for no-good extraction",
535535
Search::Config::nogoods_limit),
536+
_relax("-relax","probability for relaxing variable", 0.0),
536537
_interrupt("-interrupt","whether to catch Ctrl-C (true) or not (false)",
537538
true),
538539

@@ -568,6 +569,7 @@ namespace Gecode {
568569
add(_assets); add(_slice);
569570
add(_restart); add(_r_base); add(_r_scale);
570571
add(_nogoods); add(_nogoods_limit);
572+
add(_relax);
571573
add(_mode); add(_iterations); add(_samples); add(_print_last);
572574
add(_out_file); add(_log_file); add(_trace);
573575
}

gecode/driver/options.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,15 @@ namespace Gecode {
418418
return _nogoods_limit.value();
419419
}
420420

421+
inline void
422+
Options::relax(double d) {
423+
_relax.value(d);
424+
}
425+
inline double
426+
Options::relax(void) const {
427+
return _relax.value();
428+
}
429+
421430

422431

423432
inline void

gecode/float.hh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,6 +1814,34 @@ namespace Gecode {
18141814

18151815
}
18161816

1817+
namespace Gecode {
1818+
1819+
/*
1820+
* \brief Relaxed assignment of variables in \a x from values in \a sx
1821+
*
1822+
* The variables in \a x are assigned values from the assigned variables
1823+
* in the solution \a sx with a relaxation probability \a p. That is,
1824+
* if \$fp=0.1\f$ approximately 10% of the variables in \a x will be
1825+
* assigned a value from \a sx.
1826+
*
1827+
* The random numbers are generated from the generator \a r. At least
1828+
* one variable will not be assigned: in case the relaxation attempt
1829+
* would suggest that all variables should be assigned, a single
1830+
* variable will be selected randomly to remain unassigned.
1831+
*
1832+
* Throws an exception of type Float::ArgumentSizeMismatch, if \a x and
1833+
* \a sx are of different size.
1834+
*
1835+
* Throws an exception of type Float::OutOfLimits, if \a p is not between
1836+
* \a 0.0 and \a 1.0.
1837+
*
1838+
* \ingroup TaskModeFloat
1839+
*/
1840+
GECODE_FLOAT_EXPORT void
1841+
relax(Home home, const FloatVarArgs& x, const FloatVarArgs& sx,
1842+
Rnd r, double p);
1843+
1844+
}
18171845

18181846
#include <gecode/float/trace/trace-view.hpp>
18191847

gecode/float/relax.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2+
/*
3+
* Main authors:
4+
* Christian Schulte <schulte@gecode.org>
5+
*
6+
* Copyright:
7+
* Christian Schulte, 2016
8+
*
9+
* Last modified:
10+
* $Date$ by $Author$
11+
* $Revision$
12+
*
13+
* This file is part of Gecode, the generic constraint
14+
* development environment:
15+
* http://www.gecode.org
16+
*
17+
* Permission is hereby granted, free of charge, to any person obtaining
18+
* a copy of this software and associated documentation files (the
19+
* "Software"), to deal in the Software without restriction, including
20+
* without limitation the rights to use, copy, modify, merge, publish,
21+
* distribute, sublicense, and/or sell copies of the Software, and to
22+
* permit persons to whom the Software is furnished to do so, subject to
23+
* the following conditions:
24+
*
25+
* The above copyright notice and this permission notice shall be
26+
* included in all copies or substantial portions of the Software.
27+
*
28+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35+
*
36+
*/
37+
38+
#include <gecode/float.hh>
39+
#include <gecode/search/relax.hh>
40+
41+
namespace Gecode { namespace Float {
42+
43+
/// Class for posting equalities for non-relaxed variables
44+
class Relax {
45+
public:
46+
/// Post the actual equality for non-relaxed variables
47+
ExecStatus operator ()(Home home, FloatVar x, FloatVar sx);
48+
};
49+
50+
forceinline ExecStatus
51+
Relax::operator ()(Home home, FloatVar x, FloatVar sx) {
52+
FloatView xv(x);
53+
return me_failed(xv.eq(home,sx.val())) ? ES_FAILED : ES_OK;
54+
}
55+
56+
}}
57+
58+
namespace Gecode {
59+
60+
void
61+
relax(Home home, const FloatVarArgs& x, const FloatVarArgs& sx,
62+
Rnd r, double p) {
63+
if (x.size() != sx.size())
64+
throw Float::ArgumentSizeMismatch("Float::relax");
65+
if ((p < 0.0) || (p > 1.0))
66+
throw Float::OutOfLimits("Float::relax");
67+
Float::Relax fr;
68+
Search::relax<FloatVarArgs,Float::Relax>(home,x,sx,r,p,fr);
69+
}
70+
71+
}
72+
73+
// STATISTICS: float-other
74+

gecode/int.hh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <vector>
5656

5757
#include <gecode/kernel.hh>
58+
#include <gecode/search.hh>
5859
#include <gecode/iter.hh>
5960

6061
/*
@@ -4579,6 +4580,61 @@ namespace Gecode {
45794580
BoolBranchFilter bf=NULL, BoolVarValPrint vvp=NULL);
45804581
}
45814582

4583+
namespace Gecode {
4584+
4585+
/*
4586+
* \brief Relaxed assignment of variables in \a x from values in \a sx
4587+
*
4588+
* The variables in \a x are assigned values from the assigned variables
4589+
* in the solution \a sx with a relaxation probability \a p. That is,
4590+
* if \$fp=0.1\f$ approximately 10% of the variables in \a x will be
4591+
* assigned a value from \a sx.
4592+
*
4593+
* The random numbers are generated from the generator \a r. At least
4594+
* one variable will not be assigned: in case the relaxation attempt
4595+
* would suggest that all variables should be assigned, a single
4596+
* variable will be selected randomly to remain unassigned.
4597+
*
4598+
* Throws an exception of type Int::ArgumentSizeMismatch, if \a x and
4599+
* \a sx are of different size.
4600+
*
4601+
* Throws an exception of type Int::OutOfLimits, if \a p is not between
4602+
* \a 0.0 and \a 1.0.
4603+
*
4604+
* \ingroup TaskModelInt
4605+
*/
4606+
GECODE_INT_EXPORT void
4607+
relax(Home home, const IntVarArgs& x, const IntVarArgs& sx,
4608+
Rnd r, double p);
4609+
4610+
/*
4611+
* \brief Relaxed assignment of variables in \a x from values in \a sx
4612+
*
4613+
* The variables in \a x are assigned values from the assigned variables
4614+
* in the solution \a sx with a relaxation probability \a p. That is,
4615+
* if \$fp=0.1\f$ approximately 10% of the variables in \a x will be
4616+
* assigned a value from \a sx.
4617+
*
4618+
* The random numbers are generated from the generator \a r. At least
4619+
* one variable will not be assigned: in case the relaxation attempt
4620+
* would suggest that all variables should be assigned, a single
4621+
* variable will be selected randomly to remain unassigned.
4622+
*
4623+
* Throws an exception of type Int::ArgumentSizeMismatch, if \a x and
4624+
* \a sx are of different size.
4625+
*
4626+
* Throws an exception of type Int::OutOfLimits, if \a p is not between
4627+
* \a 0.0 and \a 1.0.
4628+
*
4629+
* \ingroup TaskModelInt
4630+
*/
4631+
GECODE_INT_EXPORT void
4632+
relax(Home home, const BoolVarArgs& x, const BoolVarArgs& sx,
4633+
Rnd r, double p);
4634+
4635+
}
4636+
4637+
45824638
#include <gecode/int/trace/int-trace-view.hpp>
45834639
#include <gecode/int/trace/bool-trace-view.hpp>
45844640

0 commit comments

Comments
 (0)