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