rglpk 0.1.1 → 0.2.0

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.
@@ -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