gecoder-with-gecode 0.7.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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