gecoder 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGES +9 -1
  2. data/Rakefile +3 -0
  3. data/example/send_most_money.rb +58 -0
  4. data/ext/missing.cpp +26 -1
  5. data/ext/missing.h +2 -0
  6. data/ext/vararray.cpp +31 -11
  7. data/ext/vararray.h +6 -0
  8. data/lib/gecoder/bindings.rb +5 -5
  9. data/lib/gecoder/bindings/bindings.rb +52 -0
  10. data/lib/gecoder/interface/binding_changes.rb +16 -11
  11. data/lib/gecoder/interface/constraints.rb +28 -15
  12. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +8 -17
  13. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +8 -3
  14. data/lib/gecoder/interface/constraints/int/arithmetic.rb +10 -15
  15. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +10 -16
  16. data/lib/gecoder/interface/constraints/int_enum/element.rb +6 -11
  17. data/lib/gecoder/interface/constraints/int_var_constraints.rb +2 -1
  18. data/lib/gecoder/interface/constraints/set/cardinality.rb +4 -7
  19. data/lib/gecoder/interface/constraints/set/connection.rb +13 -22
  20. data/lib/gecoder/interface/model.rb +52 -41
  21. data/lib/gecoder/interface/search.rb +29 -24
  22. data/lib/gecoder/interface/variables.rb +27 -15
  23. data/lib/gecoder/version.rb +1 -1
  24. data/specs/constraints/arithmetic.rb +27 -17
  25. data/specs/constraints/bool_enum.rb +4 -2
  26. data/specs/constraints/boolean.rb +5 -2
  27. data/specs/constraints/cardinality.rb +28 -8
  28. data/specs/constraints/connection.rb +58 -37
  29. data/specs/constraints/constraints.rb +2 -2
  30. data/specs/constraints/count.rb +3 -3
  31. data/specs/constraints/element.rb +5 -5
  32. data/specs/constraints/int_domain.rb +4 -2
  33. data/specs/constraints/set_domain.rb +8 -4
  34. data/specs/constraints/set_relation.rb +10 -5
  35. data/specs/int_var.rb +3 -3
  36. data/specs/model.rb +10 -9
  37. data/specs/search.rb +54 -5
  38. data/specs/spec_helper.rb +2 -0
  39. data/tasks/distribution.rake +8 -1
  40. data/tasks/specs.rake +0 -1
  41. data/vendor/rust/rust/class.rb +6 -1
  42. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +3 -3
  43. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +15 -1
  44. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +2 -0
  45. metadata +51 -21
data/CHANGES CHANGED
@@ -1,3 +1,11 @@
1
+ == Version 0.6.1
2
+ This release fixes various bugs introduced in 0.6.0 and changes the way that
3
+ int variable domains are specified (breaking backward-compatibility).
4
+
5
+ * The domain for int variables can no longer be specified as several individual elements, it has to be specified as either a single element, a range or another enumeration.
6
+ * Fixed a bug with set cardinality, min and max constraints using composite sugar.
7
+ * Variables can now be created inside the optimization block.
8
+
1
9
  == Version 0.6.0
2
10
  This release adds most of the remaining set constraints. It also makes
3
11
  backward-compatibility breaking changes to the way that properties of variables
@@ -9,7 +17,7 @@ are accessed.
9
17
  * Added include (match) constraint for sets.
10
18
  * Added distinct constraints (distinct and at most one) for sets.
11
19
  * Added branch and bound search (optimization search). It's quite shaky at the moment though.
12
- * Assigned values of variables are now always accessed using #value instread of the various previous methods. The methods for extracting information from set variables have been changed and renamed.
20
+ * Assigned values of variables are now always accessed using #value instead of the various previous methods. The methods for extracting information from set variables have been changed and renamed.
13
21
  * Enumerations containing variables now provide a convenience method #values which returns an array of the enum's values.
14
22
 
15
23
  == Version 0.5.0
data/Rakefile CHANGED
@@ -8,3 +8,6 @@ task :default => [:verify_rcov]
8
8
 
9
9
  desc 'Performs the tasks necessary when releasing'
10
10
  task :release => [:publish_website, :publish_packages, :tag]
11
+
12
+ desc 'Runs all the tests'
13
+ task :test => :specs
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/example_helper'
2
+
3
+ # Solves the cryptarithmetic send+most=money problem while maximizing the value
4
+ # of "money".
5
+ class SendMoreMoney < Gecode::Model
6
+ attr :money
7
+
8
+ def initialize
9
+ # Set up the variables, 9 letters with domain 0..9.
10
+ s,e,n,d,m,o,s,t,y = @letters = int_var_array(9, 0..9)
11
+ @money = wrap_enum([m,o,n,e,y])
12
+
13
+ # Set up the constraints.
14
+ # The equation must hold.
15
+ (equation_row(s, e, n, d) + equation_row(m, o, s, t)).must ==
16
+ equation_row(m,o,n,e,y)
17
+
18
+ # The initial letters may not be 0.
19
+ s.must_not == 0
20
+ m.must_not == 0
21
+
22
+ # All letters must be assigned different digits.
23
+ @letters.must_be.distinct
24
+
25
+ # Set the branching.
26
+ branch_on @letters, :variable => :smallest_size, :value => :min
27
+ end
28
+
29
+ def to_s
30
+ %w{s e n d m o s t y}.zip(@letters).map do |text, letter|
31
+ "#{text}: #{letter.value}"
32
+ end.join(', ')
33
+ end
34
+
35
+ private
36
+
37
+ # A helper to make the linear equation a bit tidier. Takes a number of
38
+ # variables and computes the linear combination as if the variable
39
+ # were digits in a base 10 number. E.g. x,y,z becomes
40
+ # 100*x + 10*y + z .
41
+ def equation_row(*variables)
42
+ variables.to_number
43
+ end
44
+ end
45
+
46
+ class Array
47
+ # Computes a number of the specified base using the array's elements as
48
+ # digits.
49
+ def to_number(base = 10)
50
+ inject{ |result, variable| variable + result * base }
51
+ end
52
+ end
53
+
54
+ solution = SendMoreMoney.new.optimize! do |model, best_so_far|
55
+ model.money.to_number.must > best_so_far.money.values.to_number
56
+ end
57
+ puts solution.to_s
58
+ puts "money: #{solution.money.values.to_number}"
data/ext/missing.cpp CHANGED
@@ -194,12 +194,37 @@ void MSpace::own(Gecode::MSetVarArray *sva, const char *name)
194
194
  d->setArrays[name] = sva;
195
195
  }
196
196
 
197
+ void MSpace::gc_mark()
198
+ {
199
+ {
200
+ IntVarArrays::iterator it, eend = d->intArrays.end();
201
+ for(it = d->intArrays.begin(); it != eend; it++)
202
+ {
203
+ rb_gc_mark(Rust_gecode::cxx2ruby((*it).second));
204
+ }
205
+ }
206
+ {
207
+ BoolVarArrays::iterator it, eend = d->boolArrays.end();
208
+ for(it = d->boolArrays.begin(); it != eend; it++)
209
+ {
210
+ rb_gc_mark(Rust_gecode::cxx2ruby((*it).second));
211
+ }
212
+ }
213
+ {
214
+ SetVarArrays::iterator it, eend = d->setArrays.end();
215
+ for(it = d->setArrays.begin(); it != eend; it++)
216
+ {
217
+ rb_gc_mark(Rust_gecode::cxx2ruby((*it).second));
218
+ }
219
+ }
220
+ }
221
+
197
222
  // For BAB.
198
223
  void MSpace::constrain(MSpace* s)
199
224
  {
200
225
  // Call Ruby's constrain.
201
226
  rb_funcall(Rust_gecode::cxx2ruby(this), rb_intern("constrain"), 1,
202
- Rust_gecode::cxx2ruby(s));
227
+ Rust_gecode::cxx2ruby(s, false));
203
228
  }
204
229
 
205
230
  Gecode::MIntVarArray *MSpace::intVarArray(const char *name) const
data/ext/missing.h CHANGED
@@ -61,6 +61,8 @@ class MSpace : public Space
61
61
  void own(Gecode::MBoolVarArray *bva, const char *name);
62
62
  void own(Gecode::MSetVarArray *sva, const char *name);
63
63
 
64
+ void gc_mark();
65
+
64
66
  void constrain(MSpace* s);
65
67
 
66
68
  Gecode::MIntVarArray *intVarArray(const char *name ) const;
data/ext/vararray.cpp CHANGED
@@ -18,6 +18,7 @@
18
18
  **/
19
19
 
20
20
  #include "vararray.h"
21
+ #include "gecode.hh"
21
22
 
22
23
  namespace Gecode {
23
24
 
@@ -74,7 +75,6 @@ MIntVarArray::MIntVarArray() : d(new Private)
74
75
  MIntVarArray::MIntVarArray(const Gecode::IntVarArray &arr) : d(new Private)
75
76
  {
76
77
  setArray(arr);
77
- setCount(0);
78
78
  }
79
79
 
80
80
  MIntVarArray::MIntVarArray (Space *home, int n) : d(new Private)
@@ -107,7 +107,7 @@ void MIntVarArray::setArray(const Gecode::IntVarArray &arr)
107
107
  void MIntVarArray::enlargeArray(Gecode::Space *parent, int n)
108
108
  {
109
109
  Gecode::IntVarArray na(parent, size()+n, 0, 0);
110
- for(int i = count(); i--; )
110
+ for(int i = size(); i--; )
111
111
  na[i] = d->array[i];
112
112
 
113
113
  d->array = na;
@@ -130,6 +130,13 @@ IntVar &MIntVarArray::operator [](int index)
130
130
  return d->array[index];
131
131
  }
132
132
 
133
+ void MIntVarArray::gc_mark()
134
+ {
135
+ for(int i = size(); i--; ) {
136
+ rb_gc_mark(Rust_gecode::cxx2ruby(&(d->array[i])));
137
+ }
138
+ }
139
+
133
140
  void MIntVarArray::debug() const
134
141
  {
135
142
  for(int i = 0; i < d->array.size(); i++)
@@ -150,14 +157,14 @@ struct MBoolVarArray::Private
150
157
 
151
158
  MBoolVarArray::MBoolVarArray() : d(new Private)
152
159
  {
160
+ setArray(Gecode::BoolVarArray());
153
161
  }
154
162
 
155
163
  MBoolVarArray::MBoolVarArray(const Gecode::BoolVarArray &arr) : d(new Private)
156
164
  {
157
- d->array = arr;
158
- setSize(arr.size());
159
- setCount(0);
165
+ setArray(arr);
160
166
  }
167
+
161
168
  MBoolVarArray::MBoolVarArray (Space *home, int n) : d(new Private)
162
169
  {
163
170
  setArray(Gecode::BoolVarArray(home, n));
@@ -177,7 +184,7 @@ void MBoolVarArray::setArray(const Gecode::BoolVarArray &arr)
177
184
  void MBoolVarArray::enlargeArray(Gecode::Space *parent, int n)
178
185
  {
179
186
  Gecode::BoolVarArray na(parent, size()+n, 0, 0);
180
- for(int i = count(); i--; )
187
+ for(int i = size(); i--; )
181
188
  na[i] = d->array[i];
182
189
 
183
190
  d->array = na;
@@ -200,6 +207,13 @@ Gecode::BoolVar &MBoolVarArray::operator[](int index)
200
207
  return d->array[index];
201
208
  }
202
209
 
210
+ void MBoolVarArray::gc_mark()
211
+ {
212
+ for(int i = size(); i--; ) {
213
+ rb_gc_mark(Rust_gecode::cxx2ruby(&(d->array[i])));
214
+ }
215
+ }
216
+
203
217
  void MBoolVarArray::debug() const
204
218
  {
205
219
  for(int i = 0; i < d->array.size(); i++)
@@ -219,13 +233,12 @@ struct MSetVarArray::Private
219
233
 
220
234
  MSetVarArray::MSetVarArray() : d(new Private)
221
235
  {
236
+ setArray(Gecode::SetVarArray());
222
237
  }
223
238
 
224
239
  MSetVarArray::MSetVarArray(const Gecode::SetVarArray &arr) : d(new Private)
225
240
  {
226
- d->array = arr;
227
- setSize(arr.size());
228
- setCount(0);
241
+ setArray(arr);
229
242
  }
230
243
 
231
244
  MSetVarArray::MSetVarArray(Space *home, int n) : d(new Private)
@@ -266,8 +279,8 @@ void MSetVarArray::setArray(const Gecode::SetVarArray &arr)
266
279
 
267
280
  void MSetVarArray::enlargeArray(Gecode::Space *parent, int n)
268
281
  {
269
- Gecode::SetVarArray na(parent, size()*n);
270
- for (int i = count(); i--; )
282
+ Gecode::SetVarArray na(parent, size()+n);
283
+ for (int i = size(); i--; )
271
284
  na[i] = d->array[i];
272
285
 
273
286
  d->array = na;
@@ -290,6 +303,13 @@ Gecode::SetVar &MSetVarArray::operator[](int index)
290
303
  return d->array[index];
291
304
  }
292
305
 
306
+ void MSetVarArray::gc_mark()
307
+ {
308
+ for(int i = size(); i--; ) {
309
+ rb_gc_mark(Rust_gecode::cxx2ruby(&(d->array[i])));
310
+ }
311
+ }
312
+
293
313
  void MSetVarArray::debug() const
294
314
  {
295
315
  for(int i = 0; i < d->array.size(); i++)
data/ext/vararray.h CHANGED
@@ -65,6 +65,8 @@ class MIntVarArray : public MVarArray
65
65
 
66
66
  void debug() const;
67
67
 
68
+ void gc_mark();
69
+
68
70
  IntVar &operator [](int index);
69
71
 
70
72
  private:
@@ -93,6 +95,8 @@ class MBoolVarArray : public MVarArray
93
95
 
94
96
  void debug() const;
95
97
 
98
+ void gc_mark();
99
+
96
100
  private:
97
101
  struct Private;
98
102
  Private *const d;
@@ -131,6 +135,8 @@ class MSetVarArray : public MVarArray
131
135
 
132
136
  void debug() const;
133
137
 
138
+ void gc_mark();
139
+
134
140
  private:
135
141
  struct Private;
136
142
  Private *const d;
@@ -3,11 +3,6 @@ module Gecode
3
3
  # The Gecode::Raw module is what the interface should use to access methods
4
4
  # in Gecode. The actual bindings are located in ::GecodeRaw.
5
5
 
6
- # We just make Gecode::Raw an alias of the real module.
7
- Raw = ::GecodeRaw
8
- # Log all calls via Gecode::Raw.
9
- #Raw = ::LoggingLayer
10
-
11
6
  # Describes a layer that delegates to GecodeRaw only after having logged the
12
7
  # call.
13
8
  module LoggingLayer
@@ -31,4 +26,9 @@ module Gecode
31
26
  @logger
32
27
  end
33
28
  end
29
+
30
+ # We just make Gecode::Raw an alias of the real module.
31
+ Raw = ::GecodeRaw
32
+ # Log all calls via Gecode::Raw.
33
+ #Raw = LoggingLayer
34
34
  end
@@ -48,6 +48,28 @@ Gecode::IntArgs ruby2Gecode_IntArgs(VALUE arr, int argn)
48
48
  }
49
49
  @
50
50
 
51
+ custom_mark_definitions =<<-"end_custom_definition"
52
+ static void Gecode_MSpace_custom_mark(void *p) {
53
+ Gecode_MSpace_mark(p);
54
+ ((Gecode::MSpace*)p)->gc_mark();
55
+ }
56
+
57
+ static void Gecode_MIntVarArray_custom_mark(void *p) {
58
+ Gecode_MIntVarArray_mark(p);
59
+ ((Gecode::MIntVarArray*)p)->gc_mark();
60
+ }
61
+
62
+ static void Gecode_MBoolVarArray_custom_mark(void *p) {
63
+ Gecode_MBoolVarArray_mark(p);
64
+ ((Gecode::MBoolVarArray*)p)->gc_mark();
65
+ }
66
+
67
+ static void Gecode_MSetVarArray_custom_mark(void *p) {
68
+ Gecode_MSetVarArray_mark(p);
69
+ ((Gecode::MSetVarArray*)p)->gc_mark();
70
+ }
71
+ end_custom_definition
72
+
51
73
 
52
74
  Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
53
75
  b.include_header 'gecode/kernel.hh', Rust::Bindings::HeaderGlobal
@@ -57,6 +79,7 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
57
79
  b.include_header 'missing.h', Rust::Bindings::HeaderLocal
58
80
 
59
81
  b.add_custom_definition ruby2intargs
82
+ b.add_custom_definition custom_mark_definitions
60
83
 
61
84
  # Is it possible to use namespaces with multiple levels in Rust? I.e. use
62
85
  # Gecode::Raw instead of GecodeRaw here (and avoid the hidious renaming)
@@ -146,6 +169,8 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
146
169
 
147
170
  ns.add_cxx_class "MIntVarArray" do |klass|
148
171
  klass.bindname = "IntVarArray"
172
+ klass.function_mark = 'Gecode_MIntVarArray_custom_mark'
173
+
149
174
  klass.add_constructor
150
175
  klass.add_constructor do |func|
151
176
  func.add_parameter "Gecode::MSpace *", "home"
@@ -178,6 +203,11 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
178
203
  method.add_parameter "Gecode::IntVar", "val"
179
204
  end
180
205
 
206
+ klass.add_method "enlargeArray" do |method|
207
+ method.add_parameter "Gecode::MSpace *", "home"
208
+ method.add_parameter "int", "n"
209
+ end
210
+
181
211
  klass.add_method "size", "int"
182
212
 
183
213
  klass.add_method "debug"
@@ -187,6 +217,8 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
187
217
 
188
218
  ns.add_cxx_class "MBoolVarArray" do |klass|
189
219
  klass.bindname = "BoolVarArray"
220
+ klass.function_mark = 'Gecode_MBoolVarArray_custom_mark'
221
+
190
222
  klass.add_constructor
191
223
  klass.add_constructor do |func|
192
224
  func.add_parameter "Gecode::MSpace *", "home"
@@ -206,6 +238,11 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
206
238
  method.add_parameter "Gecode::BoolVar", "val"
207
239
  end
208
240
 
241
+ klass.add_method "enlargeArray" do |method|
242
+ method.add_parameter "Gecode::MSpace *", "home"
243
+ method.add_parameter "int", "n"
244
+ end
245
+
209
246
  klass.add_method "size", "int"
210
247
 
211
248
  klass.add_method "debug"
@@ -214,6 +251,8 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
214
251
 
215
252
  ns.add_cxx_class "MSetVarArray" do |klass|
216
253
  klass.bindname = "SetVarArray"
254
+ klass.function_mark = 'Gecode_MSetVarArray_custom_mark'
255
+
217
256
  klass.add_constructor
218
257
 
219
258
  klass.add_constructor do |method|
@@ -274,6 +313,11 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
274
313
  method.add_parameter "Gecode::SetVar", "val"
275
314
  end
276
315
 
316
+ klass.add_method "enlargeArray" do |method|
317
+ method.add_parameter "Gecode::MSpace *", "home"
318
+ method.add_parameter "int", "n"
319
+ end
320
+
277
321
  klass.add_method "size", "int"
278
322
 
279
323
  klass.add_method "debug"
@@ -288,6 +332,7 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
288
332
 
289
333
  ns.add_cxx_class "MSpace" do |klass|
290
334
  klass.bindname = "Space"
335
+ klass.function_mark = 'Gecode_MSpace_custom_mark'
291
336
 
292
337
  klass.add_constructor
293
338
 
@@ -1429,6 +1474,13 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
1429
1474
  # func.add_parameter "Gecode::IntConLevel", "icl", true
1430
1475
  # end
1431
1476
 
1477
+ ns.add_function "bab", "Gecode::MSpace*" do |func|
1478
+ func.add_parameter "Gecode::MSpace*", "home"
1479
+ func.add_parameter "int", "c_d"
1480
+ func.add_parameter "int", "a_d"
1481
+ func.add_parameter "Gecode::Search::MStop *", "st"
1482
+ end
1483
+
1432
1484
  ns.add_function "rel" do |func|
1433
1485
  func.add_parameter "Gecode::MSpace*", "home"
1434
1486
  func.add_parameter "Gecode::IntVar", "x0"
@@ -52,31 +52,40 @@ module GecodeRaw
52
52
  Gecode::Model.constrain(self, best_so_far_space)
53
53
  end
54
54
 
55
+ # Refreshes the underlying stores used by the space.
56
+ def refresh
57
+ @int_var_store = nil
58
+ @bool_var_store = nil
59
+ @set_var_store = nil
60
+ end
61
+
55
62
  private
56
63
 
57
64
  # Retrieves the store used for integer variables. Creates one if none
58
65
  # exists.
59
66
  def int_var_store
60
- if @int_var_store.nil?
67
+ # TODO: caching interferes with the variable creation during BAB-search,
68
+ # find out why.
69
+ #if @int_var_store.nil?
61
70
  @int_var_store = Gecode::Util::IntVarStore.new(self)
62
- end
71
+ #end
63
72
  return @int_var_store
64
73
  end
65
74
 
66
75
  # Retrieves the store used for boolean variables. Creates one if none
67
76
  # exists.
68
77
  def bool_var_store
69
- if @bool_var_store.nil?
78
+ #if @bool_var_store.nil?
70
79
  @bool_var_store = Gecode::Util::BoolVarStore.new(self)
71
- end
80
+ #end
72
81
  return @bool_var_store
73
82
  end
74
83
 
75
84
  # Retrieves the store used for set variables. Creates one if none exists.
76
85
  def set_var_store
77
- if @set_var_store.nil?
86
+ #if @set_var_store.nil?
78
87
  @set_var_store = Gecode::Util::SetVarStore.new(self)
79
- end
88
+ #end
80
89
  return @set_var_store
81
90
  end
82
91
  end
@@ -100,11 +109,7 @@ module Gecode
100
109
 
101
110
  # Grows the store to the new size.
102
111
  def grow(new_size)
103
- new_array = new_storage_array(new_size)
104
- @var_array.size.times do |i|
105
- new_array[i] = @var_array[i]
106
- end
107
- @var_array = new_array
112
+ @var_array.enlargeArray(@space, new_size - @size)
108
113
  @size = new_size
109
114
  end
110
115
  end