amor 0.0.3 → 0.1.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.
- checksums.yaml +4 -4
- data/lib/amor/model.rb +54 -1
- data/lib/amor/variable.rb +4 -0
- data/lib/amor/version.rb +1 -1
- data/spec/amor/model_spec.rb +67 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46282019baa1044124775c91d8e2aae1c46156a5
|
4
|
+
data.tar.gz: 4cbb2861f562e55943517188594c84cffb22f4f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2b827c94fc45987b12ece82d7eee41528933ee3df684eef112704239f7799e101003b8e639ff54b01aee73ca17c6b8d74a83afaafa9037985c067d1ad51ee0c
|
7
|
+
data.tar.gz: 1d7864300b2030f1b1c2ad2dc276ab75d5282b031d1f6b2360a0b35ace42af032ac6d78184a1e94dd6c6ccd88fb6f789090eebace885164e9ec9265b7804de48
|
data/lib/amor/model.rb
CHANGED
@@ -8,28 +8,33 @@ module Amor
|
|
8
8
|
def initialize
|
9
9
|
@variables = Array.new
|
10
10
|
@indices = Hash.new
|
11
|
+
@constraints = Array.new
|
11
12
|
end
|
12
13
|
|
13
14
|
# Return the variable for that index if already existing or a new one
|
14
15
|
def x(index)
|
15
16
|
@variables[@indices[index] ||= @indices.size] ||= Variable.new(self, index)
|
16
17
|
end
|
18
|
+
alias :var :x
|
17
19
|
|
18
20
|
# Add a minimization objective
|
19
21
|
def min(expression)
|
20
22
|
@objective = Objective.new(:minimize, expression)
|
21
23
|
end
|
24
|
+
alias :minimize :min
|
22
25
|
|
23
26
|
# Add a maximization objective
|
24
27
|
def max(expression)
|
25
28
|
@objective = Objective.new(:maximize, expression)
|
26
29
|
end
|
30
|
+
alias :maximize :max
|
27
31
|
|
28
32
|
# Add a constraint
|
29
33
|
def st(constraint)
|
30
|
-
|
34
|
+
@constraints << constraint
|
31
35
|
return constraint
|
32
36
|
end
|
37
|
+
alias :subject_to :st
|
33
38
|
|
34
39
|
# Create a model from a given string
|
35
40
|
def self.from_string(string)
|
@@ -53,6 +58,21 @@ module Amor
|
|
53
58
|
result << @constraints.each_with_index.map do |constraint, i|
|
54
59
|
" c#{i+1}: #{constraint.lp_string}"
|
55
60
|
end.join("\n")
|
61
|
+
|
62
|
+
# Bounds section
|
63
|
+
bounded_vars = @variables.each_with_index.select{|v| v[0].lb}
|
64
|
+
result << "\nBounds" if bounded_vars.size > 0
|
65
|
+
bounded_vars.each{|v| result << "\n 0 <= x#{v[1]+1}"}
|
66
|
+
|
67
|
+
# Variable type section
|
68
|
+
integer_vars = @variables.each_with_index.select{|v| v[0].type == :integer}
|
69
|
+
result << "\nGenerals\n " if integer_vars.size > 0
|
70
|
+
result << integer_vars.map{|v| "x#{v[1]+1}"}.join(" ")
|
71
|
+
|
72
|
+
binary_vars = @variables.each_with_index.select{|v| v[0].type == :binary}
|
73
|
+
result << "\nBinary\n " if binary_vars.size > 0
|
74
|
+
result << binary_vars.map{|v| "x#{v[1]+1}"}.join(" ")
|
75
|
+
|
56
76
|
result << "\nEnd"
|
57
77
|
return result
|
58
78
|
end
|
@@ -61,5 +81,38 @@ module Amor
|
|
61
81
|
File.open(filename, 'w') {|file| file.puts self.lp_string}
|
62
82
|
end
|
63
83
|
|
84
|
+
def for_all(container)
|
85
|
+
container.each do |e|
|
86
|
+
result = yield(e)
|
87
|
+
if result.is_a?(Constraint)
|
88
|
+
self.st result
|
89
|
+
end
|
90
|
+
end
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
alias :forall :for_all
|
94
|
+
|
95
|
+
def sum(container)
|
96
|
+
container[1..-1].inject(yield(container[0])) do |m, e|
|
97
|
+
m + yield(e)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def integer(variable)
|
102
|
+
variable.type = :integer
|
103
|
+
return variable
|
104
|
+
end
|
105
|
+
alias :int :integer
|
106
|
+
|
107
|
+
def binary(variable)
|
108
|
+
variable.type = :binary
|
109
|
+
return variable
|
110
|
+
end
|
111
|
+
alias :bin :binary
|
112
|
+
|
113
|
+
def positive(variable)
|
114
|
+
variable.lb = 0
|
115
|
+
return variable
|
116
|
+
end
|
64
117
|
end
|
65
118
|
end
|
data/lib/amor/variable.rb
CHANGED
data/lib/amor/version.rb
CHANGED
data/spec/amor/model_spec.rb
CHANGED
@@ -110,10 +110,74 @@ module Amor
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
describe '
|
113
|
+
describe '#lp_string' do
|
114
114
|
it 'returns a LP Format ready string of the model' do
|
115
|
-
model = Model.from_string("min x(3) + 3 * x(2) + 4.0\nst x(2) - 2.0 * x(3) <= 5.0")
|
116
|
-
expect(model.lp_string).to eq("Minimize\n obj: 1 x1 + 3 x2 + 4.0\nSubject To\n c1: 1 x2 - 2.0 x1 <= 5.0\nEnd")
|
115
|
+
model = Model.from_string("min x(3) + 3 * x(2) + 4.0\nst x(2) - 2.0 * x(3) <= 5.0\nbinary x(2)\npositive integer x(3)")
|
116
|
+
expect(model.lp_string).to eq("Minimize\n obj: 1 x1 + 3 x2 + 4.0\nSubject To\n c1: 1 x2 - 2.0 x1 <= 5.0\nBounds\n 0 <= x1\nGenerals\n x1\nBinary\n x2\nEnd")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#for_all' do
|
121
|
+
it 'repeats the block for each element in the provided collection' do
|
122
|
+
expect { |b| @model.for_all([1,2,3], &b) }.to yield_control.exactly(3).times
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'calls the block with the elements from the provided collection' do
|
126
|
+
expect { |b| @model.for_all([1,2,4], &b) }.to yield_successive_args(1,2,4)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns nil' do
|
130
|
+
expect(@model.for_all([1,2]) {}).to eq(nil)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'registers a Constraint with the model' do
|
134
|
+
c = []
|
135
|
+
@model.for_all([1,2]) {|i| c[i] = (@model.x(i) <= i)}
|
136
|
+
expect(@model.constraints).to include(c[1])
|
137
|
+
expect(@model.constraints).to include(c[2])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#sum' do
|
142
|
+
it 'returns an Expression' do
|
143
|
+
expect(@model.sum([1,2]) {|i| @model.x(i)}).to be_a(Expression)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'sums up the results from the provided block for each element in the collection' do
|
147
|
+
expect(@model.sum([1,2,3]) {|i| i * @model.x(i)}).to eql(@model.x(1) + 2 * @model.x(2) + 3 * @model.x(3))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#integer' do
|
152
|
+
it 'returns a Variable' do
|
153
|
+
expect(@model.integer(@model.x(1))).to be_a(Variable)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'sets the type of the Variable to :integer' do
|
157
|
+
@model.integer(@model.x(1))
|
158
|
+
expect(@model.x(1).type).to eq(:integer)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#binary' do
|
163
|
+
it 'returns a Variable' do
|
164
|
+
expect(@model.binary(@model.x(1))).to be_a(Variable)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'sets the type of the Variable to :binary' do
|
168
|
+
@model.binary(@model.x(1))
|
169
|
+
expect(@model.x(1).type).to eq(:binary)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#positive' do
|
174
|
+
it 'returns a Variable' do
|
175
|
+
expect(@model.positive(@model.x(1))).to be_a(Variable)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'sets the variables lower bound to 0' do
|
179
|
+
@model.positive(@model.x(1))
|
180
|
+
expect(@model.x(1).lb).to eq(0)
|
117
181
|
end
|
118
182
|
end
|
119
183
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Dahms
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|