gecoder 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,9 @@
1
+ == Version 1.1.0
2
+ This release fixes a compilation error when installing the gecoder-with-gecode gem using GCC 4.4+ .
3
+
4
+ * Added the :time_limit to Gecode#solve! which can be used to limit the amount of time that the solver is allowed to search for a solution.
5
+ * [#29630] Fixed compilation errors when installing gecoder-with-gecode using GCC 4.4+ .
6
+
1
7
  == Version 1.0.0
2
8
  This release represents a commitment to the current syntax.
3
9
 
@@ -10,7 +16,7 @@ This release changes the preferred way of defining a model to including Gecode::
10
16
  * Updated the backend to Gecode 2.2.0. See http://www.gecode.org/gecode-doc-latest/PageChanges_2_2_0.html for a list of changes.
11
17
 
12
18
  == Version 0.9.0
13
- This release adds a generous amount of sugar designed to cut down on often
19
+ This release adds a generous amount of sugar designed to cut down on often
14
20
  repeated code. It also adds the ability to freely combine constraints
15
21
  without needing temporary variables.
16
22
 
@@ -24,11 +30,11 @@ without needing temporary variables.
24
30
  * [#21580] Fixed a bug that caused ranges that use three dots to not be correctly interpreted by the negated integer domain constraint.
25
31
  * [#21581] Fixed a bug that caused the abs constraint to prune away valid solutions in some cases.
26
32
 
27
- == Version 0.8.3
33
+ == Version 0.8.3
28
34
  This release adds regular expression constraints, the last channel
29
35
  constraint and various minor convenience improvements. It also fixes a
30
36
  rather serious bug that occurs when using the latest patchlevels of Ruby
31
- 1.8.6.
37
+ 1.8.6.
32
38
 
33
39
  * [#20888] Fixed a GC bug causing problems with Ruby 1.8.6 at patchlevels around 230.
34
40
  * Boolean constraints can no longer be specified using the form "bool.must == true". Only the "bool.must_be.true" form can now be used.
@@ -39,7 +45,7 @@ rather serious bug that occurs when using the latest patchlevels of Ruby
39
45
  * Added integer and boolean regular expression constraints. Thanks goes to Eivind Eklund for providing the idea for the syntax used to specify the regular expressions.
40
46
 
41
47
  == Version 0.8.2
42
- This release adds search statistics along with some new arithmetic constraints
48
+ This release adds search statistics along with some new arithmetic constraints
43
49
  and channel constraints between boolean and integer variables.
44
50
 
45
51
  * Wrapping an enumerable that is already wrapped is no longer allowed.
@@ -49,17 +55,17 @@ and channel constraints between boolean and integer variables.
49
55
  * Added channel constraints between enumerations of boolean variables and single integer variables.
50
56
 
51
57
  == Version 0.8.1
52
- This release adds tuple constraints along with a couple of minor features. It
58
+ This release adds tuple constraints along with a couple of minor features. It
53
59
  also fixes a bug introduced in the previous version.
54
60
 
55
61
  * [#19435] Fixed a bug causing inconsistencies during BAB-search. The bug stopped the send+more=money example from working correctly.
56
62
  * Fixed the "raw_bindings" and "sudoku-set" examples, which were broken by the 0.8.0 release.
57
- * Integers can now be used to specify singleton lower and upper bounds when creating set variables.
63
+ * Integers can now be used to specify singleton lower and upper bounds when creating set variables.
58
64
  * Added convenience methods Model#maximize! and Model#minimize! for optimizing single variables.
59
65
  * Added tuple constraints for enumerations of integer and boolean variables.
60
66
 
61
67
  == Version 0.8.0
62
- This release makes the jump from using Gecode 1.3.1 to using Gecode 2.1.1 .
68
+ This release makes the jump from using Gecode 1.3.1 to using Gecode 2.1.1 .
63
69
  The following changes have been made to the interface as a result of the jump.
64
70
 
65
71
  * Removed the distinct constraint for sets.
@@ -87,7 +93,7 @@ int variable domains are specified (breaking backward-compatibility).
87
93
  * Variables can now be created inside the optimization block.
88
94
 
89
95
  == Version 0.6.0
90
- This release adds most of the remaining set constraints. It also makes
96
+ This release adds most of the remaining set constraints. It also makes
91
97
  backward-compatibility breaking changes to the way that properties of variables
92
98
  are accessed.
93
99
 
@@ -101,7 +107,7 @@ are accessed.
101
107
  * Enumerations containing variables now provide a convenience method #values which returns an array of the enum's values.
102
108
 
103
109
  == Version 0.5.0
104
- This release adds set variables and some of their constraints, along with the
110
+ This release adds set variables and some of their constraints, along with the
105
111
  last of the boolean constraints.
106
112
 
107
113
  * Added exclusive or and implication.
@@ -125,7 +131,7 @@ This release adds most of the integer variable constraints supported by Gecode.
125
131
  * Added arithmetic constraints (min, max, abs and variable multiplication).
126
132
 
127
133
  == Version 0.3.0
128
- This release fleshes out the existing constraints with things such as
134
+ This release fleshes out the existing constraints with things such as
129
135
  reification and adds boolean variables and their basic constraints.
130
136
 
131
137
  * The constructor of Gecode::Model no longer has to be called by classes inheriting from it.
data/THANKS CHANGED
@@ -1,18 +1,19 @@
1
1
  This is a list of people who have contributed to making Gecode/R what it
2
2
  is today. It is sorted in alphabetical order by last name.
3
3
 
4
- * David Cuadrado - For the initial raw bindings from Gecode to Ruby.
5
- * Eivind Eklund - For the idea that led to the syntax used to specify
4
+ * David Cuadrado - Created the initial raw bindings from Gecode to Ruby.
5
+ * Eivind Eklund - Provided the idea that led to the syntax used to specify
6
6
  the regular expressions used in regexp constraints.
7
- * Google and Ruby Central - For the funding through Google Summer of
8
- Code 2007 that got the project started.
9
- * James Edward Gray II - For the superb mentoring during Google Summer
7
+ * Google and Ruby Central - Got the project started with funding through
8
+ Google Summer of Code 2007.
9
+ * James Edward Gray II - Provided superb mentoring during Google Summer
10
10
  of Code 2007, influencing many decisions made.
11
- * Mikael Lagerkvist - For the support from the Gecode side.
12
- * Andreas Launila - For the interface on top of the raw bindings and
11
+ * Hakan Kjellerstrand - Created many new example models.
12
+ * Mikael Lagerkvist - Provided support from the Gecode side.
13
+ * Andreas Launila - Created the interface on top of the raw bindings and
13
14
  the website.
14
- * Adam Rose - For suggesting that Gecode/R should use a mixin rather
15
- than inheritance.
15
+ * Adam Rose - Suggested that Gecode/R should use a mixin rather than
16
+ inheritance.
16
17
 
17
18
  If you think that you should be on this list then please contact the
18
19
  gecoder-devel mailing list.
@@ -0,0 +1,136 @@
1
+ # Copyright 2009, Hakan Kjellerstrand <hakank@bonetmail.com>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require File.dirname(__FILE__) + '/example_helper'
18
+ require 'enumerator'
19
+
20
+ #
21
+ # Minesweeper in Gecode/R
22
+ #
23
+ # From gecode/examples/minesweeper.cc:
24
+ # """
25
+ # A specification is a square matrix of characters. Alphanumeric
26
+ # characters represent the number of mines adjacent to that field.
27
+ # Dots represent fields with an unknown number of mines adjacent to
28
+ # it (or an actual mine).
29
+ # """
30
+ #
31
+ # E.g.
32
+ # "..2.3."
33
+ # "2....."
34
+ # "..24.3"
35
+ # "1.34.."
36
+ # ".....3"
37
+ # ".3.3.."
38
+ # """
39
+ #
40
+ # Also see
41
+ #
42
+ # http://www.janko.at/Raetsel/Minesweeper/index.htm
43
+ #
44
+ # http://en.wikipedia.org/wiki/Minesweeper_(computer_game)
45
+ #
46
+ # Ian Stewart on Minesweeper: http://www.claymath.org/Popular_Lectures/Minesweeper/
47
+ #
48
+ # Richard Kaye's Minesweeper Pages
49
+ # http://web.mat.bham.ac.uk/R.W.Kaye/minesw/minesw.htm
50
+ # Some Minesweeper Configurations
51
+ # http://web.mat.bham.ac.uk/R.W.Kaye/minesw/minesw.pdf
52
+ #
53
+ # Compare with my other Minesweeper models:
54
+ #
55
+ # - MiniZinc: http://www.hakank.org/minizinc/minesweeper.mzn
56
+ #
57
+ # - Choco: http://www.hakank.org/choco/MineSweeper.java
58
+ #
59
+ # - JaCoP: http://www.hakank.org/JaCoP/MineSweeper.java
60
+ #
61
+ #
62
+ # Model created by Hakan Kjellerstrand, hakank@bonetmail.com
63
+ # See also my Gecode/R page: http://www.hakank.org/gecode_r
64
+ #
65
+ # Slight modifications made by Andreas Launila to keep the example in
66
+ # line with the other example models.
67
+ class Minesweeper
68
+ include Gecode::Mixin
69
+
70
+ # The provided +game+ should be a matrix encoding the problem in the
71
+ # following way:
72
+ # -1 for the unknowns,
73
+ # >= 0 for number of mines in the neighbourhood
74
+ def initialize(game)
75
+ # Boolean variables representing whether each square has a mine or
76
+ # not.
77
+ mines_is_an bool_var_matrix(game.row_size, game.column_size)
78
+
79
+ # Place the constraints.
80
+ game.row_size.times do |i|
81
+ game.column_size.times do |j|
82
+ # The sum of all the number of mines in the neighbourhood of this cell
83
+ # must agree with the problem specification.
84
+ if game[i,j] >= 0 then
85
+ neighbourhood = mines.minor([i-1,0].max..(i+1), [j-1,0].max..(j+1))
86
+ neighbourhood.to_a.flatten.sum.must == game[i,j]
87
+ end
88
+
89
+ # A square can not contain a mine if the number of neighbouring
90
+ # mines is known.
91
+ if game[i,j] >= 0 then
92
+ mines[i,j].must_be.false
93
+ end
94
+ end
95
+ end
96
+
97
+ branch_on mines, :variable => :largest_degree, :value => :max
98
+ end
99
+ end
100
+
101
+ class Array
102
+ # A helper for summing the contents of an array.
103
+ def sum
104
+ inject{ |sum, x| sum + x }
105
+ end
106
+ end
107
+
108
+ # Problem from Gecode/examples/minesweeper.cc problem 2
109
+ X = -1 # unknowns
110
+ game = Matrix[
111
+ [1,X,X,2,X,2,X,2,X,X],
112
+ [X,3,2,X,X,X,4,X,X,1],
113
+ [X,X,X,1,3,X,X,X,4,X],
114
+ [3,X,1,X,X,X,3,X,X,X],
115
+ [X,2,1,X,1,X,X,3,X,2],
116
+ [X,3,X,2,X,X,2,X,1,X],
117
+ [2,X,X,3,2,X,X,2,X,X],
118
+ [X,3,X,X,X,3,2,X,X,3],
119
+ [X,X,3,X,3,3,X,X,X,X],
120
+ [X,2,X,2,X,X,X,2,2,X]
121
+ ]
122
+
123
+ minesweeper = Minesweeper.new(game)
124
+ # Find all of the solutions.
125
+ num_solutions = 0
126
+ minesweeper.each_solution do |s|
127
+ num_solutions += 1
128
+ puts "\nSolution ##{num_solutions}\n";
129
+ # Print the solution.
130
+ s.mines.values.enum_slice(s.mines.column_size).each do |row|
131
+ puts row.map{ |filled| filled ? "X " : ". " }.join
132
+ end
133
+ end
134
+
135
+ puts "\nNumber of solutions: #{num_solutions}"
136
+
@@ -0,0 +1,155 @@
1
+ # Copyright 2009, Hakan Kjellerstrand <hakank@bonetmail.com>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require File.dirname(__FILE__) + '/example_helper'
18
+ require 'enumerator'
19
+
20
+ #
21
+ # Nonogram (a.k.a. Painting by Numbers) in Gecode/R
22
+ #
23
+ # http://en.wikipedia.org/wiki/Nonogram
24
+ # """
25
+ # Nonograms or Paint by Numbers are picture logic puzzles in which cells
26
+ # in a grid have to be colored or left blank according to numbers given
27
+ # at the side of the grid to reveal a hidden picture. In this puzzle
28
+ # type, the numbers measure how many unbroken lines of filled-in squares
29
+ # there are in any given row or column. For example, a clue of "4 8 3"
30
+ # would mean there are sets of four, eight, and three filled squares, in
31
+ # that order, with at least one blank square between successive groups.
32
+ # """
33
+ #
34
+ # Also see
35
+ # * Brunetti, Sara & Daurat, Alain (2003)
36
+ # "An algorithm reconstructing convex lattice sets"
37
+ # http://geodisi.u-strasbg.fr/~daurat/papiers/tomoqconv.pdf
38
+ #
39
+ # * CSPLib problem 12 at http://www.csplib.org/
40
+ #
41
+ # * http://www.puzzlemuseum.com/nonogram.htm
42
+ #
43
+ # * Haskell solution:
44
+ # http://twan.home.fmf.nl/blog/haskell/Nonograms.details
45
+ #
46
+ # * My MiniZinc model http://www.hakank.org/minizinc/nonogram.mzn
47
+ #
48
+ #
49
+ # Model created by Hakan Kjellerstrand, hakank@bonetmail.com
50
+ # See also my Gecode/R page: http://www.hakank.org/gecode_r
51
+ #
52
+ # Slight modifications made by Andreas Launila to keep the example in
53
+ # line with the other example models.
54
+ class Nonogram
55
+ include Gecode::Mixin
56
+
57
+ def initialize(row_rules, col_rules)
58
+ # A matrix of variables where each variable represents whether the
59
+ # square has been filled in or not.
60
+ filled_is_an bool_var_matrix(row_rules.size, col_rules.size)
61
+
62
+ # Place the constraints on the rows.
63
+ row_rules.each_with_index do |row_rule, i|
64
+ filled.row(i).must.match parse_regex(row_rule)
65
+ end
66
+ # Place the constraints on the columns.
67
+ col_rules.each_with_index do |col_rule, i|
68
+ filled.column(i).must.match parse_regex(col_rule)
69
+ end
70
+
71
+ branch_on filled, :variable => :none, :value => :max
72
+ end
73
+
74
+ # Parses a nonogram segment and converts it to a "regexp"
75
+ # e.g. [3,2] -> [repeat(false), repeat(true,3,3), at_least_once(false),
76
+ # repeat(true,2,2),repeat(false)]
77
+ def parse_regex(a)
78
+ r = [repeat(false)]
79
+ a.each_with_index do |e,i|
80
+ r << repeat(true,e,e)
81
+ if i < a.length-1 then
82
+ r << at_least_once(false)
83
+ end
84
+ end
85
+ r << repeat(false)
86
+ return r
87
+ end
88
+ end
89
+
90
+ # A nonogram problem taken from Wikipedia
91
+ # http://en.wikipedia.org/wiki/Nonogram
92
+ # Animation:
93
+ # http://en.wikipedia.org/wiki/File:Paint_by_numbers_Animation.gif
94
+ #
95
+ row_rules =
96
+ [
97
+ [3],
98
+ [5],
99
+ [3,1],
100
+ [2,1],
101
+ [3,3,4],
102
+ [2,2,7],
103
+ [6,1,1],
104
+ [4,2,2],
105
+ [1,1],
106
+ [3,1],
107
+ [6],
108
+ [2,7],
109
+ [6,3,1],
110
+ [1,2,2,1,1],
111
+ [4,1,1,3],
112
+ [4,2,2],
113
+ [3,3,1],
114
+ [3,3],
115
+ [3],
116
+ [2,1]
117
+ ]
118
+
119
+ col_rules =
120
+ [
121
+ [2],
122
+ [1,2],
123
+ [2,3],
124
+ [2,3],
125
+ [3,1,1],
126
+ [2,1,1],
127
+ [1,1,1,2,2],
128
+ [1,1,3,1,3],
129
+ [2,6,4],
130
+ [3,3,9,1],
131
+ [5,3,2],
132
+ [3,1,2,2],
133
+ [2,1,7],
134
+ [3,3,2],
135
+ [2,4],
136
+ [2,1,2],
137
+ [2,2,1],
138
+ [2,2],
139
+ [1],
140
+ [1]
141
+ ]
142
+
143
+ nonogram = Nonogram.new(row_rules, col_rules)
144
+ # Find all of the solutions.
145
+ num_solutions = 0
146
+ nonogram.each_solution do |s|
147
+ num_solutions += 1
148
+ puts "\nSolution ##{num_solutions}\n"
149
+ # Output the solution.
150
+ s.filled.values.enum_slice(s.filled.column_size).each do |row|
151
+ puts row.map{ |filled| filled ? "#" : " " }.join
152
+ end
153
+ end
154
+
155
+ puts "\nNumber of solutions: #{num_solutions}"
@@ -0,0 +1,131 @@
1
+ # Copyright 2009, Hakan Kjellerstrand <hakank@bonetmail.com>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with this program; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require File.dirname(__FILE__) + '/example_helper'
18
+ require 'enumerator'
19
+
20
+ # Survo Puzzle in Gecode/R
21
+ #
22
+ # http://en.wikipedia.org/wiki/Survo_Puzzle
23
+ # """
24
+ # Survo puzzle is a kind of logic puzzle presented (in April 2006) and studied
25
+ # by Seppo Mustonen. The name of the puzzle is associated to Mustonen's
26
+ # Survo system which is a general environment for statistical computing and
27
+ # related areas.
28
+ #
29
+ # In a Survo puzzle the task is to fill an m * n table by integers 1,2,...,m*n so
30
+ # that each of these numbers appears only once and their row and column sums are
31
+ # equal to integers given on the bottom and the right side of the table.
32
+ # Often some of the integers are given readily in the table in order to
33
+ # guarantee uniqueness of the solution and/or for making the task easier.
34
+ # """
35
+ #
36
+ # See also
37
+ # http://www.survo.fi/english/index.html
38
+ # http://www.survo.fi/puzzles/index.html
39
+ #
40
+ # References:
41
+ # Mustonen, S. (2006b). "On certain cross sum puzzles", http://www.survo.fi/papers/puzzles.pdf
42
+ # Mustonen, S. (2007b). "Enumeration of uniquely solvable open Survo puzzles.", http://www.survo.fi/papers/enum_survo_puzzles.pdf
43
+ # Kimmo Vehkalahti: "Some comments on magic squares and Survo puzzles", http://www.helsinki.fi/~kvehkala/Kimmo_Vehkalahti_Windsor.pdf
44
+ # R code: http://koti.mbnet.fi/tuimala/tiedostot/survo.R
45
+ #
46
+ # Compare with my other Survo Puzzle models
47
+ #
48
+ # - MiniZinc: http://www.hakank.org/minizinc/survo_puzzle.mzn
49
+ # - JaCoP: http://www.hakank.org/JaCoP/SurvoPuzzle.java
50
+ # - Choco: http://www.hakank.org/choco/SurvoPuzzle.java
51
+ #
52
+ # Model created by Hakan Kjellerstrand, hakank@bonetmail.com
53
+ # See also my Gecode/R page: http://www.hakank.org/gecode_r
54
+ #
55
+ # Slight modifications made by Andreas Launila to keep the example in
56
+ # line with the other example models.
57
+ class SurvoPuzzle
58
+ include Gecode::Mixin
59
+
60
+ # The +clues+ are given as an m*n matrix where 0 represents that the
61
+ # cell has no clue. The row sums and column sums are specified by the
62
+ # +rowsums+ array of length m, and the +colsums+ array of length n
63
+ # respectively.
64
+ def initialize(clues, rowsums, colsums)
65
+ r = rowsums.length # Number of rows
66
+ c = colsums.length # Number of columns
67
+
68
+ # Integer variables representing each cell in the m*n table.
69
+ cells_is_an int_var_matrix(r, c, 1..r*c)
70
+
71
+ # Add the constraints.
72
+ # Each number must appear only once.
73
+ cells.must_be.distinct
74
+
75
+ # The row sums must be satisfied.
76
+ cells.row_vectors.each_with_index do |row, i|
77
+ row.sum.must == rowsums[i]
78
+ end
79
+
80
+ # The column sums must be satisfied.
81
+ cells.column_vectors.each_with_index do |column, i|
82
+ column.sum.must == colsums[i]
83
+ end
84
+
85
+ # The clues must be satisfied.
86
+ cells.row_size.times do |i|
87
+ cells.column_size.times do |j|
88
+ cells[i,j].must == clues[i,j] if clues[i,j] > 0
89
+ end
90
+ end
91
+
92
+ branch_on cells, :variable => :smallest_size, :value => :min
93
+ end
94
+ end
95
+
96
+ class Vector
97
+ # A helper for summing the contents of a vector.
98
+ def sum
99
+ inject{ |sum, element| sum + element }
100
+ end
101
+ end
102
+
103
+ # Default problem:
104
+ # Survo puzzle 126/2008 (25) #363-33148
105
+ # From http://www.survo.fi/puzzles/280708.txt
106
+ rowsums = [32,79,60]
107
+ colsums = [24,22,43,35,39,8]
108
+ clues = Matrix[
109
+ [ 0, 4, 0, 0, 0, 0,32],
110
+ [12, 0, 0,16,17, 0,79],
111
+ [ 0, 0,15, 0, 0, 2,60],
112
+ ]
113
+
114
+ survo_puzzle = SurvoPuzzle.new(clues, rowsums, colsums)
115
+ num_solutions = 0
116
+ survo_puzzle.each_solution do |s|
117
+ num_solutions += 1
118
+ puts "\nSolution ##{num_solutions}";
119
+ # Print the solution.
120
+ s.cells.values.enum_slice(s.cells.column_size).each_with_index do |row,i|
121
+ row.each{ |element| printf('%3d ', element) }
122
+ printf ' = %3d ', rowsums[i]
123
+ puts
124
+ end
125
+ colsums.size.times{ printf('%2s= ', '') }
126
+ puts
127
+ colsums.each{ |element| printf('%3d ', element) }
128
+ end
129
+
130
+ puts "\nNumber of solutions: #{num_solutions}"
131
+