guruby 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/guruby/ext/gurobi.rb +3 -0
- data/lib/guruby/model.rb +100 -2
- data/lib/guruby/var.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90abe0f8288b62ebbd12eabbac3fbfbc5a24eb50
|
4
|
+
data.tar.gz: 39f00000b36f43bdc997ecb6a685d3f7c1878523
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25c749b6eafece828bf27940b7678477230b1f237316e5a331e253b053723db1c8462ce67ecbeafd06842ac4ed96e098e3bfd6dfedde1cf23fa74abf8c6059ac
|
7
|
+
data.tar.gz: e09329ac7900cfbb8dca7447b486e01ff6840d18863971bdaa54f0a05f8a296820ce9847388ca9d995a89a2199203db6b16fff167d1dc42c7bc6cfddd57369c9
|
data/lib/guruby/ext/gurobi.rb
CHANGED
@@ -22,6 +22,9 @@ module Gurobi
|
|
22
22
|
:pointer, :pointer], :int
|
23
23
|
attach_function :GRBaddconstr, [:pointer, :int, :pointer, :pointer, :char,
|
24
24
|
:double, :string], :int
|
25
|
+
attach_function :GRBaddconstrs, [:pointer, :int, :int, :pointer, :pointer,
|
26
|
+
:pointer, :pointer, :pointer,
|
27
|
+
:pointer], :int
|
25
28
|
attach_function :GRBoptimize, [:pointer], :int
|
26
29
|
attach_function :GRBcomputeIIS, [:pointer], :int
|
27
30
|
attach_function :GRBwrite, [:pointer, :string], :int
|
data/lib/guruby/model.rb
CHANGED
@@ -17,15 +17,18 @@ module Guruby
|
|
17
17
|
@var_count = 0
|
18
18
|
@variables = []
|
19
19
|
@constraints = []
|
20
|
+
|
21
|
+
@pending_variables = []
|
22
|
+
@pending_constraints = []
|
20
23
|
end
|
21
24
|
|
22
25
|
# Add new objects (variables and constraints) to the model
|
23
26
|
def <<(obj)
|
24
27
|
case obj
|
25
28
|
when Variable
|
26
|
-
|
29
|
+
@pending_variables << obj
|
27
30
|
when Constraint
|
28
|
-
|
31
|
+
@pending_constraints << obj
|
29
32
|
else
|
30
33
|
fail TypeError
|
31
34
|
end
|
@@ -33,6 +36,20 @@ module Guruby
|
|
33
36
|
|
34
37
|
# Update the model
|
35
38
|
def update
|
39
|
+
if @pending_variables.length == 1
|
40
|
+
add_variable @pending_variables.first
|
41
|
+
elsif @pending_variables.length > 0
|
42
|
+
add_variables @pending_variables
|
43
|
+
end
|
44
|
+
@pending_variables = []
|
45
|
+
|
46
|
+
if @pending_constraints.length == 1
|
47
|
+
add_constraint @pending_constraints.first
|
48
|
+
elsif @pending_constraints.length > 0
|
49
|
+
add_constraints @pending_constraints
|
50
|
+
end
|
51
|
+
@pending_constraints = []
|
52
|
+
|
36
53
|
ret = Gurobi.GRBupdatemodel @ptr
|
37
54
|
fail if ret != 0
|
38
55
|
end
|
@@ -50,6 +67,9 @@ module Guruby
|
|
50
67
|
|
51
68
|
# Optimize the model
|
52
69
|
def optimize
|
70
|
+
# Ensure pending variables and constraints are added
|
71
|
+
update
|
72
|
+
|
53
73
|
ret = Gurobi.GRBoptimize @ptr
|
54
74
|
fail if ret != 0
|
55
75
|
end
|
@@ -83,6 +103,34 @@ module Guruby
|
|
83
103
|
proc { Gurobi.GRBfreemodel ptr }
|
84
104
|
end
|
85
105
|
|
106
|
+
# Add multiple variables to the model simultaneously
|
107
|
+
def add_variables(vars)
|
108
|
+
objective_buffer = FFI::MemoryPointer.new :double, vars.length
|
109
|
+
objective_buffer.write_array_of_double vars.map(&:coefficient)
|
110
|
+
|
111
|
+
lb_buffer = FFI::MemoryPointer.new :double, vars.length
|
112
|
+
lb_buffer.write_array_of_double vars.map(&:lower_bound)
|
113
|
+
|
114
|
+
ub_buffer = FFI::MemoryPointer.new :double, vars.length
|
115
|
+
ub_buffer.write_array_of_double vars.map(&:upper_bound)
|
116
|
+
|
117
|
+
type_buffer = FFI::MemoryPointer.new :char, vars.length
|
118
|
+
type_buffer.write_array_of_char vars.map { |var| var.type.ord }
|
119
|
+
|
120
|
+
names = array_to_pointers_to_names vars
|
121
|
+
names_buffer = FFI::MemoryPointer.new :pointer, vars.length
|
122
|
+
names_buffer.write_array_of_pointer names
|
123
|
+
|
124
|
+
ret = Gurobi.GRBaddvars @ptr, vars.length, 0, nil, nil, nil,
|
125
|
+
objective_buffer, lb_buffer, ub_buffer,
|
126
|
+
type_buffer, names_buffer
|
127
|
+
|
128
|
+
fail if ret != 0
|
129
|
+
|
130
|
+
# Store all the variables in the model
|
131
|
+
vars.each { |var| store_variable var }
|
132
|
+
end
|
133
|
+
|
86
134
|
# Add a new variable to the model
|
87
135
|
def add_variable(var)
|
88
136
|
ret = Gurobi.GRBaddvar @ptr, 0, nil, nil, var.coefficient,
|
@@ -90,6 +138,11 @@ module Guruby
|
|
90
138
|
var.type.ord, var.name
|
91
139
|
fail if ret != 0
|
92
140
|
|
141
|
+
store_variable var
|
142
|
+
end
|
143
|
+
|
144
|
+
# Save the variable to the model and update the variable pointers
|
145
|
+
def store_variable(var)
|
93
146
|
# Update the variable to track the index in the model
|
94
147
|
var.instance_variable_set :@model, self
|
95
148
|
var.instance_variable_set :@index, @var_count
|
@@ -98,6 +151,44 @@ module Guruby
|
|
98
151
|
@variables << var
|
99
152
|
end
|
100
153
|
|
154
|
+
# Add multiple constraints at once
|
155
|
+
def add_constraints(constrs)
|
156
|
+
cbeg = []
|
157
|
+
cind = []
|
158
|
+
cval = []
|
159
|
+
constrs.each_with_index.map do |constr, i|
|
160
|
+
cbeg << cind.length
|
161
|
+
constr.expression.terms.each do |var, coeff|
|
162
|
+
cind << var.instance_variable_get(:@index)
|
163
|
+
cval << coeff
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
cbeg_buffer = FFI::MemoryPointer.new :pointer, cbeg.length
|
168
|
+
cbeg_buffer.write_array_of_int cbeg
|
169
|
+
|
170
|
+
cind_buffer = FFI::MemoryPointer.new :pointer, cind.length
|
171
|
+
cind_buffer.write_array_of_int cind
|
172
|
+
|
173
|
+
cval_buffer = FFI::MemoryPointer.new :pointer, cval.length
|
174
|
+
cval_buffer.write_array_of_double cval
|
175
|
+
|
176
|
+
sense_buffer = FFI::MemoryPointer.new :pointer, constrs.length
|
177
|
+
sense_buffer.write_array_of_char constrs.map { |c| c.sense.ord }
|
178
|
+
|
179
|
+
rhs_buffer = FFI::MemoryPointer.new :pointer, constrs.length
|
180
|
+
rhs_buffer.write_array_of_double constrs.map(&:rhs)
|
181
|
+
|
182
|
+
names = array_to_pointers_to_names constrs
|
183
|
+
names_buffer = FFI::MemoryPointer.new :pointer, constrs.length
|
184
|
+
names_buffer.write_array_of_pointer names
|
185
|
+
|
186
|
+
ret = Gurobi.GRBaddconstrs @ptr, constrs.length, cind.length,
|
187
|
+
cbeg_buffer, cind_buffer, cval_buffer,
|
188
|
+
sense_buffer, rhs_buffer, names_buffer
|
189
|
+
fail if ret != 0
|
190
|
+
end
|
191
|
+
|
101
192
|
# Add a new constraint to the model
|
102
193
|
def add_constraint(constr)
|
103
194
|
terms = constr.expression.terms
|
@@ -117,5 +208,12 @@ module Guruby
|
|
117
208
|
@constraints << constr
|
118
209
|
end
|
119
210
|
|
211
|
+
# Convert an array of objects to an FFI array of
|
212
|
+
# memory pointers to the names of each object
|
213
|
+
def array_to_pointers_to_names(arr)
|
214
|
+
arr.map do |obj|
|
215
|
+
obj.name.nil? ? nil : FFI::MemoryPointer.from_string(obj.name)
|
216
|
+
end
|
217
|
+
end
|
120
218
|
end
|
121
219
|
end
|
data/lib/guruby/var.rb
CHANGED
@@ -81,7 +81,7 @@ module Guruby
|
|
81
81
|
def set_double_attribute(name, value)
|
82
82
|
buffer = FFI::MemoryPointer.new :double, 1
|
83
83
|
buffer.write_array_of_double [value]
|
84
|
-
ret = Gurobi.GRBsetdblattrarray model.ptr, name, @index, 1, buffer
|
84
|
+
ret = Gurobi.GRBsetdblattrarray @model.ptr, name, @index, 1, buffer
|
85
85
|
fail if ret != 0
|
86
86
|
end
|
87
87
|
end
|