class MIPPeR::GLPKModel
Attributes
ptr[R]
Public Class Methods
new()
click to toggle source
Calls superclass method
# File lib/mipper/glpk/model.rb, line 5 def initialize fail unless MIPPeR.const_defined?(:GLPK) super @var_count = 0 @constr_count = 0 # Constraint matrix initialization (see #add_constraints) @ia = [0] @ja = [0] @ar = [0] # Disable terminal output GLPK.glp_term_out GLPK::GLP_OFF # Construct a new model @ptr = FFI::AutoPointer.new GLPK.glp_create_prob, GLPK.method(:glp_delete_prob) end
Public Instance Methods
optimize()
click to toggle source
Optimize the model
# File lib/mipper/glpk/model.rb, line 46 def optimize # Ensure pending variables and constraints are added update # Run the solver and save the status for later iocp = GLPK::IOCP.new GLPK.glp_init_iocp iocp iocp[:presolve] = GLPK::GLP_ON status = GLPK.glp_intopt(@ptr, iocp) save_solution status end
sense=(sense)
click to toggle source
Set the sense of the model
# File lib/mipper/glpk/model.rb, line 39 def sense=(sense) @sense = sense sense = sense == :min ? GLPK::GLP_MIN : GLPK::GLP_MAX GLPK.glp_set_obj_dir @ptr, sense end
set_variable_bounds(var_index, lb, ub)
click to toggle source
# File lib/mipper/glpk/model.rb, line 59 def set_variable_bounds(var_index, lb, ub) # Determine the type of the variable bounds if lb == ub type = GLPK::GLP_FX elsif lb.finite? type = ub.finite? ? GLPK::GLP_DB : GLPK::GLP_LO else type = ub.finite? ? GLPK::GLP_UP : GLPK::GLP_FR end # Set the bounds on the variable GLPK.glp_set_col_bnds(@ptr, var_index, type, lb, ub) end
write_lp(filename)
click to toggle source
Write the model to a file in CPLEX LP format
# File lib/mipper/glpk/model.rb, line 27 def write_lp(filename) ret = GLPK.glp_write_lp @ptr, 0, filename fail if ret != 0 end
write_mps(filename)
click to toggle source
Write the model to a file in MPS format
# File lib/mipper/glpk/model.rb, line 33 def write_mps(filename) ret = GLPK.glp_write_mps @ptr, GLPK::GLP_MPS_FILE, nil, filename fail if ret != 0 end
Protected Instance Methods
add_constraints(constrs)
click to toggle source
Add multiple constraints at once
# File lib/mipper/glpk/model.rb, line 83 def add_constraints(constrs) GLPK.glp_add_rows(@ptr, constrs.length) # Store each constraint and initialize a matrix used to hold # the coefficients of each value in the constraint matrix # # * ia - row (constraint) index # * ja - column (variable) index # * ar - constraint coefficient constrs.each do |constr| store_constraint constr constr.expression.terms.each do |var, coeff| @ia << constr.index @ja << var.index @ar << coeff end end ia_buffer = build_pointer_array @ia, :int ja_buffer = build_pointer_array @ja, :int ar_buffer = build_pointer_array @ar, :double GLPK.glp_load_matrix(@ptr, @ar.length - 1, ia_buffer, ja_buffer, ar_buffer) @constraints.concat constrs end
add_variables(vars)
click to toggle source
Add multiple variables to the model simultaneously
# File lib/mipper/glpk/model.rb, line 76 def add_variables(vars) # Store all the variables in the model GLPK.glp_add_cols(@ptr, vars.length) vars.each { |var| store_variable var } end
Private Instance Methods
glpk_type(type)
click to toggle source
Get the constant GLPK
uses to represent our variable types
# File lib/mipper/glpk/model.rb, line 184 def glpk_type(type) case type when :integer GLPK::GLP_IV when :binary GLPK::GLP_BV when :continuous GLPK::GLP_CV else fail type end end
save_solution(status)
click to toggle source
Save the solution to the model for access later
# File lib/mipper/glpk/model.rb, line 114 def save_solution(status) status = case status when 0, GLPK::GLP_EMIPGAP :optimized when GLPK::GLP_EBOUND, GLPK::GLP_EROOT, GLPK::GLP_ENOPFS :invalid else :unknown end if status == :optimized objective_value = GLPK.glp_mip_obj_val @ptr variable_values = [nil] @variables.each do |var| variable_values << GLPK.glp_mip_col_val(@ptr, var.index) end else objective_value = nil variable_values = [] end @solution = Solution.new status, objective_value, variable_values end
store_constraint(constr)
click to toggle source
Save the constraint to the model and update the constraint pointers
# File lib/mipper/glpk/model.rb, line 139 def store_constraint(constr) # Update the constraint to track the index in the model index = @constr_count + 1 constr.model = self constr.index = index constr.freeze @constr_count += 1 # Set constraint properties GLPK.glp_set_row_name(@ptr, index, constr.name) case constr.sense when :== lb = ub = constr.rhs type = GLPK::GLP_FX when :>= lb = constr.rhs ub = Float::INFINITY type = GLPK::GLP_LO when :<= lb = -Float::INFINITY ub = constr.rhs type = GLPK::GLP_UP end GLPK.glp_set_row_bnds(@ptr, index, type, lb, ub) end
store_variable(var)
click to toggle source
Save the variable to the model and update the variable pointers
# File lib/mipper/glpk/model.rb, line 167 def store_variable(var) # Update the variable to track the index in the model index = @var_count + 1 var.model = self var.index = index @var_count += 1 @variables << var # Set variable properties GLPK.glp_set_col_name(@ptr, index, var.name) GLPK.glp_set_col_kind(@ptr, index, glpk_type(var.type)) GLPK.glp_set_obj_coef(@ptr, index, var.coefficient) set_variable_bounds index, var.lower_bound, var.upper_bound end