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.
- data/CHANGES +81 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +45 -0
- data/Rakefile +13 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +110 -0
- data/example/sudoku.rb +61 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +54 -0
- data/lib/gecoder/bindings/bindings.rb +2210 -0
- data/lib/gecoder/interface.rb +8 -0
- data/lib/gecoder/interface/binding_changes.rb +313 -0
- data/lib/gecoder/interface/branch.rb +152 -0
- data/lib/gecoder/interface/constraints.rb +397 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +153 -0
- data/lib/gecoder/interface/model.rb +251 -0
- data/lib/gecoder/interface/search.rb +123 -0
- data/lib/gecoder/interface/variables.rb +254 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/binding_changes.rb +76 -0
- data/specs/bool_var.rb +74 -0
- data/specs/branch.rb +170 -0
- data/specs/constraints/arithmetic.rb +266 -0
- data/specs/constraints/bool_enum.rb +140 -0
- data/specs/constraints/boolean.rb +232 -0
- data/specs/constraints/cardinality.rb +154 -0
- data/specs/constraints/channel.rb +126 -0
- data/specs/constraints/connection.rb +373 -0
- data/specs/constraints/constraint_helper.rb +180 -0
- data/specs/constraints/constraints.rb +74 -0
- data/specs/constraints/count.rb +139 -0
- data/specs/constraints/distinct.rb +218 -0
- data/specs/constraints/element.rb +106 -0
- data/specs/constraints/equality.rb +31 -0
- data/specs/constraints/int_domain.rb +69 -0
- data/specs/constraints/int_relation.rb +78 -0
- data/specs/constraints/linear.rb +332 -0
- data/specs/constraints/reification_sugar.rb +96 -0
- data/specs/constraints/selection.rb +292 -0
- data/specs/constraints/set_domain.rb +181 -0
- data/specs/constraints/set_operation.rb +285 -0
- data/specs/constraints/set_relation.rb +201 -0
- data/specs/constraints/sort.rb +175 -0
- data/specs/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +122 -0
- data/specs/int_var.rb +144 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +190 -0
- data/specs/search.rb +246 -0
- data/specs/set_var.rb +68 -0
- data/specs/spec_helper.rb +93 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/building.howto +65 -0
- data/tasks/distribution.rake +156 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/specs.rake +15 -0
- data/tasks/svn.rake +11 -0
- data/tasks/website.rake +51 -0
- data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +339 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +98 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- 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
|