class Object
Public Instance Methods
maximize(objective, lp)
click to toggle source
# File lib/opl.rb, line 1016 def maximize(objective, lp) optimize("maximize", objective, lp) end
minimize(objective, lp)
click to toggle source
# File lib/opl.rb, line 1020 def minimize(objective, lp) optimize("minimize", objective, lp) end
optimize(optimization, objective, lp)
click to toggle source
# File lib/opl.rb, line 1024 def optimize(optimization, objective, lp) original_objective = objective while original_objective.include?("abs") #need to add some constraints, change the objective, #and reprocess the constraints #lp = lp.recreate_with_objective_abs(original_objective) end objective = OPL::Helper.sub_sum(objective, lp) objective = OPL::Helper.sum_indices(objective) objective = OPL::Helper.substitute_data(objective, lp) objective_constants = OPL::Helper.get_constants(objective) if objective_constants[:formatted].empty? objective_addition = 0 else objective_addition = OPL::Helper.sum_constants(objective_constants[:formatted].inject("+")) end objective = OPL::Helper.remove_constants(objective) objective = OPL::Helper.sum_variables(objective, lp) o = OPL::Objective.new(original_objective, optimization) o.expanded_function = objective lp.objective = o lp.objective.addition = objective_addition rows_c = lp.rows p = Rglpk::Problem.new p.name = "sample" if optimization == "maximize" p.obj.dir = Rglpk::GLP_MAX elsif optimization == "minimize" p.obj.dir = Rglpk::GLP_MIN end rows = p.add_rows(rows_c.size) rows_c.each_index do |i| row = rows_c[i] rows[i].name = row.name if row.lower_bound.nil? && row.upper_bound.nil? rows[i].set_bounds(Rglpk::GLP_FR, nil, nil) elsif row.lower_bound.nil? rows[i].set_bounds(Rglpk::GLP_UP, nil, row.upper_bound) elsif row.upper_bound.nil? rows[i].set_bounds(Rglpk::GLP_LO, row.lower_bound, nil) else rows[i].set_bounds(Rglpk::GLP_DB, row.lower_bound, row.upper_bound) end end vars = rows_c.first.variable_coefficient_pairs cols = p.add_cols(vars.size) solver = "simplex" vars.each_index do |i| column_name = vars[i].variable cols[i].name = column_name cols[i].kind = vars[i].variable_type#boolean, integer, etc. if [1,2].include? cols[i].kind if vars[i].lower_bound.nil? && vars[i].upper_bound.nil? cols[i].set_bounds(Rglpk::GLP_FR, nil, nil) elsif vars[i].lower_bound.nil? cols[i].set_bounds(Rglpk::GLP_UP, nil, vars[i].upper_bound) elsif vars[i].upper_bound.nil? cols[i].set_bounds(Rglpk::GLP_LO, vars[i].lower_bound, nil) else cols[i].set_bounds(Rglpk::GLP_DB, vars[i].lower_bound, vars[i].upper_bound) end end if vars[i].variable_type != 1 solver = "mip" end end lp.solver = solver all_vars = rows_c.first.variable_coefficient_pairs.map{|vcp|vcp.variable} obj_coefficients = OPL::Helper.coefficients(objective.gsub(" ",""), lp).map{|c|c.to_f} obj_vars = OPL::Helper.variables(objective.gsub(" ",""), lp) all_obj_coefficients = [] all_vars.each do |var| i = obj_vars.index(var) coef = i.nil? ? 0 : obj_coefficients[i] all_obj_coefficients << coef end p.obj.coefs = all_obj_coefficients matrix = rows_c.map{|row|row.variable_coefficient_pairs.map{|vcp|vcp.coefficient.to_f}}.flatten lp.matrix = matrix p.set_matrix(matrix) answer = Hash.new() lp.simplex_message = p.simplex if solver == "simplex" lp.objective.optimized_value = p.obj.get + objective_addition.to_f cols.each do |c| answer[c.name] = c.get_prim.to_s end elsif solver == "mip" lp.mip_message = p.mip lp.objective.optimized_value = p.obj.mip + objective_addition.to_f cols.each do |c| answer[c.name] = c.mip_val.to_s end end lp.solution = answer lp.rglpk_object = p begin lp.matrix_solution = lp.solution_as_matrix rescue return lp end if lp.stop_processing lp.solution = lp.error_message lp.matrix_solution = lp.error_message lp.rglpk_object = lp.error_message lp.objective = lp.error_message end if lp.rglpk_object.status.to_s == "4" puts "There is no feasible solution." elsif lp.rglpk_object.status.to_s == "6" puts "The solution is unbounded." elsif lp.rglpk_object.status.to_s == "1" puts "The solution is undefined." end lp end
subject_to(constraints, options=[])
click to toggle source
# File lib/opl.rb, line 890 def subject_to(constraints, options=[]) OPL::Helper.check_options_syntax(options) lp = OPL::LinearProgram.new lp.original_constraints = constraints variable_types = options.find_all{|option|option.downcase.include?("boolean") || option.downcase.include?("integer")} || [] epsilon = options.find_all{|option|option.downcase.include?("epsilon")}.first.gsub(" ","").split(":")[1].to_f rescue $default_epsilon bounded_columns = options.find_all{|option|option.downcase.include?("negative") || option.downcase.include?("positive") || option.downcase.include?("nonnegative")} data = options.find_all{|option|option.gsub(" ","").downcase.include?("data:")}[0] if data parsed_data = OPL::Helper.parse_data(data) parsed_data.keys.each do |data_key| data_value = parsed_data[data_key] lp.data << OPL::Data.new(data_key, data_value) end end lp.epsilon = epsilon constraints = constraints.flatten #constraints = constraints.split_ors(constraints) constraints = OPL::Helper.split_equals_a(constraints) data_names = lp.data.map{|d|d.name} constraints = constraints.map do |constraint| OPL::Helper.sub_forall(constraint) end.flatten constraints = constraints.map do |constraint| OPL::Helper.sum_indices(constraint) end constraints = constraints.map do |constraint| OPL::Helper.sub_sum(constraint, lp) end constraints = constraints.map do |constraint| OPL::Helper.sum_indices(constraint) end new_constraints = [] constraints.each do |constraint| replace_absolute_value_results = OPL::Helper.replace_absolute_value(constraint) if replace_absolute_value_results[:constraints_to_add].empty? new_constraints << constraint else new_constraints += replace_absolute_value_results[:constraints_to_add] end end constraints = new_constraints constraints = constraints.map do |constraint| OPL::Helper.put_constants_on_rhs(constraint) end constraints = constraints.map do |constraint| OPL::Helper.put_variables_on_lhs(constraint) end constraints = constraints.map do |constraint| OPL::Helper.sub_rhs_with_summed_constants(constraint) end constraints = constraints.map do |constraint| OPL::Helper.substitute_data(constraint, lp) end constraints = constraints.map do |constraint| OPL::Helper.put_constants_on_rhs(constraint) end constraints = constraints.map do |constraint| OPL::Helper.put_variables_on_lhs(constraint) end constraints = constraints.map do |constraint| OPL::Helper.sub_rhs_with_summed_constants(constraint) end constraints = constraints.map do |constraint| OPL::Helper.sum_variables(constraint, lp) end lp.constraints = constraints all_vars = OPL::Helper.get_all_vars(constraints, lp) variable_type_hash = OPL::Helper.produce_variable_type_hash(variable_types, all_vars) column_bounds = OPL::Helper.get_column_bounds(bounded_columns, all_vars) lp.variable_types = variable_type_hash lp.column_bounds = column_bounds rows = [] constraints.each do |constraint| negate = false constraint = constraint.gsub(" ", "") name = constraint.split(":")[0] value = constraint.split(":")[1] || constraint lower_bound = nil if value.include?("<=") upper_bound = value.split("<=")[1] elsif value.include?(">=") negate = true bound = value.split(">=")[1].to_f upper_bound = (bound*-1).to_s elsif value.include?("<") upper_bound = (value.split("<")[1]).to_f - epsilon elsif value.include?(">") negate = true bound = (value.split(">")[1]).to_f + epsilon upper_bound = (bound*-1).to_s end lhs = OPL::Helper.sides(constraint)[:lhs] coefs = OPL::Helper.coefficients(lhs, lp) if negate coefs = coefs.map do |coef| if coef.include?("+") coef.gsub("+", "-") elsif coef.include?("-") coef.gsub("-", "+") end end end vars = OPL::Helper.variables(lhs, lp) zero_coef_vars = all_vars - vars row = OPL::Row.new("row-#{rand(10000)}", lower_bound, upper_bound, epsilon) row.constraint = constraint coefs = coefs + zero_coef_vars.map{|z|0} vars = vars + zero_coef_vars zipped = vars.zip(coefs) pairs = [] all_vars.each do |var| coef = coefs[vars.index(var)] variable_type = variable_type_hash[var.to_sym] || 1 vcp = OPL::VariableCoefficientPair.new(var, coef, variable_type) vcp.lower_bound = column_bounds[var.to_sym][:lower] rescue nil vcp.upper_bound = column_bounds[var.to_sym][:upper] rescue nil pairs << vcp end row.variable_coefficient_pairs = pairs rows << row end lp.rows = rows lp end