amor 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72757cf7317f8c6f13c187a67ad6d62697d9af49
4
- data.tar.gz: 770eaad8ad91d9d2772e191c499ccbcc267af955
3
+ metadata.gz: 46282019baa1044124775c91d8e2aae1c46156a5
4
+ data.tar.gz: 4cbb2861f562e55943517188594c84cffb22f4f4
5
5
  SHA512:
6
- metadata.gz: 48c8b6a7c69e8f45676492f04c96469d6ac6de992f97bba0d15fb05747c8702c905549e41bd1d234a632d3c19f48229723fc66e9aee86e7d174834d69ac699b3
7
- data.tar.gz: f1c4c7140e3c676905860f7329ce0b43da472da7ea549142c90d0f3c4ab08d8a04374094ba89fbba9c89efbc3f20aa10a768baf22512057f6442eced110b3d5e
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
- (@constraints ||= Array.new) << constraint
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
@@ -3,6 +3,10 @@ module Amor
3
3
 
4
4
  attr_reader :model, :index
5
5
 
6
+ attr_accessor :type, :lb, :ub
7
+ alias :lower_bound :lb
8
+ alias :upper_bound :ub
9
+
6
10
  def initialize(model, index)
7
11
  @model = model
8
12
  @index = index
data/lib/amor/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Amor
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -110,10 +110,74 @@ module Amor
110
110
  end
111
111
  end
112
112
 
113
- describe '.lp_string' do
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.3
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-22 00:00:00.000000000 Z
11
+ date: 2014-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler