gecoder-with-gecode 0.7.1-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. data/CHANGES +81 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +45 -0
  5. data/Rakefile +13 -0
  6. data/example/example_helper.rb +1 -0
  7. data/example/magic_sequence.rb +43 -0
  8. data/example/queens.rb +43 -0
  9. data/example/raw_bindings.rb +42 -0
  10. data/example/send_more_money.rb +43 -0
  11. data/example/send_most_money.rb +58 -0
  12. data/example/square_tiling.rb +84 -0
  13. data/example/sudoku-set.rb +110 -0
  14. data/example/sudoku.rb +61 -0
  15. data/lib/gecode.dll +0 -0
  16. data/lib/gecoder.rb +5 -0
  17. data/lib/gecoder/bindings.rb +54 -0
  18. data/lib/gecoder/bindings/bindings.rb +2210 -0
  19. data/lib/gecoder/interface.rb +8 -0
  20. data/lib/gecoder/interface/binding_changes.rb +313 -0
  21. data/lib/gecoder/interface/branch.rb +152 -0
  22. data/lib/gecoder/interface/constraints.rb +397 -0
  23. data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
  24. data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
  25. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
  26. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  27. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
  28. data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
  29. data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
  30. data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
  31. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
  32. data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
  33. data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
  34. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
  35. data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
  36. data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
  37. data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
  38. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
  39. data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
  40. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  41. data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
  42. data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
  43. data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
  44. data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
  45. data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
  46. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  47. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
  48. data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
  49. data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
  50. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
  51. data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
  52. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  53. data/lib/gecoder/interface/enum_wrapper.rb +153 -0
  54. data/lib/gecoder/interface/model.rb +251 -0
  55. data/lib/gecoder/interface/search.rb +123 -0
  56. data/lib/gecoder/interface/variables.rb +254 -0
  57. data/lib/gecoder/version.rb +4 -0
  58. data/specs/binding_changes.rb +76 -0
  59. data/specs/bool_var.rb +74 -0
  60. data/specs/branch.rb +170 -0
  61. data/specs/constraints/arithmetic.rb +266 -0
  62. data/specs/constraints/bool_enum.rb +140 -0
  63. data/specs/constraints/boolean.rb +232 -0
  64. data/specs/constraints/cardinality.rb +154 -0
  65. data/specs/constraints/channel.rb +126 -0
  66. data/specs/constraints/connection.rb +373 -0
  67. data/specs/constraints/constraint_helper.rb +180 -0
  68. data/specs/constraints/constraints.rb +74 -0
  69. data/specs/constraints/count.rb +139 -0
  70. data/specs/constraints/distinct.rb +218 -0
  71. data/specs/constraints/element.rb +106 -0
  72. data/specs/constraints/equality.rb +31 -0
  73. data/specs/constraints/int_domain.rb +69 -0
  74. data/specs/constraints/int_relation.rb +78 -0
  75. data/specs/constraints/linear.rb +332 -0
  76. data/specs/constraints/reification_sugar.rb +96 -0
  77. data/specs/constraints/selection.rb +292 -0
  78. data/specs/constraints/set_domain.rb +181 -0
  79. data/specs/constraints/set_operation.rb +285 -0
  80. data/specs/constraints/set_relation.rb +201 -0
  81. data/specs/constraints/sort.rb +175 -0
  82. data/specs/distribution.rb +14 -0
  83. data/specs/enum_matrix.rb +43 -0
  84. data/specs/enum_wrapper.rb +122 -0
  85. data/specs/int_var.rb +144 -0
  86. data/specs/logging.rb +24 -0
  87. data/specs/model.rb +190 -0
  88. data/specs/search.rb +246 -0
  89. data/specs/set_var.rb +68 -0
  90. data/specs/spec_helper.rb +93 -0
  91. data/tasks/all_tasks.rb +1 -0
  92. data/tasks/building.howto +65 -0
  93. data/tasks/distribution.rake +156 -0
  94. data/tasks/rcov.rake +17 -0
  95. data/tasks/specs.rake +15 -0
  96. data/tasks/svn.rake +11 -0
  97. data/tasks/website.rake +51 -0
  98. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  99. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  100. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  101. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  102. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  103. data/vendor/rust/README +28 -0
  104. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  105. data/vendor/rust/include/rust_checks.hh +115 -0
  106. data/vendor/rust/include/rust_conversions.hh +102 -0
  107. data/vendor/rust/rust.rb +67 -0
  108. data/vendor/rust/rust/attribute.rb +51 -0
  109. data/vendor/rust/rust/bindings.rb +172 -0
  110. data/vendor/rust/rust/class.rb +339 -0
  111. data/vendor/rust/rust/constants.rb +48 -0
  112. data/vendor/rust/rust/container.rb +110 -0
  113. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  114. data/vendor/rust/rust/cwrapper.rb +72 -0
  115. data/vendor/rust/rust/cxxclass.rb +98 -0
  116. data/vendor/rust/rust/element.rb +81 -0
  117. data/vendor/rust/rust/enum.rb +63 -0
  118. data/vendor/rust/rust/function.rb +407 -0
  119. data/vendor/rust/rust/namespace.rb +61 -0
  120. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  121. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  122. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  123. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  124. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  125. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  126. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  127. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  128. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
  129. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  130. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  131. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  132. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  133. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  134. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  135. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  136. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  137. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  138. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  139. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  140. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  141. data/vendor/rust/rust/type.rb +98 -0
  142. data/vendor/rust/test/Makefile +4 -0
  143. data/vendor/rust/test/constants.rb +36 -0
  144. data/vendor/rust/test/cppclass.cc +45 -0
  145. data/vendor/rust/test/cppclass.hh +67 -0
  146. data/vendor/rust/test/cppclass.rb +59 -0
  147. data/vendor/rust/test/cwrapper.c +74 -0
  148. data/vendor/rust/test/cwrapper.h +41 -0
  149. data/vendor/rust/test/cwrapper.rb +56 -0
  150. data/vendor/rust/test/dummyclass.hh +31 -0
  151. data/vendor/rust/test/lib/extension-test.rb +98 -0
  152. data/vendor/rust/test/operators.cc +41 -0
  153. data/vendor/rust/test/operators.hh +39 -0
  154. data/vendor/rust/test/operators.rb +39 -0
  155. data/vendor/rust/test/test-constants.rb +43 -0
  156. data/vendor/rust/test/test-cppclass.rb +82 -0
  157. data/vendor/rust/test/test-cwrapper.rb +80 -0
  158. data/vendor/rust/test/test-operators.rb +42 -0
  159. metadata +293 -0
@@ -0,0 +1,8 @@
1
+ require 'gecoder/interface/binding_changes'
2
+ require 'gecoder/interface/variables'
3
+ require 'gecoder/interface/enum_matrix'
4
+ require 'gecoder/interface/model'
5
+ require 'gecoder/interface/search'
6
+ require 'gecoder/interface/constraints'
7
+ require 'gecoder/interface/enum_wrapper'
8
+ require 'gecoder/interface/branch'
@@ -0,0 +1,313 @@
1
+ # This file adds a small layer on top of the bindings. It alters the allocation
2
+ # of variables so that a single array is allocated in each space which is then
3
+ # used to store variable. The variables themselves are not directly returned,
4
+ # rather they are represented as the index in that store, which allows the
5
+ # variable to be retrieved back given a space.
6
+ #
7
+ # This layer should be moved to the C++ side instead when possible for better
8
+ # performance.
9
+ module GecodeRaw #:nodoc: all
10
+ class Space
11
+ # Creates the specified number of integer variables in the space with the
12
+ # specified domain. Returns the indices with which they can then be
13
+ # accessed using int_var. The domain can be given as a Range (trated
14
+ # specially) or as another enum.
15
+ def new_int_vars(domain, count = 1)
16
+ int_var_store.new_vars(domain, count)
17
+ end
18
+
19
+ # Gets the int variable with the specified index, nil if none exists.
20
+ def int_var(index)
21
+ int_var_store[index]
22
+ end
23
+
24
+ # Creates the specified number of boolean variables in the space. Returns
25
+ # the indices with which they can then be accessed using bool_var.
26
+ def new_bool_vars(count = 1)
27
+ bool_var_store.new_vars(count)
28
+ end
29
+
30
+ # Gets the bool variable with the specified index, nil if none exists.
31
+ def bool_var(index)
32
+ bool_var_store[index]
33
+ end
34
+
35
+ # Creates the specified number of set variables in the space with the
36
+ # specified domain for greatest lower bound and least upper bound
37
+ # (specified as either a range or enum). A range for the allowed
38
+ # cardinality of the set can also be specified, if none is specified, or
39
+ # nil is given, then the default range (anything) will be used. Returns
40
+ # the indices with which they can then be accessed using set_var.
41
+ def new_set_vars(*vars)
42
+ set_var_store.new_vars(*vars)
43
+ end
44
+
45
+ # Gets the set variable with the specified index, nil if none exists.
46
+ def set_var(index)
47
+ set_var_store[index]
48
+ end
49
+
50
+ # Used by Gecode during BAB-search.
51
+ def constrain(best_so_far_space)
52
+ Gecode::Model.constrain(self, best_so_far_space)
53
+ end
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
+
62
+ private
63
+
64
+ # Retrieves the store used for integer variables. Creates one if none
65
+ # exists.
66
+ def int_var_store
67
+ # TODO: caching interferes with the variable creation during BAB-search,
68
+ # find out why.
69
+ #if @int_var_store.nil?
70
+ @int_var_store = Gecode::Util::IntVarStore.new(self)
71
+ #end
72
+ return @int_var_store
73
+ end
74
+
75
+ # Retrieves the store used for boolean variables. Creates one if none
76
+ # exists.
77
+ def bool_var_store
78
+ #if @bool_var_store.nil?
79
+ @bool_var_store = Gecode::Util::BoolVarStore.new(self)
80
+ #end
81
+ return @bool_var_store
82
+ end
83
+
84
+ # Retrieves the store used for set variables. Creates one if none exists.
85
+ def set_var_store
86
+ #if @set_var_store.nil?
87
+ @set_var_store = Gecode::Util::SetVarStore.new(self)
88
+ #end
89
+ return @set_var_store
90
+ end
91
+ end
92
+ end
93
+
94
+ module Gecode
95
+ # Various utility (mainly used to change the behavior of the raw bindings).
96
+ module Util #:nodoc: all
97
+ # Provides common methods to the variable stores. The stores must provide
98
+ # @next_index, @var_array, @size, ARRAY_IDENTIFIER and #new_storage_array .
99
+ module VarStoreMethods
100
+ # Returns the int var with the specified index, nil if none exists.
101
+ def [](index)
102
+ if index < 0 or index >= @next_index
103
+ return nil
104
+ end
105
+ return @var_array.at(index)
106
+ end
107
+
108
+ private
109
+
110
+ # Grows the store to the new size.
111
+ def grow(new_size)
112
+ @var_array.enlargeArray(@space, new_size - @size)
113
+ @size = new_size
114
+ end
115
+ end
116
+
117
+ # A store in which int variables are created and stored.
118
+ class IntVarStore
119
+ # Design note: The store used to double its size when it needed to grow
120
+ # leaving unallocated slots (in rev 16). This was changed to only growing
121
+ # the amount of space needed because the additional information about which
122
+ # slot is the next unallocated one could not be encoded without changes to
123
+ # the bindings (and without that information we can not deduce the store
124
+ # from the new copy of space). So for additional performance the bindings
125
+ # should grow the array more than needed (when this is moved to the bindings).
126
+
127
+ include VarStoreMethods
128
+
129
+ private
130
+
131
+ # A string that identifies the array used by the store.
132
+ ARRAY_IDENTIFIER = 'int_array'
133
+
134
+ public
135
+
136
+ # Creates a store for the specified space with the specified capacit.
137
+ def initialize(space)
138
+ @space = space
139
+
140
+ @var_array = space.int_var_array(ARRAY_IDENTIFIER)
141
+ if @var_array.nil?
142
+ # Create a new one.
143
+ @var_array = new_storage_array(0)
144
+ end
145
+
146
+ @size = @var_array.size
147
+ @next_index = @size
148
+ end
149
+
150
+ # Creates the specified number of integer variables in the space with the
151
+ # specified domain. Returns the indices with which they can then be
152
+ # accessed using int_var. The domain can be given as a Range (trated
153
+ # specially) or as another enum.
154
+ def new_vars(domain, count = 1)
155
+ grow(@next_index + count) # See the design note for more information.
156
+ count.times do |i|
157
+ if domain.kind_of? Range
158
+ domain_params = [domain.first, domain.last]
159
+ elsif domain.kind_of? Enumerable
160
+ arr = domain.to_a
161
+ domain_params = [Gecode::Raw::IntSet.new(arr, arr.size)]
162
+ else
163
+ raise TypeError, "Expected Enumerable, got #{domain.class}."
164
+ end
165
+
166
+ @var_array[@next_index] = Gecode::Raw::IntVar.new(@space,
167
+ *domain_params)
168
+ @next_index += 1
169
+ end
170
+
171
+ ((@next_index - count)...@next_index).to_a
172
+ end
173
+
174
+ # Returns the int var with the specified index, nil if none exists.
175
+ def [](index)
176
+ if index < 0 or index >= @next_index
177
+ return nil
178
+ end
179
+ return @var_array.at(index)
180
+ end
181
+
182
+ private
183
+
184
+ # Creates a new storage array for int variables.
185
+ def new_storage_array(new_size)
186
+ arr = Gecode::Raw::IntVarArray.new(@space, new_size)
187
+ @space.own(arr, ARRAY_IDENTIFIER)
188
+ return arr
189
+ end
190
+ end
191
+
192
+ # A store in which int variables are created and stored.
193
+ class BoolVarStore
194
+ # TODO: can we refactor this better seeing as IntVarStore and BoolVarStore
195
+ # are similar?
196
+
197
+ include VarStoreMethods
198
+
199
+ private
200
+
201
+ # A string that identifies the array used by the store.
202
+ ARRAY_IDENTIFIER = 'bool_array'
203
+
204
+ public
205
+
206
+ # Creates a store for the specified space with the specified capacit.
207
+ def initialize(space)
208
+ @space = space
209
+
210
+ @var_array = space.bool_var_array(ARRAY_IDENTIFIER)
211
+ if @var_array.nil?
212
+ # Create a new one.
213
+ @var_array = new_storage_array(0)
214
+ end
215
+
216
+ @size = @var_array.size
217
+ @next_index = @size
218
+ end
219
+
220
+ # Creates the specified number of new bool variables. Returns the indices
221
+ # of the created variables as an array.
222
+ def new_vars(count = 1)
223
+ grow(@next_index + count) # See the design note for more information.
224
+ count.times do |i|
225
+ @var_array[@next_index] = Gecode::Raw::BoolVar.new(@space, 0, 1)
226
+ @next_index += 1
227
+ end
228
+
229
+ ((@next_index - count)...@next_index).to_a
230
+ end
231
+
232
+ private
233
+
234
+ # Creates a new storage array for bool variables.
235
+ def new_storage_array(new_size)
236
+ arr = Gecode::Raw::BoolVarArray.new(@space, new_size)
237
+ @space.own(arr, ARRAY_IDENTIFIER)
238
+ return arr
239
+ end
240
+ end
241
+
242
+ # A store in which int variables are created and stored.
243
+ class SetVarStore
244
+ include VarStoreMethods
245
+
246
+ private
247
+
248
+ # A string that identifies the array used by the store.
249
+ ARRAY_IDENTIFIER = 'set_array'
250
+
251
+ public
252
+
253
+ # Creates a store for the specified space with the specified capacit.
254
+ def initialize(space)
255
+ @space = space
256
+
257
+ @var_array = space.set_var_array(ARRAY_IDENTIFIER)
258
+ if @var_array.nil?
259
+ # Create a new one.
260
+ @var_array = new_storage_array(0)
261
+ end
262
+
263
+ @size = @var_array.size
264
+ @next_index = @size
265
+ end
266
+
267
+ # Creates the specified number of set variables in the space with the
268
+ # specified domain for greatest lower bound and least upper bound
269
+ # (specified as either a range or enum). A range for the allowed
270
+ # cardinality of the set can also be specified, if none is specified, or
271
+ # nil is given, then the default range (anything) will be used. Returns
272
+ # the indices with which they can then be accessed using set_var.
273
+ def new_vars(glb_domain, lub_domain, cardinality_range = nil, count = 1)
274
+ grow(@next_index + count) # See the design note for more information.
275
+
276
+ if cardinality_range.nil?
277
+ cardinality_range = 0..Gecode::Raw::Limits::Set::CARD_MAX
278
+ end
279
+
280
+ params = [@space]
281
+ params << domain_to_args(glb_domain)
282
+ params << domain_to_args(lub_domain)
283
+ params << cardinality_range.first << cardinality_range.last
284
+ count.times do |i|
285
+ @var_array[@next_index] = Gecode::Raw::SetVar.new(*params.flatten)
286
+ @next_index += 1
287
+ end
288
+
289
+ ((@next_index - count)...@next_index).to_a
290
+ end
291
+
292
+ private
293
+
294
+ # Transforms a lub or glb domain given as a range or enumeration into one
295
+ # or more parameters that describe the domain to Gecode::Raw::SetVar .
296
+ def domain_to_args(domain)
297
+ if domain.kind_of? Range
298
+ return domain.first, domain.last
299
+ else
300
+ elements = domain.to_a
301
+ return Gecode::Raw::IntSet.new(domain, domain.size)
302
+ end
303
+ end
304
+
305
+ # Creates a new storage array for bool variables.
306
+ def new_storage_array(new_size)
307
+ arr = Gecode::Raw::SetVarArray.new(@space, new_size)
308
+ @space.own(arr, ARRAY_IDENTIFIER)
309
+ return arr
310
+ end
311
+ end
312
+ end
313
+ end
@@ -0,0 +1,152 @@
1
+ module Gecode
2
+ class Model
3
+ # Specifies which variables that should be branched on. One can optionally
4
+ # also select which of the variables that should be used first with the
5
+ # :variable option and which value in that variable's domain that should be
6
+ # used with the :value option. If nothing is specified then :variable uses
7
+ # :none and value uses :min.
8
+ #
9
+ # The following values can be used with :variable for integer and boolean
10
+ # enums:
11
+ # [:none] The first unassigned variable.
12
+ # [:smallest_min] The one with the smallest minimum.
13
+ # [:largest_min] The one with the largest minimum.
14
+ # [:smallest_max] The one with the smallest maximum.
15
+ # [:largest_max] The one with the largest maximum.
16
+ # [:smallest_size] The one with the smallest size.
17
+ # [:largest_size] The one with the larges size.
18
+ # [:smallest_degree] The one with the smallest degree. The degree of a
19
+ # variable is defined as the number of dependant
20
+ # propagators. In case of ties, choose the variable
21
+ # with smallest domain.
22
+ # [:largest_degree] The one with the largest degree. The degree of a
23
+ # variable is defined as the number of dependant
24
+ # propagators. In case of ties, choose the variable
25
+ # with smallest domain.
26
+ # [:smallest_min_regret] The one with the smallest min-regret. The
27
+ # min-regret of a variable is the difference between
28
+ # the smallest and second-smallest value still in
29
+ # the domain.
30
+ # [:largest_min_regret] The one with the largest min-regret. The
31
+ # min-regret of a variable is the difference between
32
+ # the smallest and second-smallest value still in
33
+ # the domain.
34
+ # [:smallest_max_regret] The one with the smallest max-regret The
35
+ # max-regret of a variable is the difference between
36
+ # the largest and second-largest value still in
37
+ # the domain.
38
+ # [:largest_max_regret] The one with the largest max-regret. The
39
+ # max-regret of a variable is the difference between
40
+ # the largest and second-largest value still in
41
+ # the domain.
42
+ #
43
+ # The following values can be used with :value for integer and boolean
44
+ # enums:
45
+ # [:min] Selects the smallest value.
46
+ # [:med] Select the median value.
47
+ # [:max] Selects the largest vale
48
+ # [:split_min] Selects the lower half of the domain.
49
+ # [:split_max] Selects the upper half of the domain.
50
+ #
51
+ # The following values can be used with :variable for set enums:
52
+ # [:none] The first unassigned set.
53
+ # [:smallest_cardinality] The one with the smallest cardinality.
54
+ # [:largest_cardinality] The one with the largest cardinality.
55
+ # [:smallest_unknown] The one with the smallest number of unknown
56
+ # elements
57
+ # [:largest_unknown] The one with the largest number of unknown
58
+ # elements
59
+ #
60
+ # The following values can be used with :value set enums:
61
+ # enums:
62
+ # [:min] Selects the smallest value in the unknown part of the set.
63
+ # [:max] Selects the largest value in the unknown part of the set.
64
+ def branch_on(variables, options = {})
65
+ if variables.respond_to? :to_int_var_array or
66
+ variables.respond_to? :to_bool_var_array
67
+ add_branch(variables, options, Constants::BRANCH_INT_VAR_CONSTANTS,
68
+ Constants::BRANCH_INT_VALUE_CONSTANTS)
69
+ elsif variables.respond_to? :to_set_var_array
70
+ add_branch(variables, options, Constants::BRANCH_SET_VAR_CONSTANTS,
71
+ Constants::BRANCH_SET_VALUE_CONSTANTS)
72
+ else
73
+ raise TypeError, "Unknown type of variable enum #{variables.class}."
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # This is a hack to get RDoc to ignore the constants.
80
+ module Constants #:nodoc:
81
+ # Maps the names of the supported variable branch strategies for integer and
82
+ # booleans to the corresponding constant in Gecode.
83
+ BRANCH_INT_VAR_CONSTANTS = {
84
+ :none => Gecode::Raw::BVAR_NONE,
85
+ :smallest_min => Gecode::Raw::BVAR_MIN_MIN,
86
+ :largest_min => Gecode::Raw::BVAR_MIN_MAX,
87
+ :smallest_max => Gecode::Raw::BVAR_MAX_MIN,
88
+ :largest_max => Gecode::Raw::BVAR_MAX_MAX,
89
+ :smallest_size => Gecode::Raw::BVAR_SIZE_MIN,
90
+ :largest_size => Gecode::Raw::BVAR_SIZE_MAX,
91
+ :smallest_degree => Gecode::Raw::BVAR_DEGREE_MIN,
92
+ :largest_degree => Gecode::Raw::BVAR_DEGREE_MAX,
93
+ :smallest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MIN,
94
+ :largest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MAX,
95
+ :smallest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MIN,
96
+ :largest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MAX
97
+ }
98
+ # Maps the names of the supported variable branch strategies for sets to
99
+ # the corresponding constant in Gecode.
100
+ BRANCH_SET_VAR_CONSTANTS = { #:nodoc:
101
+ :none => Gecode::Raw::SETBVAR_NONE,
102
+ :smallest_cardinality => Gecode::Raw::SETBVAR_MIN_CARD,
103
+ :largest_cardinality => Gecode::Raw::SETBVAR_MAX_CARD,
104
+ :smallest_unknown => Gecode::Raw::SETBVAR_MIN_UNKNOWN_ELEM,
105
+ :largest_unknown => Gecode::Raw::SETBVAR_MAX_UNKNOWN_ELEM
106
+ }
107
+
108
+ # Maps the names of the supported value branch strategies for integers and
109
+ # booleans to the corresponding constant in Gecode.
110
+ BRANCH_INT_VALUE_CONSTANTS = { #:nodoc:
111
+ :min => Gecode::Raw::BVAL_MIN,
112
+ :med => Gecode::Raw::BVAL_MED,
113
+ :max => Gecode::Raw::BVAL_MAX,
114
+ :split_min => Gecode::Raw::BVAL_SPLIT_MIN,
115
+ :split_max => Gecode::Raw::BVAL_SPLIT_MAX
116
+ }
117
+ # Maps the names of the supported value branch strategies for sets to the
118
+ # corresponding constant in Gecode.
119
+ BRANCH_SET_VALUE_CONSTANTS = { #:nodoc:
120
+ :min => Gecode::Raw::SETBVAL_MIN,
121
+ :max => Gecode::Raw::SETBVAL_MAX
122
+ }
123
+ end
124
+
125
+ # Adds a branching selection for the specified variable with the specified
126
+ # options. The hashes are used to decode the options into Gecode's
127
+ # constants.
128
+ def add_branch(variables, options, branch_var_hash, branch_value_hash)
129
+ # Extract optional arguments.
130
+ var_strat = options.delete(:variable) || :none
131
+ val_strat = options.delete(:value) || :min
132
+
133
+ # Check that the options are correct.
134
+ unless options.empty?
135
+ raise ArgumentError, 'Unknown branching option given: ' +
136
+ options.keys.join(', ')
137
+ end
138
+ unless branch_var_hash.include? var_strat
139
+ raise ArgumentError, "Unknown variable selection strategy: #{var_strat}"
140
+ end
141
+ unless branch_value_hash.include? val_strat
142
+ raise ArgumentError, "Unknown value selection strategy: #{val_strat}"
143
+ end
144
+
145
+ # Add the branching as a gecode interaction.
146
+ add_interaction do
147
+ Gecode::Raw.branch(active_space, variables.to_var_array,
148
+ branch_var_hash[var_strat], branch_value_hash[val_strat])
149
+ end
150
+ end
151
+ end
152
+ end