guruby 0.0.1 → 0.0.2
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/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
|