rulp 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/extensions/extensions.rb +3 -1
- data/lib/extensions/file_extensions.rb +9 -0
- data/lib/extensions/os_extensions.rb +25 -0
- data/lib/helpers/log.rb +1 -1
- data/lib/rulp.rb +1 -1
- data/lib/rulp/constraint.rb +14 -1
- data/lib/rulp/lv.rb +18 -3
- data/lib/rulp/rulp.rb +54 -19
- data/lib/rulp/rulp_bounds.rb +1 -1
- data/lib/rulp/rulp_initializers.rb +6 -2
- data/lib/solvers/cbc.rb +2 -2
- data/lib/solvers/glpk.rb +2 -2
- data/lib/solvers/scip.rb +6 -5
- data/lib/solvers/solvers.rb +9 -1
- data/test/test_basic_suite.rb +58 -0
- data/test/test_boolean.rb +12 -25
- data/test/test_helper.rb +14 -2
- data/test/test_save_to_file.rb +31 -0
- data/test/test_simple.rb +11 -26
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Yzk4NWFlMmYwMGQ0ZDFjZTUxMmEwNzlkNDAwZmQ4MDU3YWY2Zjg5Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDI3Y2E5MjdhNTY2M2FiZDBhZGMzZTg4MzU2ZDRiMzgyOGFmZTIzMA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTg0OTJlNjhiMGJkNjdlM2U1ZTQ0ZGMyMTkwMTc0ZmI5NjliZjIzM2M3NjE1
|
10
|
+
N2VlNTBiNDBjZmIwOTA5MWI2OGEzZjhkYzYyMmFkOTkzNWM5YTg5OWUzNTc3
|
11
|
+
ZmUwY2U0ODM0ZmJhNTdiNjY2M2JjZDNhNzI0MTJmZDllMDY4Y2Q=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzU4YjQxNzkzNTRlMmU0NzMyNTIyNGQ0NmE1ODM1YzU0NmYyYzFiZmM2YzI1
|
14
|
+
YmI2MTFkNWZmMzJjZWFmZjY0ZTAzODVmNTEwZTk5MDlkYjBhMmZhNzg1NzZm
|
15
|
+
NzFhNTllMTM1MTIwNmJmMDk3MGYyNTRmZGY5ZGMyM2U5YWI2ZjA=
|
@@ -0,0 +1,9 @@
|
|
1
|
+
def choose_file
|
2
|
+
case os
|
3
|
+
when :macosx
|
4
|
+
command = "osascript -e 'set the_file to choose file name with prompt \"Select an output file\"' -e 'set the result to POSIX path of the_file'"
|
5
|
+
File.absolute_path(`#{command}`.strip)
|
6
|
+
else
|
7
|
+
File.absolute_path(gets)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
def os
|
2
|
+
@os ||= (
|
3
|
+
require "rbconfig"
|
4
|
+
host_os = RbConfig::CONFIG['host_os'].downcase
|
5
|
+
|
6
|
+
case host_os
|
7
|
+
when /linux/
|
8
|
+
:linux
|
9
|
+
when /darwin|mac os/
|
10
|
+
:macosx
|
11
|
+
when /mswin|msys|mingw32/
|
12
|
+
:windows
|
13
|
+
when /cygwin/
|
14
|
+
:cygwin
|
15
|
+
when /solaris|sunos/
|
16
|
+
:solaris
|
17
|
+
when /bsd/
|
18
|
+
:bsd
|
19
|
+
when /aix/
|
20
|
+
:aix
|
21
|
+
else
|
22
|
+
raise Error, "unknown os: #{host_os.inspect}"
|
23
|
+
end
|
24
|
+
)
|
25
|
+
end
|
data/lib/helpers/log.rb
CHANGED
data/lib/rulp.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
STDOUT.sync = true
|
2
|
-
require_relative 'rulp/rulp'
|
2
|
+
require_relative 'rulp/rulp'
|
data/lib/rulp/constraint.rb
CHANGED
@@ -12,6 +12,19 @@ class Constraint
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def to_s
|
15
|
-
return "#{@expressions} #{
|
15
|
+
return "#{@expressions} #{constraint_op} #{@value}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def constraint_op
|
19
|
+
case "#{@constraint_op}"
|
20
|
+
when "=="
|
21
|
+
"="
|
22
|
+
when "<"
|
23
|
+
"<="
|
24
|
+
when ">"
|
25
|
+
">="
|
26
|
+
else
|
27
|
+
@constraint_op
|
28
|
+
end
|
16
29
|
end
|
17
30
|
end
|
data/lib/rulp/lv.rb
CHANGED
@@ -13,8 +13,8 @@ class LV
|
|
13
13
|
->(index){ send(self.meth(index)) }
|
14
14
|
end
|
15
15
|
|
16
|
-
def meth(
|
17
|
-
"#{self.name}#{
|
16
|
+
def meth(*args)
|
17
|
+
"#{self.name}#{args.join("_")}_#{self.suffix}"
|
18
18
|
end
|
19
19
|
|
20
20
|
def suffix
|
@@ -31,7 +31,15 @@ class LV
|
|
31
31
|
|
32
32
|
def self.definition(name)
|
33
33
|
self.class.send(:define_method, name){
|
34
|
-
|
34
|
+
defined = LV::names_table["#{name}"]
|
35
|
+
if defined && defined.class != self
|
36
|
+
raise StandardError.new("ERROR:\n#{name} was already defined as a variable of type #{defined.class}."+
|
37
|
+
"You are trying to redefine it as a variable of type #{self}")
|
38
|
+
elsif(!defined)
|
39
|
+
self.new(name)
|
40
|
+
else
|
41
|
+
defined
|
42
|
+
end
|
35
43
|
}
|
36
44
|
return self.send(name) || self.new(name)
|
37
45
|
end
|
@@ -54,12 +62,19 @@ class LV
|
|
54
62
|
end
|
55
63
|
|
56
64
|
def value
|
65
|
+
return nil unless @value
|
57
66
|
if self.class == BV
|
58
67
|
return @value.round(2) == 1
|
68
|
+
elsif self.class == IV
|
69
|
+
return @value
|
59
70
|
else
|
60
71
|
@value
|
61
72
|
end
|
62
73
|
end
|
74
|
+
|
75
|
+
def inspect
|
76
|
+
"#{name}(#{suffix})[#{value || 'undefined'}]"
|
77
|
+
end
|
63
78
|
end
|
64
79
|
|
65
80
|
class BV < LV;
|
data/lib/rulp/rulp.rb
CHANGED
@@ -24,21 +24,21 @@ module Rulp
|
|
24
24
|
CBC = ::CBC
|
25
25
|
|
26
26
|
SOLVERS = {
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
GLPK => Glpk,
|
28
|
+
SCIP => Scip,
|
29
|
+
CBC => Cbc
|
30
30
|
}
|
31
31
|
|
32
32
|
def self.Glpk(lp)
|
33
|
-
lp.solve_with(GLPK)
|
33
|
+
lp.solve_with(GLPK) rescue nil
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.Cbc(lp)
|
37
|
-
lp.solve_with(CBC)
|
37
|
+
lp.solve_with(CBC) rescue nil
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.Scip(lp)
|
41
|
-
lp.solve_with(SCIP)
|
41
|
+
lp.solve_with(SCIP) rescue nil
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.Max(objective_expression)
|
@@ -51,6 +51,12 @@ module Rulp
|
|
51
51
|
Problem.new(Rulp::MIN, objective_expression)
|
52
52
|
end
|
53
53
|
|
54
|
+
def self.solver_exists?(solver_name)
|
55
|
+
solver = solver_name[0].upcase + solver_name[1..-1].downcase
|
56
|
+
solver_class = ObjectSpace.const_defined?(solver) && ObjectSpace.const_get(solver)
|
57
|
+
solver_class.exists? if(solver_class)
|
58
|
+
end
|
59
|
+
|
54
60
|
class Problem
|
55
61
|
def initialize(objective, objective_expression)
|
56
62
|
@objective = objective
|
@@ -66,10 +72,32 @@ module Rulp
|
|
66
72
|
self
|
67
73
|
end
|
68
74
|
|
75
|
+
def solve
|
76
|
+
Rulp.send(self.solver, self)
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_missing(method_name)
|
80
|
+
self.call(method_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def solver(solver=nil)
|
84
|
+
solver = solver || ENV["SOLVER"] || "Scip"
|
85
|
+
solver = solver[0].upcase + solver[1..-1].downcase
|
86
|
+
end
|
87
|
+
|
88
|
+
def call(using=nil)
|
89
|
+
Rulp.send(self.solver(using), self)
|
90
|
+
end
|
91
|
+
|
69
92
|
def constraints
|
70
|
-
@constraints.map.with_index{|constraint, i|
|
93
|
+
constraints_str = @constraints.map.with_index{|constraint, i|
|
71
94
|
" c#{i}: #{constraint}"
|
72
|
-
}.join("\n")
|
95
|
+
}.join("\n").strip
|
96
|
+
if constraints_str.empty?
|
97
|
+
"0 #{@variables.first} = 0"
|
98
|
+
else
|
99
|
+
" #{constraints_str}"
|
100
|
+
end
|
73
101
|
end
|
74
102
|
|
75
103
|
def integers
|
@@ -84,8 +112,8 @@ module Rulp
|
|
84
112
|
|
85
113
|
def bounds
|
86
114
|
@variables.map{|var|
|
87
|
-
next unless var.
|
88
|
-
" #{var.
|
115
|
+
next unless var.bounds
|
116
|
+
" #{var.bounds}"
|
89
117
|
}.compact.join("\n")
|
90
118
|
end
|
91
119
|
|
@@ -93,7 +121,7 @@ module Rulp
|
|
93
121
|
"/tmp/rulp-#{Random.rand(0..1000)}.lp"
|
94
122
|
end
|
95
123
|
|
96
|
-
def output(filename)
|
124
|
+
def output(filename=choose_file)
|
97
125
|
IO.write(filename, self)
|
98
126
|
end
|
99
127
|
|
@@ -120,15 +148,22 @@ module Rulp
|
|
120
148
|
return result
|
121
149
|
end
|
122
150
|
|
151
|
+
def inspect
|
152
|
+
to_s
|
153
|
+
end
|
154
|
+
|
123
155
|
def to_s
|
124
|
-
|
125
|
-
#{@objective}
|
126
|
-
obj: #{@objective_expression}
|
127
|
-
Subject to
|
128
|
-
#{constraints}
|
129
|
-
Bounds
|
130
|
-
#{bounds}#{integers}#{bits}
|
131
|
-
End
|
156
|
+
%Q(
|
157
|
+
#{' '*0}#{@objective}
|
158
|
+
#{' '*0} obj: #{@objective_expression}
|
159
|
+
#{' '*0}Subject to
|
160
|
+
#{' '*0}#{constraints}
|
161
|
+
#{' '*0}Bounds
|
162
|
+
#{' '*0}#{bounds}#{integers}#{bits}
|
163
|
+
#{' '*0}End
|
164
|
+
)
|
132
165
|
end
|
166
|
+
|
167
|
+
alias_method :save, :output
|
133
168
|
end
|
134
169
|
end
|
data/lib/rulp/rulp_bounds.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Rulp
|
2
2
|
module Initializers
|
3
3
|
def initialize(name)
|
4
|
-
raise
|
5
|
-
LV::names_table["#{name}
|
4
|
+
raise StandardError.new("Variable with the name #{name} of a different type (#{LV::names_table[name].class}) already exists") if LV::names_table["#{name}"]
|
5
|
+
LV::names_table["#{name}"] = self
|
6
6
|
@name = name
|
7
7
|
end
|
8
8
|
|
@@ -14,6 +14,10 @@ module Rulp
|
|
14
14
|
def names_table
|
15
15
|
@@names ||= {}
|
16
16
|
end
|
17
|
+
|
18
|
+
def clear
|
19
|
+
@@names = {}
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def to_s
|
data/lib/solvers/cbc.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
class Cbc < Solver
|
2
2
|
def solve(open_solution=false)
|
3
|
-
|
3
|
+
system("#{executable} #{@filename} branch solution #{@outfile}")
|
4
4
|
`open #{@outfile}` if open_solution
|
5
5
|
end
|
6
6
|
|
7
|
-
def executable
|
7
|
+
def self.executable
|
8
8
|
:cbc
|
9
9
|
end
|
10
10
|
|
data/lib/solvers/glpk.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
class Glpk < Solver
|
2
2
|
def solve(open_solution=false)
|
3
|
-
|
3
|
+
system("#{executable} --lp #{@filename} --write #{@outfile}")
|
4
4
|
`open #{@outfile}` if open_solution
|
5
5
|
end
|
6
6
|
|
7
|
-
def executable
|
7
|
+
def self.executable
|
8
8
|
:glpsol
|
9
9
|
end
|
10
10
|
|
data/lib/solvers/scip.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
class Scip < Solver
|
2
|
-
def solve(open_solution=false)
|
3
|
-
`#{executable} -f #{@filename} > #{@outfile}`
|
4
|
-
`open #{@outfile}` if open_solution
|
5
|
-
end
|
6
2
|
|
7
|
-
def executable
|
3
|
+
def self.executable
|
8
4
|
:scip
|
9
5
|
end
|
10
6
|
|
7
|
+
def solve(open_solution=false)
|
8
|
+
system("rm #{@outfile}; #{executable} -f #{@filename} -l #{@outfile}")
|
9
|
+
`open #{@outfile}` if open_solution
|
10
|
+
end
|
11
|
+
|
11
12
|
def store_results(variables)
|
12
13
|
results = IO.read(@outfile)
|
13
14
|
start = results.sub(/.*?primal solution:.*?=+/m, "")
|
data/lib/solvers/solvers.rb
CHANGED
@@ -2,7 +2,7 @@ class Solver
|
|
2
2
|
def initialize(filename)
|
3
3
|
@filename = filename
|
4
4
|
@outfile = "/tmp/#{executable}-output.txt"
|
5
|
-
raise
|
5
|
+
raise StandardError.new("Couldn't find solver #{executable}!") if `which #{executable}`.length == 0
|
6
6
|
@solver_exists = true
|
7
7
|
end
|
8
8
|
|
@@ -10,9 +10,17 @@ class Solver
|
|
10
10
|
puts "Not yet implemented"
|
11
11
|
end
|
12
12
|
|
13
|
+
def executable
|
14
|
+
self.class.executable
|
15
|
+
end
|
16
|
+
|
13
17
|
def solver_exists?
|
14
18
|
@solver_exists || false
|
15
19
|
end
|
20
|
+
|
21
|
+
def self.exists?
|
22
|
+
return `which #{self.executable}`.length != 0
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
require_relative 'cbc'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class BasicSuite < Minitest::Test
|
4
|
+
|
5
|
+
def test_single_binary_var
|
6
|
+
each_solver do |solver|
|
7
|
+
assert_equal X_b.value, nil
|
8
|
+
|
9
|
+
# The minimal value for a single binary variable is 0
|
10
|
+
Rulp::Min(X_b).(solver)
|
11
|
+
assert_equal X_b.value, false
|
12
|
+
|
13
|
+
# The maximal value for a single binary variable is 1
|
14
|
+
Rulp::Max(X_b).(solver)
|
15
|
+
assert_equal X_b.value, true
|
16
|
+
|
17
|
+
# If we set an upper bound this is respected by the solver
|
18
|
+
Rulp::Max(X_b)[1 * X_b <= 0].(solver)
|
19
|
+
assert_equal X_b.value, false
|
20
|
+
|
21
|
+
# If we set a lower bound this is respected by the solver
|
22
|
+
Rulp::Min(X_b)[1 * X_b >= 1].(solver)
|
23
|
+
assert_equal X_b.value, true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_single_integer_var
|
28
|
+
each_solver do |solver|
|
29
|
+
assert_equal X_i.value, nil
|
30
|
+
|
31
|
+
given[ -35 <= X_i <= 35 ]
|
32
|
+
|
33
|
+
# Integer variables respect integer bounds
|
34
|
+
Rulp::Min(X_i).(solver)
|
35
|
+
assert_equal X_i.value, -35
|
36
|
+
|
37
|
+
# Integer variables respect integer bounds
|
38
|
+
Rulp::Max(X_i).(solver)
|
39
|
+
assert_equal X_i.value, 35
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_single_general_var
|
44
|
+
each_solver do |solver|
|
45
|
+
assert_equal X_f.value, nil
|
46
|
+
|
47
|
+
given[ -345.4321 <= X_f <= 345.4321 ]
|
48
|
+
|
49
|
+
# Integer variables respect integer bounds
|
50
|
+
Rulp::Min(X_f).(solver)
|
51
|
+
assert_equal X_f.value, -345.4321
|
52
|
+
|
53
|
+
# Integer variables respect integer bounds
|
54
|
+
Rulp::Max(X_f).(solver)
|
55
|
+
assert_equal X_f.value, 345.4321
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/test/test_boolean.rb
CHANGED
@@ -9,36 +9,23 @@ class BooleanTest < Minitest::Test
|
|
9
9
|
def setup
|
10
10
|
@items = 30.times.map(&Shop_Item_b)
|
11
11
|
items_count = @items.sum
|
12
|
-
items_costs = @items.map{|item| item * Random.rand(1.0...5.0)}.sum
|
12
|
+
@items_costs = @items.map{|item| item * Random.rand(1.0...5.0)}.sum
|
13
13
|
|
14
14
|
@problem =
|
15
|
-
Rulp::Min( items_costs ) [
|
15
|
+
Rulp::Min( @items_costs ) [
|
16
16
|
items_count >= 10,
|
17
|
-
items_costs >= 15
|
17
|
+
@items_costs >= 15
|
18
18
|
]
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
solution = Rulp::Cbc @problem
|
31
|
-
selected = @items.select(&:value)
|
32
|
-
assert_equal selected.length, 10
|
33
|
-
assert_operator solution.round(2), :>=, 15
|
34
|
-
assert_operator solution, :<=, 25
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_glpk
|
38
|
-
solution = Rulp::Glpk @problem
|
39
|
-
selected = @items.select(&:value)
|
40
|
-
assert_equal selected.length, 10
|
41
|
-
assert_operator solution.round(2), :>=, 15
|
42
|
-
assert_operator solution, :<=, 25
|
21
|
+
def test_simple
|
22
|
+
each_solver do |solver|
|
23
|
+
setup
|
24
|
+
@problem.send(solver)
|
25
|
+
selected = @items.select(&:value)
|
26
|
+
assert_equal selected.length, 10
|
27
|
+
assert_operator @items_costs.evaluate.round(2), :>=, 15
|
28
|
+
assert_operator @items_costs.evaluate, :<=, 25
|
29
|
+
end
|
43
30
|
end
|
44
31
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
-
gem "minitest"
|
2
|
-
|
3
1
|
require_relative "../lib/rulp"
|
2
|
+
|
3
|
+
gem "minitest"
|
4
4
|
require "minitest/autorun"
|
5
5
|
|
6
6
|
Rulp::Logger::level = :off
|
7
|
+
|
8
|
+
|
9
|
+
def each_solver
|
10
|
+
[:scip, :cbc, :glpk, :gurobi].each do |solver|
|
11
|
+
LV::clear
|
12
|
+
if Rulp::solver_exists?(solver)
|
13
|
+
yield(solver)
|
14
|
+
else
|
15
|
+
puts "Couldn't find solver #{solver}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
# maximize
|
3
|
+
# z = 10 * x + 6 * y + 4 * z
|
4
|
+
#
|
5
|
+
# subject to
|
6
|
+
# p: x + y + z <= 100
|
7
|
+
# q: 10 * x + 4 * y + 5 * z <= 600
|
8
|
+
# r: 2 * x + 2 * y + 6 * z <= 300
|
9
|
+
#
|
10
|
+
# where all variables are non-negative integers
|
11
|
+
# x >= 0, y >= 0, z >= 0
|
12
|
+
#
|
13
|
+
|
14
|
+
class SaveToFile < Minitest::Test
|
15
|
+
def setup
|
16
|
+
given[ X_i >= 0, Y_i >= 0, Z_i >= 0 ]
|
17
|
+
@objective = 10 * X_i + 6 * Y_i + 4 * Z_i
|
18
|
+
@problem = Rulp::Max( @objective ) [
|
19
|
+
X_i + Y_i + Z_i <= 100,
|
20
|
+
10 * X_i + 4 * Y_i + 5 * Z_i <= 600,
|
21
|
+
2 * X_i + 2 * Y_i + 6 * Z_i <= 300
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_save
|
26
|
+
sample_output_filename = @problem.get_output_filename
|
27
|
+
@problem.save(sample_output_filename)
|
28
|
+
assert_equal(IO.read(sample_output_filename), "#{@problem}")
|
29
|
+
assert_operator "#{@problem}".length, :>=, 100
|
30
|
+
end
|
31
|
+
end
|
data/test/test_simple.rb
CHANGED
@@ -14,37 +14,22 @@ require_relative 'test_helper'
|
|
14
14
|
class SimpleTest < Minitest::Test
|
15
15
|
def setup
|
16
16
|
given[ X_i >= 0, Y_i >= 0, Z_i >= 0 ]
|
17
|
-
@
|
18
|
-
Rulp::Max(
|
17
|
+
@objective = 10 * X_i + 6 * Y_i + 4 * Z_i
|
18
|
+
@problem = Rulp::Max( @objective ) [
|
19
19
|
X_i + Y_i + Z_i <= 100,
|
20
20
|
10 * X_i + 4 * Y_i + 5 * Z_i <= 600,
|
21
21
|
2 * X_i + 2 * Y_i + 6 * Z_i <= 300
|
22
22
|
]
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def test_cbc
|
35
|
-
solution = Rulp::Cbc @problem
|
36
|
-
assert_equal X_i.value, 33
|
37
|
-
assert_equal Y_i.value, 67
|
38
|
-
assert_equal Z_i.value, 0
|
39
|
-
assert_equal solution , 732
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_glpk
|
44
|
-
solution = Rulp::Glpk @problem
|
45
|
-
assert_equal X_i.value, 33
|
46
|
-
assert_equal Y_i.value, 67
|
47
|
-
assert_equal Z_i.value, 0
|
48
|
-
assert_equal solution , 732
|
25
|
+
def test_simple
|
26
|
+
each_solver do |solver|
|
27
|
+
setup
|
28
|
+
@problem.send(solver)
|
29
|
+
assert_equal X_i.value, 33
|
30
|
+
assert_equal Y_i.value, 67
|
31
|
+
assert_equal Z_i.value, 0
|
32
|
+
assert_equal @objective.evaluate , 732
|
33
|
+
end
|
49
34
|
end
|
50
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rulp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter Coppieters
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A simple Ruby LP description DSL
|
14
14
|
email: wc@pico.net.nz
|
@@ -20,8 +20,10 @@ files:
|
|
20
20
|
- bin/rulp
|
21
21
|
- lib/extensions/array_extensions.rb
|
22
22
|
- lib/extensions/extensions.rb
|
23
|
+
- lib/extensions/file_extensions.rb
|
23
24
|
- lib/extensions/kernel_extensions.rb
|
24
25
|
- lib/extensions/object_extensions.rb
|
26
|
+
- lib/extensions/os_extensions.rb
|
25
27
|
- lib/helpers/log.rb
|
26
28
|
- lib/rulp.rb
|
27
29
|
- lib/rulp/constraint.rb
|
@@ -34,8 +36,10 @@ files:
|
|
34
36
|
- lib/solvers/glpk.rb
|
35
37
|
- lib/solvers/scip.rb
|
36
38
|
- lib/solvers/solvers.rb
|
39
|
+
- test/test_basic_suite.rb
|
37
40
|
- test/test_boolean.rb
|
38
41
|
- test/test_helper.rb
|
42
|
+
- test/test_save_to_file.rb
|
39
43
|
- test/test_simple.rb
|
40
44
|
homepage:
|
41
45
|
licenses: []
|
@@ -61,7 +65,9 @@ signing_key:
|
|
61
65
|
specification_version: 4
|
62
66
|
summary: Ruby Linear Programming
|
63
67
|
test_files:
|
68
|
+
- test/test_basic_suite.rb
|
64
69
|
- test/test_boolean.rb
|
65
70
|
- test/test_helper.rb
|
71
|
+
- test/test_save_to_file.rb
|
66
72
|
- test/test_simple.rb
|
67
73
|
has_rdoc:
|