gecoder 0.7.0 → 0.7.1
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 +6 -0
- data/README +1 -1
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +107 -0
- data/example/sudoku.rb +2 -6
- data/lib/gecoder/bindings.rb +1 -1
- data/lib/gecoder/bindings/bindings.rb +20 -0
- data/lib/gecoder/interface/binding_changes.rb +2 -2
- data/lib/gecoder/interface/branch.rb +50 -51
- data/lib/gecoder/interface/constraints.rb +10 -10
- data/lib/gecoder/interface/constraints/bool/boolean.rb +79 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +34 -4
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +14 -9
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +26 -8
- data/lib/gecoder/interface/constraints/int/domain.rb +30 -3
- data/lib/gecoder/interface/constraints/int/linear.rb +82 -16
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +31 -3
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +63 -3
- data/lib/gecoder/interface/constraints/int_enum/count.rb +20 -3
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +22 -2
- data/lib/gecoder/interface/constraints/int_enum/element.rb +23 -4
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +9 -2
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +28 -3
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +1 -1
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +13 -8
- data/lib/gecoder/interface/constraints/set/cardinality.rb +27 -8
- data/lib/gecoder/interface/constraints/set/connection.rb +72 -6
- data/lib/gecoder/interface/constraints/set/domain.rb +46 -3
- data/lib/gecoder/interface/constraints/set/operation.rb +35 -4
- data/lib/gecoder/interface/constraints/set/relation.rb +59 -6
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +22 -3
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +26 -2
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +110 -36
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +11 -7
- data/lib/gecoder/interface/model.rb +6 -6
- data/lib/gecoder/interface/search.rb +6 -6
- data/lib/gecoder/interface/variables.rb +56 -12
- data/lib/gecoder/version.rb +1 -1
- data/specs/constraints/linear.rb +167 -1
- data/specs/constraints/set_domain.rb +6 -0
- data/tasks/distribution.rake +25 -3
- data/tasks/website.rake +5 -12
- metadata +10 -4
- data/vendor/rust/configure.rb +0 -6
- data/vendor/rust/out.rb +0 -627
data/CHANGES
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== Version 0.7.1
|
2
|
+
This release adds boolean linear constraints.
|
3
|
+
|
4
|
+
* Set domain constraints now checks illegal parameters when it's added (rather than when the search begins).
|
5
|
+
* Added boolean linear constraint.
|
6
|
+
|
1
7
|
== Version 0.7.0
|
2
8
|
This release adds the set selection and operation constraints.
|
3
9
|
|
data/README
CHANGED
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/example_helper'
|
2
|
+
|
3
|
+
# Solves the square tiling problem. The objective is to pack supplied squares
|
4
|
+
# into a bigger rectangle so that there is no overlap.
|
5
|
+
class SquareTiling < Gecode::Model
|
6
|
+
# Takes the width and height of the rectangle to pack the squares into. Then
|
7
|
+
# the sizes of the squares that should be packed into the rectangle. The sizes
|
8
|
+
# must be sorted.
|
9
|
+
def initialize(width, height, square_sizes)
|
10
|
+
@sizes = square_sizes
|
11
|
+
@square_count = @sizes.size
|
12
|
+
|
13
|
+
# The coordinates of the placed squares.
|
14
|
+
@xs = int_var_array(@square_count, 0..(width - @sizes.min))
|
15
|
+
@ys = int_var_array(@square_count, 0..(height - @sizes.min))
|
16
|
+
|
17
|
+
# The essential constraints of the problem.
|
18
|
+
@square_count.times do |i|
|
19
|
+
# Each square must be placed within the bounds
|
20
|
+
@xs[i].must <= width - @sizes[i]
|
21
|
+
@ys[i].must <= height - @sizes[i]
|
22
|
+
|
23
|
+
# Pairwise conditions, no pair of squares may overlap.
|
24
|
+
0.upto(i - 1) do |j|
|
25
|
+
# That the two squares don't overlap means that i is left of j,
|
26
|
+
# or j is left of i, or i is above j, or j is above i.
|
27
|
+
((@xs[j] - @xs[i]).must >= @sizes[i]) |
|
28
|
+
((@xs[i] - @xs[j]).must >= @sizes[j]) |
|
29
|
+
((@ys[j] - @ys[i]).must >= @sizes[i]) |
|
30
|
+
((@ys[i] - @ys[j]).must >= @sizes[j])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# A couple of implied constraints that only serve to make the solving
|
35
|
+
# faster:
|
36
|
+
|
37
|
+
# The combined size of all squares occupying a column must be equal to the
|
38
|
+
# total height.
|
39
|
+
occupied_length_must_equal_total_length(height, width, @xs)
|
40
|
+
# The combined size of all squares occupying a row must be equal to the
|
41
|
+
# total width.
|
42
|
+
occupied_length_must_equal_total_length(width, height, @ys)
|
43
|
+
|
44
|
+
# Symmetry-breaking constraint: Order squares of the same size.
|
45
|
+
@square_count.times do |i|
|
46
|
+
@xs[i].must <= @xs[i+1] if @sizes[i] == @sizes[i+1]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Place the squares left to right on the x-axis first, then the y-axis.
|
50
|
+
branch_on @xs, :variable => :smallest_min, :value => :min
|
51
|
+
branch_on @ys, :variable => :smallest_min, :value => :min
|
52
|
+
end
|
53
|
+
|
54
|
+
# Constrains the combined length of the squares in the same row or column to
|
55
|
+
# equal +total_length+ in the axis of the specified coordinates +coords+,
|
56
|
+
# which is +axist_length+ long.
|
57
|
+
def occupied_length_must_equal_total_length(total_length, axis_length, coords)
|
58
|
+
axis_length.times do |i|
|
59
|
+
# We create an array of boolean variables and constrain it so that element
|
60
|
+
# +j+ is true iff square +j+ occupies +i+ (+i+ being a row or column).
|
61
|
+
occupied = bool_var_array(@square_count)
|
62
|
+
occupied.each_with_index do |is_occupying, j|
|
63
|
+
coords[j].must_be.in((i - @sizes[j] + 1)..i, :reify => is_occupying)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Constrain the combined length of squares that are occupying +i+ to equal
|
67
|
+
# the total length. We multiply the sizes with the boolean variables
|
68
|
+
# since a boolean in linear equation is 0 if assigned false and 1 if
|
69
|
+
# assigned true. Hence we will mask out the sizes of any squares not in
|
70
|
+
# +i+.
|
71
|
+
occupied_sizes = occupied.zip(@sizes).map{ |bool, size| bool*size }
|
72
|
+
occupied_sizes.inject(0){ |sum, x| x + sum }.must.equal(total_length,
|
73
|
+
:strength => :domain)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Displays the corrdinates of the squares.
|
78
|
+
# TODO: Something more impressive.
|
79
|
+
def to_s
|
80
|
+
@xs.values.zip(@ys.values).map{ |x,y| "(#{x}, #{y})"}.join(', ')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
puts(SquareTiling.new(65, 47, [25, 24, 23, 22, 19, 17, 11, 6, 5, 3]).solve! || 'Failed').to_s
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/example_helper'
|
2
|
+
require 'enumerator'
|
3
|
+
|
4
|
+
# Solves the sudoku problem using sets. The model used is a fairly direct
|
5
|
+
# translation of the corresponding Gecode example:
|
6
|
+
# http://www.gecode.org/gecode-doc-latest/sudoku-set_8cc-source.html .
|
7
|
+
class SudokuSet < Gecode::Model
|
8
|
+
# Takes a 9x9 matrix of values in the initial sudoku, 0 if the square is
|
9
|
+
# empty.
|
10
|
+
def initialize(predefined_values)
|
11
|
+
unless predefined_values.column_size == 9 and
|
12
|
+
predefined_values.row_size == 9
|
13
|
+
raise ArgumentError, 'The matrix with predefined values must have ' +
|
14
|
+
'dimensions 9x9.'
|
15
|
+
end
|
16
|
+
|
17
|
+
@size = n = predefined_values.row_size
|
18
|
+
sub_matrix_size = Math.sqrt(n).round
|
19
|
+
|
20
|
+
# Create one set per assignable number (i.e. 1..9). Each set contains the
|
21
|
+
# position of all squares that the number is located in. The squares are
|
22
|
+
# given numbers from 1 to 81. Each set therefore has an empty lower bound
|
23
|
+
# (since we have no guarantees where a number will end up) and 1..81 as
|
24
|
+
# upper bound (as it may potentially occurr in any square). We know that
|
25
|
+
# each assignable number must occurr 9 times in a solved sudoku, so we
|
26
|
+
# set the cardinality to 9..9 .
|
27
|
+
@sets = set_var_array(n, [], 1..n*n, n..n)
|
28
|
+
predefined_values.row_size.times do |i|
|
29
|
+
predefined_values.column_size.times do |j|
|
30
|
+
unless predefined_values[i,j].zero?
|
31
|
+
# We add the constraint that the square position must occurr in the
|
32
|
+
# set corresponding to the predefined value.
|
33
|
+
@sets[predefined_values[i,j] - 1].must_be.superset_of [i*n + j+1]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Build arrays containing the square positions of each row and column.
|
39
|
+
rows = []
|
40
|
+
columns = []
|
41
|
+
n.times do |i|
|
42
|
+
rows << ((i*n + 1)..(i*n + 9))
|
43
|
+
columns << [1, 10, 19, 28, 37, 46, 55, 64, 73].map{ |e| e + i }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Build arrays containing the square positions of each block.
|
47
|
+
blocks = []
|
48
|
+
sub_matrix_size.times do |i|
|
49
|
+
sub_matrix_size.times do |j|
|
50
|
+
blocks << [1, 2, 3, 10, 11, 12, 19, 20, 21].map{ |e| e + (j*27)+(i*3) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# All sets must be pairwise disjoint since two numbers can't be assigned to
|
55
|
+
# the same square.
|
56
|
+
n.times do |i|
|
57
|
+
(i + 1).upto(n - 1) do |j|
|
58
|
+
@sets[i].must_be.disjoint_with @sets[j]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# The above implies that the sets must be distinct (since cardinality 0 is
|
62
|
+
# not allowed), but we also explicitly add the distinctness constraint.
|
63
|
+
@sets.must_be.distinct(:size => n)
|
64
|
+
|
65
|
+
# The sets must intersect in exactly one element with each row column and
|
66
|
+
# block. I.e. an assignable number must be assigned exactly once in each
|
67
|
+
# row, column and block. We specify the constraint by expressing that the
|
68
|
+
# intersection must be equal with a set variable with cardinality 1.
|
69
|
+
@sets.each do |set|
|
70
|
+
rows.each do |row|
|
71
|
+
set.intersection(row).must == set_var([], 1..n*n, 1..1)
|
72
|
+
end
|
73
|
+
columns.each do |column|
|
74
|
+
set.intersection(column).must == set_var([], 1..n*n, 1..1)
|
75
|
+
end
|
76
|
+
blocks.each do |block|
|
77
|
+
set.intersection(block).must == set_var([], 1..n*n, 1..1)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Branching.
|
82
|
+
branch_on @sets, :variable => :none, :value => :min
|
83
|
+
end
|
84
|
+
|
85
|
+
# Outputs the assigned numbers in a grid.
|
86
|
+
def to_s
|
87
|
+
squares = []
|
88
|
+
@sets.values.each_with_index do |positions, i|
|
89
|
+
positions.each{ |square_position| squares[square_position - 1] = i + 1 }
|
90
|
+
end
|
91
|
+
squares.enum_slice(@size).map{ |slice| slice.join(' ') }.join("\n")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
predefined_squares = Matrix[
|
96
|
+
[0,0,0, 2,0,5, 0,0,0],
|
97
|
+
[0,9,0, 0,0,0, 7,3,0],
|
98
|
+
[0,0,2, 0,0,9, 0,6,0],
|
99
|
+
|
100
|
+
[2,0,0, 0,0,0, 4,0,9],
|
101
|
+
[0,0,0, 0,7,0, 0,0,0],
|
102
|
+
[6,0,9, 0,0,0, 0,0,1],
|
103
|
+
|
104
|
+
[0,8,0, 4,0,0, 1,0,0],
|
105
|
+
[0,6,3, 0,0,0, 0,8,0],
|
106
|
+
[0,0,0, 6,0,8, 0,0,0]]
|
107
|
+
puts(SudokuSet.new(predefined_squares).solve! || 'Failed').to_s
|
data/example/sudoku.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/example_helper'
|
2
|
+
require 'enumerator'
|
2
3
|
|
3
4
|
# Solves the sudoku problem: http://en.wikipedia.org/wiki/Soduko
|
4
5
|
class Sudoku < Gecode::Model
|
@@ -41,12 +42,7 @@ class Sudoku < Gecode::Model
|
|
41
42
|
|
42
43
|
# Display the solved sudoku in a grid.
|
43
44
|
def to_s
|
44
|
-
|
45
|
-
res = (0...@size).inject(separator) do |s, i|
|
46
|
-
(0...@size).inject(s + '|') do |s, j|
|
47
|
-
s << " #{@squares[i,j].value} |"
|
48
|
-
end << "\n" << separator
|
49
|
-
end
|
45
|
+
@squares.values.enum_slice(@size).map{ |slice| slice.join(' ') }.join("\n")
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
data/lib/gecoder/bindings.rb
CHANGED
@@ -518,6 +518,26 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
|
|
518
518
|
method.add_parameter "bool", "share"
|
519
519
|
method.add_parameter "Gecode::BoolVar", "x"
|
520
520
|
end
|
521
|
+
|
522
|
+
klass.add_operator "+", "Gecode::MiniModel::LinExpr" do |operator|
|
523
|
+
operator.add_parameter("int", "i")
|
524
|
+
end
|
525
|
+
|
526
|
+
klass.add_operator "-", "Gecode::MiniModel::LinExpr" do |operator|
|
527
|
+
operator.add_parameter("int", "i")
|
528
|
+
end
|
529
|
+
|
530
|
+
klass.add_operator "*", "Gecode::MiniModel::LinExpr" do |operator|
|
531
|
+
operator.add_parameter("int", "i")
|
532
|
+
end
|
533
|
+
|
534
|
+
klass.add_operator "!=", "Gecode::MiniModel::LinRel", "different" do |operator|
|
535
|
+
operator.add_parameter("Gecode::IntVar", "other")
|
536
|
+
end
|
537
|
+
|
538
|
+
klass.add_operator "==", "Gecode::MiniModel::LinRel", "equal" do |operator|
|
539
|
+
operator.add_parameter("Gecode::IntVar", "other")
|
540
|
+
end
|
521
541
|
end
|
522
542
|
|
523
543
|
ns.add_cxx_class "SetVar" do |klass|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
#
|
7
7
|
# This layer should be moved to the C++ side instead when possible for better
|
8
8
|
# performance.
|
9
|
-
module GecodeRaw
|
9
|
+
module GecodeRaw #:nodoc: all
|
10
10
|
class Space
|
11
11
|
# Creates the specified number of integer variables in the space with the
|
12
12
|
# specified domain. Returns the indices with which they can then be
|
@@ -93,7 +93,7 @@ end
|
|
93
93
|
|
94
94
|
module Gecode
|
95
95
|
# Various utility (mainly used to change the behavior of the raw bindings).
|
96
|
-
module Util
|
96
|
+
module Util #:nodoc: all
|
97
97
|
# Provides common methods to the variable stores. The stores must provide
|
98
98
|
# @next_index, @var_array, @size, ARRAY_IDENTIFIER and #new_storage_array .
|
99
99
|
module VarStoreMethods
|
@@ -1,52 +1,5 @@
|
|
1
1
|
module Gecode
|
2
2
|
class Model
|
3
|
-
private
|
4
|
-
|
5
|
-
# Maps the names of the supported variable branch strategies for integer and
|
6
|
-
# booleans to the corresponding constant in Gecode.
|
7
|
-
BRANCH_INT_VAR_CONSTANTS = {
|
8
|
-
:none => Gecode::Raw::BVAR_NONE,
|
9
|
-
:smallest_min => Gecode::Raw::BVAR_MIN_MIN,
|
10
|
-
:largest_min => Gecode::Raw::BVAR_MIN_MAX,
|
11
|
-
:smallest_max => Gecode::Raw::BVAR_MAX_MIN,
|
12
|
-
:largest_max => Gecode::Raw::BVAR_MAX_MAX,
|
13
|
-
:smallest_size => Gecode::Raw::BVAR_SIZE_MIN,
|
14
|
-
:largest_size => Gecode::Raw::BVAR_SIZE_MAX,
|
15
|
-
:smallest_degree => Gecode::Raw::BVAR_DEGREE_MIN,
|
16
|
-
:largest_degree => Gecode::Raw::BVAR_DEGREE_MAX,
|
17
|
-
:smallest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MIN,
|
18
|
-
:largest_min_regret => Gecode::Raw::BVAR_REGRET_MIN_MAX,
|
19
|
-
:smallest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MIN,
|
20
|
-
:largest_max_regret => Gecode::Raw::BVAR_REGRET_MAX_MAX
|
21
|
-
}
|
22
|
-
# Maps the names of the supported variable branch strategies for sets to
|
23
|
-
# the corresponding constant in Gecode.
|
24
|
-
BRANCH_SET_VAR_CONSTANTS = {
|
25
|
-
:none => Gecode::Raw::SETBVAR_NONE,
|
26
|
-
:smallest_cardinality => Gecode::Raw::SETBVAR_MIN_CARD,
|
27
|
-
:largest_cardinality => Gecode::Raw::SETBVAR_MAX_CARD,
|
28
|
-
:smallest_unknown => Gecode::Raw::SETBVAR_MIN_UNKNOWN_ELEM,
|
29
|
-
:largest_unknown => Gecode::Raw::SETBVAR_MAX_UNKNOWN_ELEM
|
30
|
-
}
|
31
|
-
|
32
|
-
# Maps the names of the supported value branch strategies for integers and
|
33
|
-
# booleans to the corresponding constant in Gecode.
|
34
|
-
BRANCH_INT_VALUE_CONSTANTS = {
|
35
|
-
:min => Gecode::Raw::BVAL_MIN,
|
36
|
-
:med => Gecode::Raw::BVAL_MED,
|
37
|
-
:max => Gecode::Raw::BVAL_MAX,
|
38
|
-
:split_min => Gecode::Raw::BVAL_SPLIT_MIN,
|
39
|
-
:split_max => Gecode::Raw::BVAL_SPLIT_MAX
|
40
|
-
}
|
41
|
-
# Maps the names of the supported value branch strategies for sets to the
|
42
|
-
# corresponding constant in Gecode.
|
43
|
-
BRANCH_SET_VALUE_CONSTANTS = {
|
44
|
-
:min => Gecode::Raw::SETBVAL_MIN,
|
45
|
-
:max => Gecode::Raw::SETBVAL_MAX
|
46
|
-
}
|
47
|
-
|
48
|
-
public
|
49
|
-
|
50
3
|
# Specifies which variables that should be branched on. One can optionally
|
51
4
|
# also select which of the variables that should be used first with the
|
52
5
|
# :variable option and which value in that variable's domain that should be
|
@@ -111,11 +64,11 @@ module Gecode
|
|
111
64
|
def branch_on(variables, options = {})
|
112
65
|
if variables.respond_to? :to_int_var_array or
|
113
66
|
variables.respond_to? :to_bool_var_array
|
114
|
-
add_branch(variables, options, BRANCH_INT_VAR_CONSTANTS,
|
115
|
-
BRANCH_INT_VALUE_CONSTANTS)
|
67
|
+
add_branch(variables, options, Constants::BRANCH_INT_VAR_CONSTANTS,
|
68
|
+
Constants::BRANCH_INT_VALUE_CONSTANTS)
|
116
69
|
elsif variables.respond_to? :to_set_var_array
|
117
|
-
add_branch(variables, options, BRANCH_SET_VAR_CONSTANTS,
|
118
|
-
BRANCH_SET_VALUE_CONSTANTS)
|
70
|
+
add_branch(variables, options, Constants::BRANCH_SET_VAR_CONSTANTS,
|
71
|
+
Constants::BRANCH_SET_VALUE_CONSTANTS)
|
119
72
|
else
|
120
73
|
raise TypeError, "Unknown type of variable enum #{variables.class}."
|
121
74
|
end
|
@@ -123,6 +76,52 @@ module Gecode
|
|
123
76
|
|
124
77
|
private
|
125
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
|
+
|
126
125
|
# Adds a branching selection for the specified variable with the specified
|
127
126
|
# options. The hashes are used to decode the options into Gecode's
|
128
127
|
# constants.
|
@@ -10,15 +10,15 @@ module Gecode
|
|
10
10
|
# as left hand sides (i.e. the part before must*) when specifying
|
11
11
|
# constraints. Assumes that a method #expression is defined which produces
|
12
12
|
# a new expression given the current constraint parameters.
|
13
|
-
module LeftHandSideMethods
|
14
|
-
# Specifies that a constraint must hold for the
|
13
|
+
module LeftHandSideMethods #:nodoc:
|
14
|
+
# Specifies that a constraint must hold for the keft hand side.
|
15
15
|
def must
|
16
16
|
expression update_params(:negate => false)
|
17
17
|
end
|
18
18
|
alias_method :must_be, :must
|
19
19
|
|
20
|
-
# Specifies that the negation of a constraint must hold for the
|
21
|
-
#
|
20
|
+
# Specifies that the negation of a constraint must hold for the left hand
|
21
|
+
# side.
|
22
22
|
def must_not
|
23
23
|
expression update_params(:negate => true)
|
24
24
|
end
|
@@ -34,7 +34,7 @@ module Gecode
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# A module that provides some utility-methods for constraints.
|
37
|
-
module Util
|
37
|
+
module Util #:nodoc:
|
38
38
|
# Maps the name used in options to the value used in Gecode for
|
39
39
|
# propagation strengths.
|
40
40
|
PROPAGATION_STRENGTHS = {
|
@@ -193,7 +193,7 @@ module Gecode
|
|
193
193
|
# Describes a constraint expressions. An expression is produced by calling
|
194
194
|
# some form of must on a left hand side. The expression waits for a right
|
195
195
|
# hand side so that it can post the corresponding constraint.
|
196
|
-
class Expression
|
196
|
+
class Expression #:nodoc:
|
197
197
|
# Constructs a new expression with the specified parameters. The
|
198
198
|
# parameters shoud at least contain the keys :lhs, and :negate.
|
199
199
|
#
|
@@ -235,7 +235,7 @@ module Gecode
|
|
235
235
|
|
236
236
|
# A composite expression which is a expression with a left hand side
|
237
237
|
# resulting from a previous constraint.
|
238
|
-
class CompositeExpression < Gecode::Constraints::Expression
|
238
|
+
class CompositeExpression < Gecode::Constraints::Expression #:nodoc:
|
239
239
|
# The expression class should be the class of the expression delegated to,
|
240
240
|
# the variable class the kind of single variable used in the expression.
|
241
241
|
# The new var proc should produce a new variable (of the appropriate type)
|
@@ -300,7 +300,7 @@ module Gecode
|
|
300
300
|
#
|
301
301
|
# The call of with_offsets initiates the constraint as a stub, even though
|
302
302
|
# must has not yet been called.
|
303
|
-
class ExpressionStub
|
303
|
+
class ExpressionStub #:nodoc:
|
304
304
|
# Constructs a new expression with the specified parameters.
|
305
305
|
def initialize(model, params)
|
306
306
|
@model = model
|
@@ -311,7 +311,7 @@ module Gecode
|
|
311
311
|
# Describes an expression stub which includes left hand side methods and
|
312
312
|
# just sends models and parameters through a supplied block to construct the
|
313
313
|
# resulting expression.
|
314
|
-
class SimpleExpressionStub < ExpressionStub
|
314
|
+
class SimpleExpressionStub < ExpressionStub #:nodoc:
|
315
315
|
include Gecode::Constraints::LeftHandSideMethods
|
316
316
|
|
317
317
|
# The block provided is executed when the expression demanded by the left
|
@@ -342,7 +342,7 @@ module Gecode
|
|
342
342
|
# ".must > rhs" is then applied to. In the above case two constraints (and
|
343
343
|
# one temporary variable) are required, but in the case of equality only
|
344
344
|
# one constraint is required.
|
345
|
-
class CompositeStub < Gecode::Constraints::ExpressionStub
|
345
|
+
class CompositeStub < Gecode::Constraints::ExpressionStub #:nodoc:
|
346
346
|
include Gecode::Constraints::LeftHandSideMethods
|
347
347
|
|
348
348
|
# The composite expression class should be the class that the stub uses
|