rglpk 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ require File.expand_path('helper', File.dirname(__FILE__))
2
+
3
+ module TestProblemKind
4
+ def setup
5
+ @p = Rglpk::Problem.new
6
+ @p.obj.dir = Rglpk::GLP_MAX
7
+
8
+ cols = @p.add_cols(3)
9
+ cols[0].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
10
+ cols[1].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
11
+ cols[2].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
12
+
13
+ rows = @p.add_rows(3)
14
+
15
+ rows[0].set_bounds(Rglpk::GLP_UP, 0, 4)
16
+ rows[1].set_bounds(Rglpk::GLP_UP, 0, 5)
17
+ rows[2].set_bounds(Rglpk::GLP_UP, 0, 6)
18
+
19
+ @p.obj.coefs = [1, 1, 1]
20
+
21
+ @p.set_matrix([
22
+ 1, 1, 0,
23
+ 0, 1, 1,
24
+ 1, 0, 1
25
+ ])
26
+
27
+ @p.cols.each{|c| c.kind = column_kind}
28
+ end
29
+
30
+ def verify_results(*results)
31
+ if column_kind == Rglpk::GLP_CV
32
+ solution_method = :simplex
33
+ value_method = :get_prim
34
+ else
35
+ solution_method = :mip
36
+ value_method = :mip_val
37
+ end
38
+
39
+ @p.send(solution_method, {:presolve => Rglpk::GLP_ON})
40
+
41
+ @p.cols.each_with_index do |col, index|
42
+ assert_equal results[index], col.send(value_method)
43
+ end
44
+ end
45
+ end
46
+
47
+ class BinaryVariables < Test::Unit::TestCase
48
+ include TestProblemKind
49
+
50
+ def column_kind
51
+ Rglpk::GLP_BV
52
+ end
53
+
54
+ def test_results
55
+ verify_results(1, 1, 1)
56
+ end
57
+ end
58
+
59
+ class IntegerVariables < Test::Unit::TestCase
60
+ include TestProblemKind
61
+
62
+ def column_kind
63
+ Rglpk::GLP_IV
64
+ end
65
+
66
+ def test_results
67
+ verify_results(3, 1, 3)
68
+ end
69
+ end
70
+
71
+ class ContinuousVariables < Test::Unit::TestCase
72
+ include TestProblemKind
73
+
74
+ def column_kind
75
+ Rglpk::GLP_CV
76
+ end
77
+
78
+ def test_results
79
+ verify_results(2.5, 1.5, 3.5)
80
+ end
81
+ end
metadata CHANGED
@@ -1,70 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rglpk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Alex Gutteridge
14
+ - William Taysom
8
15
  autorequire:
9
16
  bindir: bin
10
17
  cert_chain: []
11
18
 
12
- date: 2008-11-19 00:00:00 +00:00
19
+ date: 2010-10-13 00:00:00 +08:00
13
20
  default_executable:
14
21
  dependencies: []
15
22
 
16
- description: Rglpk is a package providing a Ruby wrapper to the GNU glpk library (http://www.gnu.org/software/glpk/). The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems.
17
- email: alexg@kuicr.kyoto-u.ac.jp
23
+ description: |-
24
+ Rglpk is a package providing a Ruby wrapper to the [GNU GLPK](http://www.gnu.org/software/glpk/) library. The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems.
25
+
26
+ Rglpk (pronounced as "wriggle-pick") is currently in alpha status and the API should be considered subject to change. Rglpk uses [Swig](http://www.swig.org/) to initially wrap the C GLPK library (using a Swig wrapper originally developed by Nigel Galloway) and then a pure Ruby library to wrap the Swig code in a more friendly OO-style.
27
+
28
+ All bug reports, feature requests and patches are welcome. Please email alexg (at) kuicr.kyoto-u.ac.jp or use the [rubyforge forums](http://rubyforge.org/forum/?group_id=3943).
29
+ email:
30
+ - alexg@kuicr.kyoto-u.ac.jp
31
+ - wtaysom@gmail.com
18
32
  executables: []
19
33
 
20
34
  extensions:
21
35
  - ext/extconf.rb
36
+ - ext/extconf.rb
22
37
  extra_rdoc_files:
23
- - README.txt
24
- - History.txt
25
- - License.txt
38
+ - ChangeLog.md
39
+ - README.md
26
40
  files:
27
- - History.txt
41
+ - .gitignore
42
+ - ChangeLog.md
28
43
  - License.txt
29
- - Manifest.txt
30
- - README.txt
31
- - Rakefile.rb
44
+ - README.md
45
+ - Rakefile
46
+ - VERSION
32
47
  - ext/extconf.rb
33
- - ext/rglpk.c
34
- - lib/glpk.rb
48
+ - ext/glpk_wrapper.c
49
+ - lib/rglpk.rb
50
+ - rglpk.gemspec
35
51
  - swig/Makefile.in
36
52
  - swig/configure.in
37
53
  - swig/glpk.i
54
+ - test/helper.rb
38
55
  - test/test_all.rb
56
+ - test/test_basic.rb
57
+ - test/test_brief_example.rb
58
+ - test/test_problem_kind.rb
39
59
  has_rdoc: true
40
60
  homepage: http://rglpk.rubyforge.org/
61
+ licenses: []
62
+
41
63
  post_install_message:
42
64
  rdoc_options:
43
- - --exclude
44
- - test/*
45
- - --main
46
- - README.txt
47
- - --inline-source
65
+ - --charset=UTF-8
48
66
  require_paths:
49
- - test
67
+ - lib
68
+ - ext
69
+ - ext
50
70
  required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
51
72
  requirements:
52
73
  - - ">="
53
74
  - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
54
78
  version: "0"
55
- version:
56
79
  required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
57
81
  requirements:
58
82
  - - ">="
59
83
  - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
60
87
  version: "0"
61
- version:
62
88
  requirements: []
63
89
 
64
- rubyforge_project: rglpk
65
- rubygems_version: 1.3.1
90
+ rubyforge_project:
91
+ rubygems_version: 1.3.7
66
92
  signing_key:
67
- specification_version: 2
68
- summary: Rglpk is a package providing a Ruby wrapper to the GNU glpk library (http://www.gnu.org/software/glpk/). The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems.
93
+ specification_version: 3
94
+ summary: Rglpk is a package providing a Ruby wrapper to the [GNU GLPK](http://www.gnu.org/software/glpk/) library. The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems.
69
95
  test_files:
96
+ - test/helper.rb
70
97
  - test/test_all.rb
98
+ - test/test_basic.rb
99
+ - test/test_brief_example.rb
100
+ - test/test_problem_kind.rb
data/History.txt DELETED
@@ -1,7 +0,0 @@
1
- = 0.1.1 2008-11-19
2
-
3
- * Updated bindings to GLPK 4.33 - Thanks to Adeh DeSandies
4
-
5
- = 0.1 2007-10-24
6
-
7
- * First private release
data/Manifest.txt DELETED
@@ -1,12 +0,0 @@
1
- History.txt
2
- License.txt
3
- Manifest.txt
4
- README.txt
5
- Rakefile.rb
6
- ext/extconf.rb
7
- ext/rglpk.c
8
- lib/glpk.rb
9
- swig/Makefile.in
10
- swig/configure.in
11
- swig/glpk.i
12
- test/test_all.rb
data/README.txt DELETED
@@ -1,45 +0,0 @@
1
- == Introduction
2
-
3
- Rglpk is a package providing a Ruby wrapper to the GNU glpk library (http://www.gnu.org/software/glpk/). The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems.
4
-
5
- Rglpk is currently in alpha status and the API should be considered subject to change. The main documentation can be found at http://rglpk.rubyforge.org/. Rglpk uses Swig to initially wrap the C GLPK library (using a Swig wrapper originally developed by Nigel Galloway) and then a pure Ruby library to wrap the Swig code in a more friendly OO-style.
6
-
7
- All bug reports, feature requests and patches are welcome. Please email alexg (at) kuicr.kyoto-u.ac.jp or use the rubyforge forums: http://rubyforge.org/forum/?group_id=3943
8
-
9
- == Installation
10
-
11
- A working glpk library installation is required.
12
-
13
- Rglpk is only available as a gem. For example, under Ubuntu linux the following command succesfully compiles and installs (you may need to be root):
14
-
15
- gem install rglpk
16
-
17
- The underlying C library is wrapped using Swig. See /swig for details on the interface.
18
-
19
- == Documentation
20
-
21
- Rglpk provides two files: rglpk.so which is a Swig generated wrapper and glpk.rb which wraps rglpk.so to provide a nicer OO-orientated interface. You should only ever need to access glpk.rb.
22
-
23
- An example:
24
-
25
- require 'glpk'
26
-
27
- #Yadda yadda
28
-
29
- == License
30
-
31
- Copyright (C) 2007 Alex Gutteridge
32
-
33
- This library is free software; you can redistribute it and/or
34
- modify it under the terms of the GNU Lesser General Public
35
- License as published by the Free Software Foundation; either
36
- version 2.1 of the License, or (at your option) any later version.
37
-
38
- This library is distributed in the hope that it will be useful,
39
- but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41
- Lesser General Public License for more details.
42
-
43
- You should have received a copy of the GNU Lesser General Public
44
- License along with this library; if not, write to the Free Software
45
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
data/Rakefile.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'hoe'
2
-
3
- $LOAD_PATH.unshift("./ext")
4
-
5
- module GLPK
6
- VERSION = "0.1.1"
7
- end
8
-
9
- begin
10
- require 'glpk'
11
- rescue LoadError
12
- end
13
-
14
- hoe = Hoe.new("rglpk",GLPK::VERSION) do |p|
15
-
16
- p.author = "Alex Gutteridge"
17
- p.email = "alexg@kuicr.kyoto-u.ac.jp"
18
- p.url = "http://rglpk.rubyforge.org/"
19
-
20
- p.description = p.paragraphs_of("README.txt",1..3)[0]
21
- p.summary = p.paragraphs_of("README.txt",1)[0]
22
- p.changes = p.paragraphs_of("History.txt",0..1).join("\n\n")
23
-
24
- p.clean_globs = ["ext/*.o","ext/*.so","ext/Makefile","ext/mkmf.log","**/*~","email.txt"]
25
-
26
- p.rdoc_pattern = /(^ext\/.*\.c$|^README|^History|^License)/
27
-
28
- p.spec_extras = {
29
- :extensions => ['ext/extconf.rb'],
30
- :require_paths => ['test'],
31
- :has_rdoc => true,
32
- :extra_rdoc_files => ["README.txt","History.txt","License.txt"],
33
- :rdoc_options => ["--exclude", "test/*", "--main", "README.txt", "--inline-source"]
34
- }
35
-
36
- end
37
-
38
- hoe.spec.dependencies.delete_if{|dep| dep.name == "hoe"}
39
-
40
- desc "Uses extconf.rb and make to build the extension"
41
- task :build_extension => ['ext/rglpk.so']
42
- SRC = FileList['ext/rglpk.c']
43
- file 'ext/rglpk.so' => SRC do
44
- Dir.chdir('ext')
45
- system("ruby extconf.rb")
46
- system("make")
47
- Dir.chdir('..')
48
- end
49
-
50
- task :test => [:build_extension]
data/lib/glpk.rb DELETED
@@ -1,320 +0,0 @@
1
- require 'rglpk.so'
2
-
3
- module GLPK
4
-
5
- Rglpk.constants.each do |c|
6
- v = Rglpk.const_get(c)
7
- self.const_set(c,v) if v.kind_of? Numeric
8
- end
9
- TypeConstants =[GLP_FR, GLP_LO, GLP_UP, GLP_DB, GLP_FX]
10
-
11
- class RowColArray < Array
12
- def [](i)
13
- super(i-1)
14
- end
15
- def []=(i,n)
16
- super(i-1,n)
17
- end
18
- def fix_idx
19
- self.each_with_index do |rc,i|
20
- if rc.respond_to?(:i)
21
- rc.i = i+1
22
- else
23
- rc.j = i+1
24
- end
25
- end
26
- end
27
- end
28
- class RowArray < RowColArray
29
- def [](i)
30
- if i.kind_of?(Numeric)
31
- super(i)
32
- elsif i.kind_of?(String)
33
- raise RuntimeError if self[1].nil?
34
- idx = Rglpk.glp_find_row(self[1].p.lp,i)
35
- raise ArgumentError if idx == 0
36
- super(idx)
37
- else
38
- raise ArgumentError
39
- end
40
- end
41
- def []=(i,n)
42
- raise ArgumentError unless n.is_a?(GLPK::Row)
43
- super
44
- end
45
- end
46
- class ColArray < RowColArray
47
- def [](i)
48
- if i.kind_of?(Numeric)
49
- super(i)
50
- elsif i.kind_of?(String)
51
- raise RuntimeError if self[1].nil?
52
- idx = Rglpk.glp_find_col(self[1].p.lp,i)
53
- raise ArgumentError if idx == 0
54
- super(idx)
55
- else
56
- raise ArgumentError
57
- end
58
- end
59
- def []=(i,n)
60
- raise ArgumentError unless n.is_a?(GLPK::Col)
61
- super
62
- end
63
- end
64
-
65
- class Problem
66
-
67
- attr_accessor :rows, :cols, :obj, :lp
68
-
69
- def initialize
70
- @lp = Rglpk.glp_create_prob
71
- @obj = GLPK::ObjectiveFunction.new(self)
72
- @rows = GLPK::RowArray.new
73
- @cols = GLPK::ColArray.new
74
- Rglpk.glp_create_index(@lp)
75
- @status = nil
76
- end
77
-
78
- def name=(n)
79
- Rglpk.glp_set_prob_name(@lp,n)
80
- end
81
- def name
82
- Rglpk.glp_get_prob_name(@lp)
83
- end
84
-
85
- def nz
86
- Rglpk.glp_get_num_nz(@lp)
87
- end
88
-
89
- def add_rows(n)
90
- Rglpk.glp_add_rows(@lp,n)
91
- s = @rows.size
92
- n.times{|i| @rows << GLPK::Row.new(self,s+i+1)}
93
- @rows
94
- end
95
- def add_cols(n)
96
- Rglpk.glp_add_cols(@lp,n)
97
- s = @cols.size
98
- n.times{|i| @cols << GLPK::Column.new(self,s+i+1)}
99
- @cols
100
- end
101
-
102
- def del_rows(a)
103
- #ensure the array of rows tro delete is sorted and unique
104
- a = a.sort.uniq
105
-
106
- r = Rglpk.new_intArray(a.size+1)
107
- a.each_with_index{|n,i| Rglpk.intArray_setitem(r,i+1,n)}
108
- Rglpk.glp_del_rows(@lp,a.size,r)
109
-
110
- a.each do |n|
111
- @rows.delete_at(n)
112
- a.each_with_index do |nn,i|
113
- a[i] -= 1
114
- end
115
- end
116
- @rows.fix_idx
117
- a
118
- end
119
-
120
- def del_cols(a)
121
- #ensure the array of rows tro delete is sorted and unique
122
- a = a.sort.uniq
123
-
124
- r = Rglpk.new_intArray(a.size+1)
125
- a.each_with_index{|n,i| Rglpk.intArray_setitem(r,i+1,n)}
126
- Rglpk.glp_del_cols(@lp,a.size,r)
127
-
128
- a.each do |n|
129
- @cols.delete_at(n)
130
- a.each_with_index do |nn,i|
131
- a[i] -= 1
132
- end
133
- end
134
- @cols.fix_idx
135
- a
136
- end
137
-
138
- def set_matrix(v)
139
-
140
- nr = Rglpk.glp_get_num_rows(@lp)
141
- nc = Rglpk.glp_get_num_cols(@lp)
142
-
143
- ia = Rglpk.new_intArray(v.size+1)
144
- ja = Rglpk.new_intArray(v.size+1)
145
- ar = Rglpk.new_doubleArray(v.size+1)
146
-
147
- v.each_with_index do |x,y|
148
- rn = (y+nr) / nc
149
- cn = (y % nc) + 1
150
-
151
- Rglpk.intArray_setitem(ia,y+1,rn) # 1,1,2,2
152
- Rglpk.intArray_setitem(ja,y+1,cn) # 1,2,1,2
153
- Rglpk.doubleArray_setitem(ar,y+1,x)
154
- end
155
-
156
- Rglpk.glp_load_matrix(@lp,v.size,ia,ja,ar)
157
-
158
- end
159
-
160
- def simplex(options)
161
-
162
- parm = Rglpk::Glp_smcp.new
163
- Rglpk.glp_init_smcp(parm)
164
-
165
- #Default to errors only temrinal output
166
- parm.msg_lev = GLPK::GLP_MSG_ERR
167
-
168
- #set options
169
- options.each do |k,v|
170
- begin
171
- parm.send("#{k}=".to_sym,v)
172
- rescue NoMethodError
173
- raise ArgumentError, "Unrecognised option: #{k}"
174
- end
175
- end
176
-
177
- Rglpk.glp_simplex(@lp,parm)
178
- end
179
-
180
- def status
181
- Rglpk.glp_get_status(@lp)
182
- end
183
-
184
- end
185
-
186
- class Row
187
- attr_accessor :i, :p
188
- def initialize(problem,i)
189
- @p = problem
190
- @i = i
191
- end
192
- def name=(n)
193
- Rglpk.glp_set_row_name(@p.lp,@i,n)
194
- end
195
- def name
196
- Rglpk.glp_get_row_name(@p.lp,@i)
197
- end
198
- def set_bounds(type,lb,ub)
199
- raise ArgumentError unless GLPK::TypeConstants.include?(type)
200
- lb = 0.0 if lb.nil?
201
- ub = 0.0 if ub.nil?
202
- Rglpk.glp_set_row_bnds(@p.lp,@i,type,lb.to_f,ub.to_f)
203
- end
204
- def bounds
205
- t = Rglpk.glp_get_row_type(@p.lp,@i)
206
- lb = Rglpk.glp_get_row_lb(@p.lp,@i)
207
- ub = Rglpk.glp_get_row_ub(@p.lp,@i)
208
-
209
- lb = (t == GLPK::GLP_FR or t == GLPK::GLP_UP) ? nil : lb
210
- ub = (t == GLPK::GLP_FR or t == GLPK::GLP_LO) ? nil : ub
211
-
212
- [t,lb,ub]
213
- end
214
- def set(v)
215
- raise RuntimeError unless v.size == @p.cols.size
216
- ind = Rglpk.new_intArray(v.size+1)
217
- val = Rglpk.new_doubleArray(v.size+1)
218
-
219
- 1.upto(v.size){|x| Rglpk.intArray_setitem(ind,x,x)}
220
- v.each_with_index{|x,y| Rglpk.doubleArray_setitem(val,y+1,x)}
221
-
222
- Rglpk.glp_set_mat_row(@p.lp,@i,v.size,ind,val)
223
- end
224
- def get
225
- ind = Rglpk.new_intArray(@p.cols.size+1)
226
- val = Rglpk.new_doubleArray(@p.cols.size+1)
227
- len = Rglpk.glp_get_mat_row(@p.lp,@i,ind,val)
228
- row = Array.new(@p.cols.size,0)
229
- len.times do |i|
230
- v = Rglpk.doubleArray_getitem(val,i+1)
231
- j = Rglpk.intArray_getitem(ind,i+1)
232
- row[j-1] = v
233
- end
234
- return row
235
- end
236
- end
237
- class Column
238
- attr_accessor :j, :p
239
- def initialize(problem,i)
240
- @p = problem
241
- @j = i
242
- end
243
- def name=(n)
244
- Rglpk.glp_set_col_name(@p.lp,@j,n)
245
- end
246
- def name
247
- Rglpk.glp_get_col_name(@p.lp,@j)
248
- end
249
- def set_bounds(type,lb,ub)
250
- raise ArgumentError unless GLPK::TypeConstants.include?(type)
251
- lb = 0.0 if lb.nil?
252
- ub = 0.0 if ub.nil?
253
- Rglpk.glp_set_col_bnds(@p.lp,@j,type,lb,ub)
254
- end
255
- def bounds
256
- t = Rglpk.glp_get_col_type(@p.lp,@j)
257
- lb = Rglpk.glp_get_col_lb(@p.lp,@j)
258
- ub = Rglpk.glp_get_col_ub(@p.lp,@j)
259
-
260
- lb = (t == GLPK::GLP_FR or t == GLPK::GLP_UP) ? nil : lb
261
- ub = (t == GLPK::GLP_FR or t == GLPK::GLP_LO) ? nil : ub
262
-
263
- [t,lb,ub]
264
- end
265
- def set(v)
266
- raise RuntimeError unless v.size == @p.rows.size
267
- ind = Rglpk.new_intArray(v.size+1)
268
- val = Rglpk.new_doubleArray(v.size+1)
269
-
270
- 1.upto(v.size){|x| Rglpk.intArray_setitem(ind,x,x)}
271
- v.each_with_index{|x,y| Rglpk.doubleArray_setitem(val,y+1,x)}
272
-
273
- Rglpk.glp_set_mat_col(@p.lp,@j,v.size,ind,val)
274
- end
275
- def get
276
- ind = Rglpk.new_intArray(@p.rows.size+1)
277
- val = Rglpk.new_doubleArray(@p.rows.size+1)
278
- len = Rglpk.glp_get_mat_col(@p.lp,@j,ind,val)
279
- col = Array.new(@p.rows.size,0)
280
- len.times do |i|
281
- v = Rglpk.doubleArray_getitem(val,i+1)
282
- j = Rglpk.intArray_getitem(ind,i+1)
283
- col[j-1] = v
284
- end
285
- return col
286
- end
287
- end
288
-
289
- class ObjectiveFunction
290
- def initialize(problem)
291
- @p = problem
292
- end
293
- def name=(n)
294
- Rglpk.glp_set_obj_name(@p.lp,n)
295
- end
296
- def name
297
- Rglpk.glp_get_obj_name(@p.lp)
298
- end
299
- def dir=(d)
300
- raise ArgumentError if d != GLPK::GLP_MIN and d != GLPK::GLP_MAX
301
- Rglpk.glp_set_obj_dir(@p.lp,d)
302
- end
303
- def dir
304
- Rglpk.glp_get_obj_dir(@p.lp)
305
- end
306
- def set_coef(j,coef)
307
- Rglpk.glp_set_obj_coef(@p.lp,j,coef)
308
- end
309
- def coefs=(a)
310
- @p.cols.each{|c| Rglpk.glp_set_obj_coef(@p.lp,c.j,a[c.j-1])}
311
- a
312
- end
313
- def coefs
314
- @p.cols.map{|c| Rglpk.glp_get_obj_coef(@p.lp,c.j)}
315
- end
316
- def get
317
- Rglpk.glp_get_obj_val(@p.lp)
318
- end
319
- end
320
- end