lpsolve 5.5.10.i

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,8 @@
1
+ task :default => [:test]
2
+ # --------- Regression tests ------
3
+ require 'rake/testtask'
4
+ desc "Run regression tests"
5
+ Rake::TestTask.new('test') do |t|
6
+ t.pattern = '*.rb'
7
+ t.warning = true
8
+ end
@@ -0,0 +1,24 @@
1
+
2
+ Model name: 'LP model' - run #1
3
+ Objective: Maximize(R0)
4
+
5
+ SUBMITTED
6
+ Model size: 3 constraints, 2 variables, 6 non-zeros.
7
+ Sets: 0 GUB, 0 SOS.
8
+
9
+ Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2.
10
+ The primal and dual simplex pricing strategy set to 'Devex'.
11
+
12
+
13
+ Optimal solution 6315.625 after 2 iter.
14
+
15
+ Excellent numeric accuracy ||*|| = 0
16
+
17
+ MEMO: lp_solve version 5.5.0.10 for 32 bit OS, with 64 bit REAL variables.
18
+ In the total iteration count 2, 0 (0.0%) were bound flips.
19
+ There were 0 refactorizations, 0 triggered by time and 0 by density.
20
+ ... on average 2.0 major pivots per refactorization.
21
+ The largest [LUSOL v2.2.1.0] fact(B) had 4 NZ entries, 1.0x largest basis.
22
+ The constraint matrix inf-norm is 210, with a dynamic range of 210.
23
+ Time to load data was 0.001 seconds, presolve used 0.000 seconds,
24
+ ... 0.001 seconds in simplex solver, in total 0.002 seconds.
@@ -0,0 +1,60 @@
1
+ print_str() test
2
+ Model name:
3
+ C1 C2 C3 C4
4
+ Minimize 0 0 0 0
5
+ R1 3 2 2 1 <= 4
6
+ Type Real Real Real Real
7
+ upbo Inf Inf Inf Inf
8
+ lowbo 0 0 0 0
9
+ Model name:
10
+ C1 C2 C3 C4
11
+ Minimize 0 0 0 0
12
+ R1 3 2 2 1 <= 4
13
+ R2 0 4 3 1 >= 3
14
+ Type Real Real Real Real
15
+ upbo Inf Inf Inf Inf
16
+ lowbo 0 0 0 0
17
+ Model name:
18
+ C1 C2 C3 C4
19
+ Minimize:
20
+ 2 3 -2 3
21
+
22
+ Subject to:
23
+ R1 3 2 2 1 <= 4
24
+ R2 4 3 1 >= 3
25
+
26
+ Type Real Real Real Real
27
+ upbo Inf Inf Inf Inf
28
+ lowbo 0 0 0 0
29
+ SOS false false false false
30
+
31
+ Value of objective function: -4
32
+
33
+ Actual values of the variables:
34
+ Column 1 0
35
+ C2 0
36
+ C3 2
37
+ C4 0
38
+
39
+ Actual values of the variables:
40
+ C3 2
41
+
42
+ Actual values of the constraints:
43
+ Row 1 4
44
+ R2 6
45
+
46
+ Objective function limits:
47
+ From Till FromValue
48
+ Column 1 -3 1e+30 0.6666667
49
+ C2 -2 1e+30 2
50
+ C3 -1e+30 0.0 -1e+30
51
+ C4 -1 1e+30 4
52
+
53
+ Dual values with from - till limits:
54
+ Dual value From Till
55
+ Row 1 -1 2 1e+30
56
+ R2 0 -1e+30 1e+30
57
+ Column 1 5 -1e+30 0.6666667
58
+ C2 5 -3 2
59
+ C3 0 -1e+30 1e+30
60
+ C4 4 -1e+30 4
@@ -0,0 +1,24 @@
1
+
2
+ Model name: 'MPS model' - run #1
3
+ Objective: Minimize(R0)
4
+
5
+ SUBMITTED
6
+ Model size: 3 constraints, 2 variables, 6 non-zeros.
7
+ Sets: 0 GUB, 0 SOS.
8
+
9
+ Using DUAL simplex for phase 1 and PRIMAL simplex for phase 2.
10
+ The primal and dual simplex pricing strategy set to 'Devex'.
11
+
12
+
13
+ Optimal solution 0 after 0 iter.
14
+
15
+ Excellent numeric accuracy ||*|| = 0
16
+
17
+ MEMO: lp_solve version 5.5.0.10 for 32 bit OS, with 64 bit REAL variables.
18
+ In the total iteration count 0, 0 (100.0%) were bound flips.
19
+ There were 0 refactorizations, 0 triggered by time and 0 by density.
20
+ ... on average 0.0 major pivots per refactorization.
21
+ The largest [LUSOL v2.2.1.0] fact(B) had 4 NZ entries, 1.0x largest basis.
22
+ The constraint matrix inf-norm is 210, with a dynamic range of 210.
23
+ Time to load data was 0.001 seconds, presolve used 0.000 seconds,
24
+ ... 0.000 seconds in simplex solver, in total 0.001 seconds.
@@ -0,0 +1,530 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id: test_lpsolve.rb,v 1.13 2007/03/28 11:48:01 rocky Exp $
3
+ require 'test/unit'
4
+ require 'rubygems'
5
+
6
+ # require 'ruby-debug' ; Debugger.start
7
+
8
+ Mypath = File.expand_path(File.dirname(__FILE__))
9
+ old_dir = File.expand_path(Dir.pwd)
10
+ if old_dir != Mypath
11
+ Dir.chdir(Mypath)
12
+ end
13
+ require Mypath + '/../ext/lpsolve.so'
14
+
15
+ def compare_files(file_correct, file_check_against, max_line=0, filter=nil)
16
+ check_against = File.new(file_check_against)
17
+ got_lines = check_against.readlines
18
+ correct = File.new(file_correct)
19
+ correct_lines = correct.readlines
20
+ filter.call(got_lines, correct_lines) if filter
21
+
22
+ correct_lines.each_with_index do |line, lineno|
23
+ begin
24
+ break if max_line > 0 && lineno >= max_line - 1
25
+ if got_lines[lineno] != correct_lines[lineno]
26
+ puts "At line #{lineno}, we expected:"
27
+ puts correct_lines[lineno]
28
+ puts 'but got:'
29
+ puts got_lines[lineno]
30
+ return false
31
+ end
32
+ rescue EOFError
33
+ return false
34
+ end
35
+ end
36
+ if correct_lines.size != got_lines.size
37
+ puts('difference in number of lines: ' +
38
+ "#{correct_lines.size} vs. #{got_lines.size}")
39
+ return false
40
+ end
41
+ return true
42
+ end
43
+
44
+ class TestLPSolve < Test::Unit::TestCase
45
+ def setup
46
+ @lp = LPSolve.new(0, 4)
47
+ end
48
+
49
+ def test_basic
50
+ assert_equal(Object, LPSolve.superclass)
51
+ assert_equal(LPSolve, @lp.class)
52
+
53
+ assert_equal(4, @lp.version.length)
54
+ @lp.print_lp()
55
+
56
+ [
57
+ # Constraint relations
58
+ [0, 'FR'], [1, 'LE'], [2, 'GE'], [3, 'EQ'],
59
+
60
+ # Verbosity constant
61
+ [0, 'NEUTRAL'], [1, 'CRITICAL'], [2, 'SEVERE'],
62
+ [3, 'IMPORTANT'], [4, 'NORMAL'], [5, 'DETAILED'],
63
+ [6, 'FULL'],
64
+
65
+ # Scaling constants
66
+
67
+ [0, 'SCALE_NONE'], [1, 'SCALE_EXTREME'], [2, 'SCALE_RANGE'],
68
+ [3, 'SCALE_MEAN'], [4, 'SCALE_GEOMETRIC'],
69
+ [7, 'SCALE_CURTISREID'],
70
+
71
+ # Simplex types
72
+ [ 5, 'SIMPLEX_PRIMAL_PRIMAL'],
73
+ [ 6, 'SIMPLEX_DUAL_PRIMAL'],
74
+ [ 9, 'SIMPLEX_PRIMAL_DUAL'],
75
+ [10, 'SIMPLEX_DUAL_DUAL'],
76
+
77
+ # Solve types
78
+ [-2, 'NOMEMORY'], [ 0, 'OPTIMAL'], [ 1, 'SUBOPTIMAL'],
79
+ [ 2, 'INFEASIBLE'], [ 3, 'UNBOUNDED'], [ 4, 'DEGENERATE'],
80
+ [ 5, 'NUMFAILURE'], [ 6, 'USERABORT'], [ 7, 'TIMEOUT'],
81
+ [ 9, 'PRESOLVED'], [10, 'PROCFAIL'], [11, 'PROCBREAK'],
82
+ [12, 'FEASFOUND'], [13, 'NOFEASFOUND']
83
+ ].each do |val, sym|
84
+ assert_equal(val, eval('LPSolve::' + sym))
85
+ end
86
+
87
+ # Brand-and-bound rules
88
+ [
89
+ [ 0, 'NODE_FIRSTSELECT'],
90
+ [ 1, 'NODE_GAPSELECT'],
91
+ [ 2, 'NODE_RANGESELECT'],
92
+ [ 3, 'NODE_FRACTIONSELECT'],
93
+ [ 4, 'NODE_PSEUDOCOSTSELECT'],
94
+ [ 5, 'NODE_PSEUDONONINTSELECT'],
95
+ [ 6, 'NODE_PSEUDORATIOSELECT'],
96
+ [ 7, 'NODE_USERSELECT'],
97
+ [ 8, 'NODE_WEIGHTREVERSEMODE'],
98
+ [ 16, 'NODE_BRANCHREVERSEMODE'],
99
+ [ 32, 'NODE_GREEDYMODE'],
100
+ [ 64, 'NODE_PSEUDOCOSTMODE'],
101
+ [ 128, 'NODE_DEPTHFIRSTMODE'],
102
+ [ 256, 'NODE_RANDOMIZEMODE'],
103
+ [1024, 'NODE_DYNAMICMODE'],
104
+ [2048, 'NODE_RESTARTMODE'],
105
+ [4096, 'NODE_BREADTHFIRSTMODE'],
106
+ [8192, 'NODE_AUTOORDER']
107
+ ].each do |val, sym|
108
+ assert_equal(val, eval('LPSolve::' + sym))
109
+ @lp.bb_rule = val
110
+ assert_equal(val, @lp.bb_rule)
111
+ end
112
+ end
113
+
114
+ def test_constraint
115
+ @lp.set_outputfile('lpsolve.out')
116
+ @lp.print_str("print_str() test\n")
117
+ assert(@lp.str_add_constraint("3 2 2 1", LPSolve::LE, 4),
118
+ "Error in adding <= constraint")
119
+ @lp.print_lp()
120
+ assert(@lp.str_add_constraint("0 4 3 1", LPSolve::GE, 3),
121
+ "Error in adding >= constraint")
122
+ @lp.print_lp()
123
+ assert true
124
+ puts "Setting the objective function: 2 3 -2 3"
125
+ assert(@lp.str_set_obj_fn("2 3 -2 3"),
126
+ "Error in setting objective function")
127
+ @lp.verbose = LPSolve::IMPORTANT
128
+ @lp.print()
129
+ solution = @lp.solve
130
+ assert_equal(0, solution)
131
+ assert_equal(0, @lp.status)
132
+ assert_equal("OPTIMAL solution", @lp.get_statustext(@lp.status))
133
+ @lp.lp_name = "Test model"
134
+ @lp.set_col_name(1, "Column 1")
135
+ @lp.set_row_name(1, "Row 1")
136
+ @lp.print_objective
137
+ @lp.print_solution(1)
138
+ @lp.print_solution(-1)
139
+ @lp.print_constraints(1)
140
+ @lp.print_duals()
141
+ assert @lp.set_mat(2,1,0.5)
142
+ assert_equal(2.0 , @lp.get_mat(1, 2))
143
+ assert_equal(-4.0 , @lp.objective)
144
+ assert_equal(-4.0 , @lp.get_var_primalresult(0))
145
+ assert_equal(4.0, @lp.get_var_primalresult(1))
146
+ assert_in_delta(6.0, @lp.get_var_primalresult(2), 0.001)
147
+ assert_in_delta(5.0, @lp.get_var_dualresult(3), 0.001)
148
+ assert_in_delta(5.0, @lp.get_var_dualresult(4), 0.001)
149
+ assert_equal(0.0, @lp.get_var_dualresult(5))
150
+ assert_equal(0, @lp.get_var_primalresult(3))
151
+ assert_equal(0, @lp.get_var_primalresult(4))
152
+ assert_equal(2.0, @lp.get_var_primalresult(5))
153
+ assert_equal(1, @lp.get_solutioncount)
154
+ assert_equal(1, @lp.solutioncount)
155
+ @lp = nil
156
+ filter = Proc.new{|got_lines, correct_lines|
157
+ [got_lines[49]].flatten.each do |s|
158
+ s.sub!(/-1e[+]30\s+.*\s+-1e[+]30/, "-1e+30\t\t0.0\t\t-1e+30")
159
+ end
160
+ }
161
+ assert compare_files('lpsolve.right', 'lpsolve.out', 0, filter)
162
+ end
163
+
164
+ # Check set_col_name(), get_col_name(), and get_origcol_name()
165
+ def test_col_name
166
+ # Test Invalid parameter type, should be a string.
167
+ assert_equal(nil, @lp.set_col_name(1, true))
168
+
169
+ col_name="column test name"
170
+ assert_equal(nil, @lp.set_col_name([1], col_name),
171
+ "Column name must be an int")
172
+ assert_equal(nil, @lp.set_col_name(1, [1]),
173
+ "Column name must be an int")
174
+ assert @lp.set_col_name(1, col_name)
175
+ assert_equal(col_name, @lp.get_col_name(1))
176
+ assert_equal(col_name, @lp.get_origcol_name(1))
177
+ assert_equal(nil, @lp.get_col_name(100))
178
+ assert_equal(nil, @lp.get_col_name("A"))
179
+ assert_equal(1, @lp.get_col_num(col_name))
180
+ end
181
+
182
+ # Check get_Nrows(), get_Ncolumns(), get_Norig_rows(), get_Norig_columns()
183
+ # Check reading an MPS and the solution.
184
+ def test_Ncols_rows
185
+ # Test Invalid parameter type, should be a string.
186
+ assert_equal(4, @lp.Ncolumns)
187
+ assert_equal(4, @lp.Norig_columns)
188
+ assert_equal(0, @lp.Nrows)
189
+ assert_equal(0, @lp.Norig_rows)
190
+ @lp = LPSolve.read_MPS("../example/model.mps", LPSolve::NORMAL)
191
+ assert_equal(nil, @lp.add_SOS("bad", 1, 1, []))
192
+ presolve = LPSolve::PRESOLVE_COLS +
193
+ LPSolve::PRESOLVE_LINDEP +
194
+ LPSolve::PRESOLVE_SOS +
195
+ LPSolve::PRESOLVE_REDUCEMIP +
196
+ LPSolve::PRESOLVE_KNAPSACK
197
+ @lp.presolve = [presolve, presolve]
198
+ @lp.solve()
199
+ assert_equal(0, @lp.status)
200
+ assert_equal(2, @lp.Ncolumns)
201
+ assert_equal(2, @lp.Norig_columns)
202
+ assert_equal(3, @lp.Nrows)
203
+ assert_equal(3, @lp.Norig_rows)
204
+ assert_equal(0.0, @lp.get_objective())
205
+ assert_equal(1, @lp.solutioncount())
206
+ end
207
+
208
+ # Check set_col_name(), get_col_name(), and get_origcol_name()
209
+ def test_nonzeros
210
+ # Test Invalid parameter type, should be a string.
211
+ assert_equal(0, @lp.nonzeros,
212
+ "Initially there are 0 nonzero entries - everything is zero")
213
+ assert_equal(0, @lp.get_nonzeros,
214
+ "Initially there are 0 nonzero entries - everything is zero")
215
+ assert(@lp.str_add_constraint("0 4 3 1", LPSolve::GE, 3),
216
+ "Error in adding <= constraint")
217
+ assert_equal(3, @lp.nonzeros,
218
+ "We just set 3 entries to be non-zero")
219
+ end
220
+
221
+ # Check get_Nrows(), get_Ncolumns(), get_Norig_rows(), get_Norig_columns()
222
+ # Check set/get_timeout
223
+ def test_get_timeout
224
+ assert_equal Float, @lp.get_timeout().class
225
+ @lp.set_timeout 10.0
226
+ assert_equal(10.0, @lp.get_timeout())
227
+ end
228
+
229
+ # Check get_bb_depthlimit set_bb_depthlimit
230
+ def test_get_bb_depthlimit
231
+ @lp.bb_depthlimit = 10
232
+ assert_equal(10, @lp.bb_depthlimit)
233
+ @lp.set_bb_depthlimit(-5)
234
+ assert_equal(-5, @lp.get_bb_depthlimit)
235
+ end
236
+
237
+ # Check get_bb_depthlimit set_bb_depthlimit
238
+ def test_set_mip_gap
239
+ @lp.set_mip_gap(true, 10)
240
+ assert_equal(10, @lp.get_mip_gap(true))
241
+ @lp.set_mip_gap(false, 1.0)
242
+ assert_equal(1.0, @lp.get_mip_gap(false))
243
+ end
244
+
245
+ # Check set_*variable* types
246
+ def test_vartype
247
+ [:set_binary, :set_int, :set_semicont].each do |fn|
248
+ assert(@lp.send(fn, 1, true),
249
+ "Should have been able to set variable type (#{fn}) for " +
250
+ "column 1")
251
+
252
+ assert(@lp.send(fn, 1, false),
253
+ "Should have been able to unset variable type (#{fn}) for " +
254
+ "column 1")
255
+
256
+ assert(@lp.send(fn, 1, nil),
257
+ "Should have been able to unset variable type (#{fn}) via " +
258
+ "nil for column 1")
259
+
260
+ assert(!@lp.send(fn, 100, false),
261
+ "Should not have been able to set variable type (#{fn}) " +
262
+ "since column number is too large")
263
+
264
+ assert(!@lp.send(fn, 1, "not a boolean parameter"),
265
+ "Should not gotten an error on (#{fn}) " +
266
+ "because parameter 2 is not boolean or nil")
267
+ end
268
+ end
269
+
270
+ # Check set_debug() and is_debug() and accessor functions to them.
271
+ def test_debug
272
+ assert_equal(false, eval("@lp.set_debug(5)")) # bad value
273
+ assert_equal(false, eval("@lp.set_debug('true')")) # bad value
274
+ assert eval("@lp.debug = true")
275
+ assert @lp.is_debug
276
+ assert @lp.debug?
277
+ @lp.set_debug(false)
278
+ assert_equal(@lp.is_debug, false)
279
+ end
280
+
281
+ # Check our deallocation routine doesn't mess
282
+ # things up across a garbage collection
283
+ def test_gc
284
+ @lp = LPSolve.new(0, 4)
285
+ GC.enable
286
+ GC.start
287
+ assert_equal(LPSolve, @lp.class)
288
+ end
289
+
290
+ # Check set_row_name(), set_orig_row_name() and get_row_name()
291
+ # and corresponding accessor functions
292
+ def test_lp_name
293
+ assert_equal(String, @lp.lp_name.class) # accessor function
294
+ assert @lp.set_lp_name("Test model")
295
+ assert_equal("Test model", @lp.get_lp_name())
296
+ @lp.lp_name = "Test 2"
297
+ assert_equal("Test 2", @lp.lp_name())
298
+ end
299
+
300
+ # Check set_mat(), get_mat(), set_add_rowmode(), str_add_constraint()
301
+ def test_mat
302
+ assert_equal(nil , @lp.get_mat(1.01, 2), "Row number should be int")
303
+ assert_equal(nil , @lp.get_mat(1, "a"), "Col number should be int")
304
+ assert_equal(0.0 , @lp.get_mat(1, 2))
305
+ assert_equal(nil, @lp.set_add_rowmode(1), "Parameter should be a boolean")
306
+ assert_equal(true, @lp.set_add_rowmode(true),
307
+ "The default should have been false")
308
+ assert_equal(false, @lp.set_add_rowmode(true),
309
+ "We should have just set rowmode to true")
310
+ assert_equal(nil, @lp.add_constraintex(nil, [],
311
+ LPSolve::LE, 3),
312
+ "add_constraintex")
313
+ assert_equal(nil, @lp.add_constraintex(nil,
314
+ [[1, 3], [2, 2], ["a", 2], [4, 1]],
315
+ LPSolve::LE, 3),
316
+ "add_constraintex")
317
+ assert_equal(1, @lp.add_constraintex("Row1",
318
+ [[1, 3], [2, 2], [3, 2], [4, 1]],
319
+ LPSolve::LE, 4),
320
+ "add_constraintex")
321
+ assert(@lp.str_add_constraint("0 4 3 1", LPSolve::GE, 3),
322
+ "Error in adding <= constraint")
323
+ assert_equal(nil, @lp.set_obj_fnex("bad"))
324
+ assert(@lp.set_obj_fnex([[1, 2], [2, 3], [3, -2], [4, 3]]),
325
+ "Error in setting objective function via set_obj_fnex")
326
+ assert(@lp.set_add_rowmode(false),
327
+ "Rowmode should have been set true and is now false")
328
+ assert @lp.set_mat(2,1,0.5)
329
+ assert_equal(2.0 , @lp.get_mat(1, 2))
330
+ end
331
+
332
+ # Check our deallocation routine doesn't mess
333
+ # things up across a garbage collection
334
+ def test_putlogfunc
335
+ @lp.put_logfunc("puts")
336
+ end
337
+
338
+ # Check read_LP()
339
+ def test_read_LP
340
+ # Check invalid parameter type. Should be a string.
341
+ assert_equal(nil, LPSolve.read_LP(TRUE, LPSolve::IMPORTANT, "LP model"))
342
+ assert_equal(nil, LPSolve.read_LP("model.lp", LPSolve::IMPORTANT, 5.0))
343
+
344
+ lp = LPSolve.read_LP("../example/model.lp", LPSolve::IMPORTANT, "LP model")
345
+ assert_equal(LPSolve, lp.class)
346
+ lp.set_outputfile("lp_model.out")
347
+ lp.set_verbose(LPSolve::NORMAL)
348
+ lp.solve
349
+
350
+ assert_in_delta(lp.time_total,
351
+ lp.time_load + lp.time_presolve + lp.time_simplex,
352
+ 0.01)
353
+ assert(lp.time_total >= lp.time_elapsed,
354
+ ("total time %g should be larger than elapsed time %g" %
355
+ [lp.time_total, lp.time_elapsed]))
356
+
357
+ filter = Proc.new{|got_lines, correct_lines|
358
+ [got_lines[14]].flatten.each do |s|
359
+ s.sub!(/\|\|[*]\|\| = .+/, '||*|| = 0') if s
360
+ end
361
+ [got_lines[49]].flatten.each do |s|
362
+ s.sub!(/-1e[+]30\s+.*\s+-1e[+]30/, "-1e+30\t\t0.0\t\t-1e+30") if s
363
+ end
364
+ }
365
+ assert compare_files("lp_model.right", "lp_model.out", 23, filter)
366
+ assert_in_delta(21.875, lp.variables[0], 0.0001)
367
+ assert_in_delta(53.125, lp.variables[1], 0.0001)
368
+ assert_equal([143.0, 120.0, 110.0, 1.0], lp.get_column(1))
369
+ assert_equal(nil, lp.get_column(0))
370
+ assert_in_delta(60.0, lp.get_column(2)[0], 0.0001)
371
+ assert_in_delta(210.0, lp.get_column(2)[1], 0.0001)
372
+ assert_equal(0, lp.get_lowbo(1))
373
+ assert_equal(lp.infinite, lp.get_upbo(1))
374
+ assert(lp.set_bounds(1, -1, 200.1))
375
+ assert_equal(false, lp.set_bounds(0, -1, 200.1))
376
+ assert_equal(200.1, lp.get_upbo(1))
377
+ assert_equal(-1, lp.get_lowbo(1))
378
+ assert lp.maxim?
379
+ end
380
+
381
+ # Check read_MPS()
382
+ def test_read_MPS
383
+ # Check invalid parameter type. Should be a string.
384
+ assert_equal(nil, LPSolve.read_MPS(5, LPSolve::IMPORTANT))
385
+
386
+ lp = LPSolve.read_MPS("../example/model.mps", LPSolve::IMPORTANT)
387
+ assert_equal(LPSolve, lp.class)
388
+ lp.set_outputfile("mps_model.out")
389
+ lp.set_verbose(LPSolve::NORMAL)
390
+ lp.set_lp_name("MPS model")
391
+ lp.solve
392
+ assert compare_files("mps_model.right", "mps_model.out", 23)
393
+ assert_in_delta(0.0, lp.variables[0], 0.0001)
394
+ assert_in_delta(0.0, lp.variables[1], 0.0001)
395
+ assert_equal([143.0, 120.0, 110.0, 1.0], lp.get_column(1))
396
+ assert_equal(nil, lp.get_column(0))
397
+ assert_in_delta(60.0, lp.get_column(2)[0], 0.0001)
398
+ assert_in_delta(210.0, lp.get_column(2)[1], 0.0001)
399
+ assert_equal(0, lp.get_lowbo(1))
400
+ assert(lp.set_lowbo(1, 1))
401
+ assert_equal(1, lp.get_lowbo(1))
402
+ assert_equal(lp.infinite, lp.get_upbo(1))
403
+
404
+ assert(lp.set_upbo(1, 100))
405
+ assert_equal(100, lp.get_upbo(1))
406
+ assert(lp.write_lp("foo.lp"))
407
+ assert(lp.write_mps("foo.mps"))
408
+ ## FIXME
409
+ # assert(lp.write_mps(nil))
410
+ # assert(lp.write_mps())
411
+ end
412
+
413
+ # Check set_row_name(), set_orig_row_name() and get_row_name()
414
+ def test_row_name
415
+ # Test Invalid parameter type, should be a string.
416
+ assert_equal(false, @lp.set_row_name(1, true))
417
+
418
+ assert @lp.set_row_name(1, "row test name")
419
+ assert_equal("row test name", @lp.get_row_name(1))
420
+ assert_equal("row test name", @lp.get_origrow_name(1))
421
+ assert_equal(nil, @lp.get_origrow_name([1]))
422
+ assert_equal(@lp.get_row_name(100), nil)
423
+ assert_equal(@lp.get_row_name("a"), nil)
424
+ end
425
+
426
+ # Check set_rh() and set_rh_range
427
+ def test_set_rh
428
+ # Test Invalid parameter type, should be a string.
429
+ assert(@lp.str_set_obj_fn("1 0 0 0"),
430
+ "Error in setting objective function via set_obj_fnex")
431
+ assert_equal(nil, @lp.set_rh(0, 6.0),
432
+ "Should get false on set_rh because row hasn't been set yet")
433
+ assert_equal(false, @lp.set_rh_range(1, 2.0),
434
+ "Should get false on _set_rh - row not set yet")
435
+ @lp.add_constraintex("ROW1", [[1, 1.0]], LPSolve::GE, 5.0)
436
+ @lp.set_rh(1, 6.0) # Reset above range from 5 to 6.
437
+ assert @lp.set_rh_range(1, 2.0) # Set lower bound to 6.0 - 2.0
438
+ assert(@lp.set_maxim, "Should have been able to maximize")
439
+ assert_equal(0, @lp.solve())
440
+ # FIXME: test solution
441
+ assert(@lp.set_minim, "Should have been able to minimmize")
442
+ assert_equal(0, @lp.solve())
443
+ # FIXME: test solution
444
+ end
445
+
446
+ # Check set_scaling(), get_scaling()
447
+ def test_scaling
448
+ scalemodes = [LPSolve::SCALE_NONE,
449
+ LPSolve::SCALE_EXTREME,
450
+ LPSolve::SCALE_RANGE,
451
+ LPSolve::SCALE_MEAN,
452
+ LPSolve::SCALE_GEOMETRIC,
453
+ LPSolve::SCALE_CURTISREID]
454
+ for scalemode in scalemodes do
455
+ @lp.set_scaling(scalemode)
456
+ assert_equal(scalemode, @lp.get_scaling())
457
+ end
458
+ end
459
+
460
+ # Check set_simplextype(), get_simplextype()
461
+ def test_simplextype
462
+ simplextypes = [
463
+ LPSolve::SIMPLEX_PRIMAL_PRIMAL,
464
+ LPSolve::SIMPLEX_DUAL_PRIMAL,
465
+ LPSolve::SIMPLEX_PRIMAL_DUAL,
466
+ LPSolve::SIMPLEX_DUAL_DUAL
467
+ ]
468
+ assert_equal LPSolve::SIMPLEX_DUAL_PRIMAL, @lp.simplextype
469
+ for simplextype in simplextypes do
470
+ @lp.set_simplextype(simplextype)
471
+ assert_equal(simplextype, @lp.get_simplextype())
472
+ end
473
+ for simplextype in simplextypes do
474
+ @lp.simplextype = simplextype
475
+ assert_equal(simplextype, @lp.simplextype)
476
+ end
477
+ end
478
+
479
+ # Check set_debug() and is_debug()
480
+ def test_verbose
481
+ assert_equal(Fixnum, @lp.get_verbose.class)
482
+ @lp.set_verbose(LPSolve::CRITICAL)
483
+ assert_equal LPSolve::CRITICAL, @lp.verbose
484
+ @lp.verbose = LPSolve::NORMAL
485
+ end
486
+
487
+ def test_solutioncount_limit
488
+ @lp = LPSolve.new(0, 4)
489
+ assert_equal(0, @lp.solutioncount,
490
+ "Haven't solved anything yet so solutioncount should be 0.")
491
+ assert_equal(1, @lp.solutionlimit,
492
+ "The default solution limit should be 1.")
493
+ assert_equal(17445, @lp.bb_rule,
494
+ "This is the default bb_rule mask. Have defaults changed? ")
495
+ @lp.solutionlimit = 3
496
+ assert_equal(3, @lp.get_solutionlimit,
497
+ "We just previously set the solution limit to 3.")
498
+ @lp.set_lp_name("Four equal solutions")
499
+ @lp.set_add_rowmode(true)
500
+
501
+ # Maximize:
502
+ @lp.set_obj_fnex([[1, 100], [2, 100], [3, 100], [4, 100]])
503
+
504
+ @lp.add_constraintex("Only two", [[1, 1], [2, 1], [3, 1], [4, 1]],
505
+ LPSolve::LE, 2)
506
+ @lp.add_SOS("SOS 1 or 2", 1, 1, [[1, 0], [2, 1]])
507
+ @lp.add_SOS("SOS 3 or 4", 1, 1, [[3, 0], [4, 1]])
508
+ @lp.set_binary(1, true)
509
+ @lp.set_binary(2, true)
510
+ @lp.set_binary(3, true)
511
+ @lp.set_binary(4, true)
512
+ @lp.set_add_rowmode(false)
513
+ assert(@lp.set_maxim, "Should have been able to maximize")
514
+ assert_equal(0, @lp.solve)
515
+ end
516
+
517
+ def test_status
518
+ @lp = LPSolve.new(0, 1)
519
+ assert_equal("LPSolve method solve() not performed yet.",
520
+ @lp.get_statustext)
521
+ assert_equal(0, @lp.solve())
522
+ assert_equal("OPTIMAL solution", @lp.get_statustext)
523
+ assert @lp.str_add_constraint("1", LPSolve::EQ, 4)
524
+ assert @lp.str_add_constraint("2", LPSolve::EQ, 2)
525
+ assert_equal(2, @lp.solve())
526
+ assert_equal(2, @lp.status)
527
+ assert_equal("Model is primal INFEASIBLE", @lp.statustext)
528
+ end
529
+
530
+ end