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