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