opl 1.0.0 → 1.0.1
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.
- data/lib/opl.rb +33 -14
- metadata +2 -2
data/lib/opl.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
require "rglpk"
|
2
2
|
|
3
3
|
#TODO
|
4
|
+
#unbounded or conflicting bounds messages
|
5
|
+
# e.g.
|
6
|
+
# lp = maximize(
|
7
|
+
# "x",
|
8
|
+
# subject_to([
|
9
|
+
# "x >= 0"
|
10
|
+
# ]))
|
11
|
+
|
12
|
+
#put a warning about branch and cut in the github description
|
13
|
+
|
4
14
|
#1.1
|
5
15
|
#setting variable values in constraints
|
6
16
|
#and then using that variable value in further constraints
|
7
|
-
|
17
|
+
|
8
18
|
#1.2
|
9
19
|
#summing of variables
|
10
20
|
#e.g. x1 + x1 <= 3
|
@@ -89,7 +99,7 @@ class OPL
|
|
89
99
|
variable = text.scan(/[a-z]\[/)[0].gsub("[","")
|
90
100
|
#will need to make this multiple variables??
|
91
101
|
#or is this even used at all????
|
92
|
-
value_combinations =
|
102
|
+
value_combinations = self.mass_product(values)
|
93
103
|
value_combinations.each_index do |vc_index|
|
94
104
|
value_combination = value_combinations[vc_index]
|
95
105
|
value_combination = [value_combination] unless value_combination.is_a?(Array)
|
@@ -263,7 +273,7 @@ class OPL
|
|
263
273
|
end
|
264
274
|
|
265
275
|
def self.coefficients(text)#parameter is one side of the equation
|
266
|
-
equation =
|
276
|
+
equation = self.add_ones(text)
|
267
277
|
if equation[0]=="-"
|
268
278
|
equation.scan(/[+-][\d\.]+/)
|
269
279
|
else
|
@@ -272,7 +282,7 @@ class OPL
|
|
272
282
|
end
|
273
283
|
|
274
284
|
def self.variables(text)#parameter is one side of the equation
|
275
|
-
equation =
|
285
|
+
equation = self.add_ones(text)
|
276
286
|
equation.scan(/[a-z]+[\[\]\d]*/)
|
277
287
|
end
|
278
288
|
|
@@ -312,8 +322,8 @@ class OPL
|
|
312
322
|
#in: "-8 + x + y + 3 <= 100"
|
313
323
|
#out: "x + y <= 100 + 5"
|
314
324
|
text = text.gsub(" ","")
|
315
|
-
s =
|
316
|
-
constants_results =
|
325
|
+
s = self.sides(text)
|
326
|
+
constants_results = self.get_constants(s[:lhs])
|
317
327
|
constants = []
|
318
328
|
constants_results[:formatted].each_index do |i|
|
319
329
|
formatted_constant = constants_results[:formatted][i]
|
@@ -356,7 +366,7 @@ class OPL
|
|
356
366
|
end
|
357
367
|
|
358
368
|
def self.sub_rhs_with_summed_constants(constraint)
|
359
|
-
rhs =
|
369
|
+
rhs = self.sides(constraint)[:rhs]
|
360
370
|
constraint.gsub(rhs, self.sum_constants(rhs))
|
361
371
|
end
|
362
372
|
|
@@ -382,7 +392,7 @@ class OPL
|
|
382
392
|
#in: "x + y - x[3] <= 3z + 2x[2] - 10"
|
383
393
|
#out: "x + y - x[3] - 3z - 2x[2] <= -10"
|
384
394
|
text = text.gsub(" ", "")
|
385
|
-
s =
|
395
|
+
s = self.sides(text)
|
386
396
|
oper = self.operator(text)
|
387
397
|
rhs = s[:rhs]
|
388
398
|
lhs = s[:lhs]
|
@@ -471,6 +481,9 @@ class OPL
|
|
471
481
|
attr_accessor :formatted_constraints
|
472
482
|
attr_accessor :rglpk_object
|
473
483
|
attr_accessor :solver
|
484
|
+
attr_accessor :matrix
|
485
|
+
attr_accessor :simplex_message
|
486
|
+
attr_accessor :mip_message
|
474
487
|
|
475
488
|
def initialize(objective, constraints)
|
476
489
|
@objective = objective
|
@@ -629,8 +642,9 @@ def optimize(optimization, objective, rows_c)
|
|
629
642
|
rows_c.each_index do |i|
|
630
643
|
row = rows_c[i]
|
631
644
|
rows[i].name = row.name
|
632
|
-
rows[i].set_bounds(Rglpk::GLP_UP,
|
633
|
-
rows[i].set_bounds(Rglpk::GLP_LO,
|
645
|
+
rows[i].set_bounds(Rglpk::GLP_UP, nil, row.upper_bound) unless row.upper_bound.nil?
|
646
|
+
rows[i].set_bounds(Rglpk::GLP_LO, nil, row.lower_bound) unless row.lower_bound.nil?
|
647
|
+
#rows[i].set_bounds(Rglpk::GLP_FR, row.lower_bound, row.upper_bound)
|
634
648
|
end
|
635
649
|
vars = rows_c.first.variable_coefficient_pairs
|
636
650
|
cols = p.add_cols(vars.size)
|
@@ -638,12 +652,15 @@ def optimize(optimization, objective, rows_c)
|
|
638
652
|
vars.each_index do |i|
|
639
653
|
column_name = vars[i].variable
|
640
654
|
cols[i].name = column_name
|
641
|
-
cols[i].set_bounds(Rglpk::GLP_LO, 0.0, 0.0)
|
642
655
|
cols[i].kind = vars[i].variable_type#boolean, integer, etc.
|
656
|
+
if [1,2].include? cols[i].kind
|
657
|
+
cols[i].set_bounds(Rglpk::GLP_FR, nil, nil)
|
658
|
+
end
|
643
659
|
if vars[i].variable_type != 1
|
644
660
|
solver = "mip"
|
645
661
|
end
|
646
662
|
end
|
663
|
+
lp.solver = solver
|
647
664
|
all_vars = rows_c.first.variable_coefficient_pairs.map{|vcp|vcp.variable}
|
648
665
|
obj_coefficients = OPL::Helper.coefficients(objective.gsub(" ","")).map{|c|c.to_f}
|
649
666
|
obj_vars = OPL::Helper.variables(objective.gsub(" ",""))
|
@@ -654,16 +671,18 @@ def optimize(optimization, objective, rows_c)
|
|
654
671
|
all_obj_coefficients << coef
|
655
672
|
end
|
656
673
|
p.obj.coefs = all_obj_coefficients
|
657
|
-
|
674
|
+
matrix = rows_c.map{|row|row.variable_coefficient_pairs.map{|vcp|vcp.coefficient.to_f}}.flatten
|
675
|
+
lp.matrix = matrix
|
676
|
+
p.set_matrix(matrix)
|
658
677
|
answer = Hash.new()
|
659
|
-
p.simplex
|
678
|
+
lp.simplex_message = p.simplex
|
660
679
|
if solver == "simplex"
|
661
680
|
lp.objective.optimized_value = p.obj.get + objective_addition.to_f
|
662
681
|
cols.each do |c|
|
663
682
|
answer[c.name] = c.get_prim.to_s
|
664
683
|
end
|
665
684
|
elsif solver == "mip"
|
666
|
-
p.mip
|
685
|
+
lp.mip_message = p.mip
|
667
686
|
lp.objective.optimized_value = p.obj.mip + objective_addition.to_f
|
668
687
|
cols.each do |c|
|
669
688
|
answer[c.name] = c.mip_val.to_s
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-24 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Built on top of the glpk gem for linear programming. The syntax is copied
|
15
15
|
from OPL Studio, which remains my favorite linear programming software, but the
|