class OPL::Helper

Public Class Methods

add_ones(text, lp) click to toggle source
# File lib/opl.rb, line 177
def self.add_ones(text, lp)
        equation = text
        equation = "#"+equation
        equation.scan(/[#+-][a-z]/).each do |p|
                if p.include?("+")
                        q = p.gsub("+", "+1*")
                elsif p.include?("-")
                        q = p.gsub("-","-1*")
                elsif p.include?("#")
                        q = p.gsub("#","#1*")
                end
                equation = equation.gsub(p,q)
        end
        equation.gsub("#","")
end
check_options_syntax(options) click to toggle source
# File lib/opl.rb, line 648
def self.check_options_syntax(options)
        return if options.empty?
        options.each do |option|
                if option.include?(":")
                        title = option.gsub(" ","").split(":")[0]
                        value = option.gsub(" ","").split(":")[1]
                        if !["nonnegative", "integer", "boolean", "data", "epsilon"].include?(title.downcase)
                                raise "Did not recognize the TITLE parameter '#{title}' in the options."
                        end
                else
                        raise "Options parameter '#{option}' does not have a colon in it. The proper syntax of an option is TITLE: VALUE"
                end
        end
end
coefficients(text, lp) click to toggle source
# File lib/opl.rb, line 294
def self.coefficients(text, lp)#text is one side of the equation
        equation = self.add_ones(text, lp)
        if equation[0]=="-"
                equation.scan(/[+-][\d\.]+/)
        else
                ("#"+equation).scan(/[#+-][\d\.]+/).map{|e|e.gsub("#","+")}
        end
end
data_coefficients() click to toggle source
# File lib/opl.rb, line 303
def self.data_coefficients

end
either_or(lp, constraint1, constraint2, i) click to toggle source
# File lib/opl.rb, line 729
def self.either_or(lp, constraint1, constraint2, i)
        # in: lp, "10.0*x1+4.0*x2+5.0*x3<=600", "2.0*x1+2.0*x2+6.0*x3<=300"
        # out: "10.0*x1+4.0*x2+5.0*x3<=600+#{$default_m}", "2.0*x1+2.0*x2+6.0*x3<=300+#{$default_m}"
        index1 = lp.constraints.index(constraint1)
        lp.constraints[index1] = lp.constraints[index1]+"#{$default_m}*m[#{i}]"
        # add "+M[n]y[n]" to the rhs of the constraint
end
forall(text) click to toggle source
# File lib/opl.rb, line 90
def self.forall(text)
        #in: "i in (0..2), x[i] <= 5"
        #out: ["x[0] <= 5", "x[1] <= 5", "x[2] <= 5"]
        helper = self
        text = text.sub_paren_with_array
        if ((text.gsub(" ","")).scan(/\]\,/).size) + ((text.gsub(" ","")).scan(/\)\,/).size) != text.gsub(" ","").scan(/in/).size
                raise "The following forall() constraint is incorrectly formatted: #{text}. Please see the examples in test.rb for forall() constraints. I suspect you are missing a comma somewhere."
        end
        final_constraints = []
        if text.include?("sum")
                indices = text.split("sum")[0].scan(/[a-z] in/).map{|sc|sc[0]}
                values = text.split("sum")[0].scan(/\s\[[\-\s\d+,]+\]/).map{|e|e.gsub(" ", "").scan(/[\-\d]+/)}
        else
                indices = text.scan(/[a-z] in/).map{|sc|sc[0]}
                values = text.scan(/\s\[[\-\s\d+,]+\]/).map{|e|e.gsub(" ", "").scan(/[\-\d]+/)}
        end
        #TODO: the indices and values should only be those
                #of the forall(), not of any sum() that is
                #inside the forall()
        index_value_pairs = indices.zip(values)
        variable = text.scan(/[a-z]\[/)[0].gsub("[","")
        value_combinations = helper.mass_product(values)
        value_combinations.each_index do |vc_index|
                value_combination = value_combinations[vc_index]
                value_combination = [value_combination] unless value_combination.is_a?(Array)
                if text.include?("sum")
                        constraint = "sum"+text.split("sum")[1..-1].join("sum")
                else
                        constraint = text.split(",")[-1].gsub(" ","")
                end
                e = constraint
                value_combination.each_index do |i|
                        index = indices[i]
                        value = value_combination[i]
                        e = e.gsub("("+index, "("+value)
                        e = e.gsub(index+")", value+")")
                        e = e.gsub("["+index, "["+value)
                        e = e.gsub(index+"]", value+"]")
                        e = e.gsub("=>"+index, "=>"+value)
                        e = e.gsub("<="+index, "<="+value)
                        e = e.gsub(">"+index, ">"+value)
                        e = e.gsub("<"+index, "<"+value)
                        e = e.gsub("="+index, "="+value)
                        e = e.gsub("=> "+index, "=> "+value)
                        e = e.gsub("<= "+index, "<= "+value)
                        e = e.gsub("> "+index, "> "+value)
                        e = e.gsub("< "+index, "< "+value)
                        e = e.gsub("= "+index, "= "+value)
                end
                final_constraints += [e]
        end
        final_constraints
end
get_all_vars(constraints, lp) click to toggle source
# File lib/opl.rb, line 316
def self.get_all_vars(constraints, lp)
        all_vars = []
        constraints.each do |constraint|
                constraint = constraint.gsub(" ", "")
                value = constraint.split(":")[1] || constraint
                all_vars << self.variables(value, lp)
        end
        all_vars.flatten.uniq
end
get_coefficient_variable_pairs(text) click to toggle source
# File lib/opl.rb, line 404
def self.get_coefficient_variable_pairs(text)
        text.scan(/\d*[\*]*[a-z]\[*\d*\]*/)
end
get_column_bounds(bound_info, all_variables) click to toggle source
# File lib/opl.rb, line 539
def self.get_column_bounds(bound_info, all_variables)
        #in: ["NONNEGATIVE: x1"]
        #out: {:x1 => {:lower => 0}}
        column_bounds = {}
        bound_info.each do |info|
                type = info.gsub(" ","").split(":")[0]
                if type.downcase == "nonnegative"
                        bounds = {:lower => 0}
                end
                variables = info.split(":")[1].gsub(" ","").split(",")
                variables.each do |root_var|
                        all_variables_with_root = all_variables.find_all{|var|var.include?("[") && var.split("[")[0]==root_var}+[root_var]
                        all_variables_with_root.each do |var|
                                column_bounds[var.to_sym] = bounds
                        end
                end
        end
        column_bounds
end
get_constants(text) click to toggle source
# File lib/opl.rb, line 326
def self.get_constants(text)
        #in: "-8 + x + y + 3"
        #out: "[-8, +3]"
        text = text.gsub(" ","")
        text = text+"#"
        cs = []
        potential_constants = text.scan(/[\d\.]+[^a-z^\[^\]^\d^\.^\)^\*]/)
        constants = potential_constants.find_all{|c|![*('a'..'z'),*('A'..'Z'),"["].include?(text[text.index(c)-1])}
        searchable_text = text
        constants.each_index do |i|
                constant = constants[i]
                c = constant.scan(/[\d\.]+/)[0]
                index = searchable_text.index(constant)
                if index == 0
                        c = "+"+c
                else
                        constant = constant.gsub('+','[+]')
                        constant = constant.gsub('-','[-]')
                        c = searchable_text.scan(/[\-\+]#{constant}/)[0]
                end
                cs << c.scan(/[\-\+][\d\.]+/)[0]
                searchable_text[index] = "**"
        end
        return({:formatted => cs, :unformatted => constants})
end
mass_product(array_of_arrays, base=[]) click to toggle source
# File lib/opl.rb, line 79
def self.mass_product(array_of_arrays, base=[])
        return(base) if array_of_arrays.empty?
        array = array_of_arrays[0]
        new_array_of_arrays = array_of_arrays[1..-1]
        if base==[]
                self.mass_product(new_array_of_arrays, array)
        else
                self.mass_product(new_array_of_arrays, base.product(array).map{|e|e.flatten})
        end
end
negate(text, explicit=false) click to toggle source
# File lib/opl.rb, line 663
def self.negate(text, explicit=false)
        # text is one side of an equation
        # there will be no foralls, no sums, and no abs
        # in: "z - 3"
        # out: "-z + 3"
        working_text = text = text.gsub(" ","")
        #!("a".."z").to_a.include?(text[0]) &&
        if !["-","+"].include?(text[0])
                working_text = "+"+working_text
        end
        indices_of_negatives = working_text.index_array("-")
        indices_of_positives = working_text.index_array("+")
        indices_of_negatives.each {|i| working_text[i] = "+"}
        indices_of_positives.each {|i| working_text[i] = "-"}
        if !explicit && working_text[0] == "+"
                working_text = working_text[1..-1]
        end
        return(working_text)
end
operator(constraint) click to toggle source
# File lib/opl.rb, line 408
def self.operator(constraint)
        if constraint.include?(">=")
                ">="
        elsif constraint.include?("<=")
                "<="
        elsif constraint.include?(">")
                ">"
        elsif constraint.include?("<")
                "<"
        elsif constraint.include?("=")
                "="
        end
end
parse_data(data_info) click to toggle source
# File lib/opl.rb, line 559
def self.parse_data(data_info)
        #in: "DATA: {d => [1, 0.3, 1.5], o => [10.3, 4.0005, -1]}"
        #out: [data_object_1, data_object_2]
        data_hash_string = data_info.gsub(" ","").split(":")[1]
        data_string = data_hash_string.gsub("{",",").gsub("}",",")
        names = data_string.scan(/,[a-z]/).map{|comma_name|comma_name.gsub(",","")}
        string_values = data_string.scan(/\=\>[\[\d\.\]\,\-]+,/).map{|scanned_value|scanned_value[2..-2]}
        values = string_values.map{|sv|sv.to_a}
        data_hash = {}
        names.each_index do |i|
                name = names[i]
                value = values[i]
                value = value[0] if value.size == 1
                data_hash[name] = value
        end
        return(data_hash)
end
produce_variable_type_hash(variable_types, all_variables) click to toggle source
# File lib/opl.rb, line 486
def self.produce_variable_type_hash(variable_types, all_variables)
        #in: ["BOOLEAN: x, y", "INTEGER: z"]
        #out: {:x => 3, :y => 3, :z => 2}
        variable_type_hash = {}
        variable_types.each do |vt|
                type = vt.gsub(" ","").split(":")[0]
                if type.downcase == "boolean"
                        type_number = 3
                elsif type.downcase == "integer"
                        type_number = 2
                end
                variables = vt.split(":")[1].gsub(" ","").split(",")
                variables.each do |root_var|
                        all_variables_with_root = all_variables.find_all{|var|var.include?("[") && var.split("[")[0]==root_var}+[root_var]
                        all_variables_with_root.each do |var|
                                variable_type_hash[var.to_sym] = type_number
                        end
                end
        end
        variable_type_hash
end
put_constants_on_rhs(text) click to toggle source
# File lib/opl.rb, line 352
def self.put_constants_on_rhs(text)
        #in: "-8 + x + y + 3 <= 100"
        #out: "x + y <= 100 + 5"
        text = text.gsub(" ","")
        s = self.sides(text)
        constants_results = self.get_constants(s[:lhs])
        constants = []
        constants_results[:formatted].each_index do |i|
                formatted_constant = constants_results[:formatted][i]
                unformatted_constant = constants_results[:unformatted][i]
                unless unformatted_constant.include?("*")
                        constants << formatted_constant
                end
        end
        unless constants.empty?
                sum = constants.map{|cc|cc.to_f}.inject("+").to_s
                if sum.include?("-")
                        sum = sum.gsub("-","+")
                else
                        sum = "-"+sum
                end
                lhs = s[:lhs].gsub(" ","")+"#"
                constants_results[:unformatted].each do |constant|
                        index = lhs.index(constant)
                        if index == 0
                                lhs = lhs[(constant.size-1)..(lhs.size-1)]
                        else
                                lhs = lhs[0..(index-2)]+lhs[(index+(constant.size-1))..(lhs.size-1)]
                        end
                end
                text = text.gsub(s[:lhs], lhs[0..-2])
                text += sum
        end
        return(text)
end
put_variables_on_lhs(text) click to toggle source
# File lib/opl.rb, line 422
def self.put_variables_on_lhs(text)
        #in: "x + y - x[3] <= 3z + 2x[2] - 10"
        #out: "x + y - x[3] - 3z - 2x[2] <= -10"
        text = text.gsub(" ", "")
        s = self.sides(text)
        oper = self.operator(text)
        rhs = s[:rhs]
        lhs = s[:lhs]
        coefficient_variable_pairs = self.get_coefficient_variable_pairs(rhs)
        add_to_left = []
        remove_from_right = []
        coefficient_variable_pairs.each do |cvp|
                index = rhs.index(cvp)
                if index == 0
                        add_to_left << "-"+cvp
                        remove_from_right << cvp
                else
                        if rhs[index-1] == "+"
                                add_to_left << "-"+cvp
                                remove_from_right << "+"+cvp
                        else
                                add_to_left << "+"+cvp
                                remove_from_right << "-"+cvp
                        end
                end
        end
        new_lhs = lhs+add_to_left.join("")
        text = text.gsub(lhs+oper, new_lhs+oper)
        new_rhs = rhs
        remove_from_right.each do |rfr|
                new_rhs = new_rhs.gsub(rfr, "")
        end
        new_rhs = "0" if new_rhs == ""
        text = text.gsub(oper+rhs, oper+new_rhs)
        return(text)
end
remove_constants(text) click to toggle source
# File lib/opl.rb, line 613
def self.remove_constants(text)
        helper = self
        text = text.gsub(" ","")
        text = "+"+text if text[0]!="-"
        text = text+"#"
        constants = helper.get_constants(text)
        replacements = []
        constants[:formatted].each_index do |i|
                formatted = constants[:formatted][i]
                unformatted = constants[:unformatted][i]
                if formatted.include?("+")
                        if unformatted.include?("+")
                                replacements << ["+"+unformatted, "+"]
                        elsif unformatted.include?("-")
                                replacements << ["-"+unformatted, "-"]
                        elsif unformatted.include?("#")
                                replacements << [formatted+"#",""]
                        end
                elsif formatted.include?("-")
                        if unformatted.include?("+")
                                replacements << ["-"+unformatted, "+"]
                        elsif unformatted.include?("-")
                                replacements << ["-"+unformatted, "-"]
                        elsif unformatted.include?("#")
                                replacements << [formatted+"#",""]
                        end
                end
        end
        replacements.each do |replacement|
                text = text.gsub(replacement[0],replacement[1])
        end
        text = text[1..-1] if text[0] == "+"
        return(text)
end
replace_absolute_value(text) click to toggle source
# File lib/opl.rb, line 683
def self.replace_absolute_value(text)
        # text is a constraint
        # there will be no foralls and no sums
        # in: "abs(x) <= 1"
        # out: "x <= 1", "-x <= 1"
        # in: "4x + 3y - 6abs(z - 3) <= 4"
        # out: "4x + 3y - 6z + 18 <= 4", "4x + 3y + 6z - 18 <= 4"
        if text.include?("abs")
                helper = self
                constraints_to_delete = [text]
                text = text.gsub(" ","")
                constraints_to_delete << text
                working_text = "#"+text
                absolute_value_elements = working_text.scan(/[\-\+\#]\d*abs\([a-z\-\+\*\d\[\]]+\)/)
                constraints_to_add = []
                absolute_value_elements.each do |ave|
                        ave = ave.gsub("#","")
                        inside_value = ave.split("(")[1].split(")")[0]
                        positive_ave = inside_value
                        negative_ave = helper.negate(inside_value)
                        if ave[0] == "-" || ave[1] == "-"
                                positive_ave = helper.negate(positive_ave, true)
                                negative_ave = helper.negate(negative_ave, true)
                        elsif ave[0] == "+"
                                positive_ave = "+"+positive_ave
                        end
                        positive_constraint = text.gsub(ave, positive_ave)
                        negative_constraint = text.gsub(ave, negative_ave)
                        constraints_to_add << positive_constraint
                        constraints_to_add << negative_constraint
                end
                return {:constraints_to_delete => constraints_to_delete, :constraints_to_add => constraints_to_add}
        else
                return {:constraints_to_delete => [], :constraints_to_add => []}
        end
end
sides(text) click to toggle source
# File lib/opl.rb, line 160
def self.sides(text)
        equation = text
        if equation.include?("<=")
                char = "<="
        elsif equation.include?(">=")
                char = ">="
        elsif equation.include?("<")
                char = "<"
        elsif equation.include?(">")
                char = ">"
        elsif equation.include?("=")
                char = "="
        end
        sides = equation.split(char)
        {:lhs => sides[0], :rhs => sides[1]}
end
split_equals(constraint) click to toggle source
# File lib/opl.rb, line 459
def self.split_equals(constraint)
        [constraint.gsub("=", "<="), constraint.gsub("=", ">=")]
end
split_equals_a(constraints) click to toggle source
# File lib/opl.rb, line 463
def self.split_equals_a(constraints)
        constraints.map do |constraint|
                if (constraint.split("") & ["<=",">=","<",">"]).empty?
                        self.split_equals(constraint)
                else
                        constraint
                end
        end.flatten
end
split_ors(lp, constraints) click to toggle source

make a default OPTION that m is BOOLEAN

# File lib/opl.rb, line 738
def self.split_ors(lp, constraints)
        # in: ["x <= 10", "y <= 24 or y + x <= 14"]
        # out: ["x <= 10", "y - 1000000000000.0*m[0] <= 24", "y + x - 1000000000000.0 + 1000000000000.0*m[0] <= 14"]

        # add m[i+1] to left side of constraints
end
strip_abs(text) click to toggle source
# File lib/opl.rb, line 720
def self.strip_abs(text)
        # in: "3 + abs(x[1] - y) + abs(x[3]) <= 3*abs(-x[2])"
        # out: {:positive => "3 + x[1] - y + x[3] <= -3*x[2]",
        #       :negative => "3 - x[1] + y - x[3] <= 3*x[2]"}
        text = text.gsub(" ","")
        working_text = "#"+text

end
sub_forall(equation, indexvalues={:indices => [], :values => []}) click to toggle source
# File lib/opl.rb, line 144
def self.sub_forall(equation, indexvalues={:indices => [], :values => []})
        #in: "forall(i in (0..2), x[i] <= 5)"
        #out: ["x[0] <= 5", "x[1] <= 5", "x[2] <= 5"]
        return equation unless equation.include?("forall")
        foralls = (equation+"#").split("forall(").map{|ee|ee.split(")")[0..-2].join(")")}.find_all{|eee|eee!=""}
        constraints = []
        if foralls.empty?
                return(equation)
        else
                foralls.each do |text|
                        constraints << self.forall(text)
                end
                return(constraints.flatten)
        end
end
sub_rhs_with_summed_constants(constraint) click to toggle source
# File lib/opl.rb, line 399
def self.sub_rhs_with_summed_constants(constraint)
        rhs = self.sides(constraint)[:rhs]
        constraint.gsub(rhs, self.sum_constants(rhs))
end
sub_sum(equation, lp, indexvalues={:indices => [], :values => []}) click to toggle source
# File lib/opl.rb, line 259
def self.sub_sum(equation, lp, indexvalues={:indices => [], :values => []})
        #in: "sum(i in (0..3), x[i]) <= 100"
        #out: "x[0]+x[1]+x[2]+x[3] <= 100"
        if equation.include?("sum(")
                sums = (equation+"#").split("sum(").map{|ee|ee.split(")")[0..-2].join(")")}.find_all{|eee|eee!=""}.find_all{|eeee|!eeee.include?("forall")}
                sums.each do |text|
                        e = text
                        unless indexvalues[:indices].empty?
                                indexvalues[:indices].each_index do |i|
                                        index = indexvalues[:indices][i]
                                        value = indexvalues[:values][i].to_s
                                        e = e.gsub("("+index, "("+value)
                                        e = e.gsub(index+")", value+")")
                                        e = e.gsub("["+index, "["+value)
                                        e = e.gsub(index+"]", value+"]")
                                        e = e.gsub("=>"+index, "=>"+value)
                                        e = e.gsub("<="+index, "<="+value)
                                        e = e.gsub(">"+index, ">"+value)
                                        e = e.gsub("<"+index, "<"+value)
                                        e = e.gsub("="+index, "="+value)
                                        e = e.gsub("=> "+index, "=> "+value)
                                        e = e.gsub("<= "+index, "<= "+value)
                                        e = e.gsub("> "+index, "> "+value)
                                        e = e.gsub("< "+index, "< "+value)
                                        e = e.gsub("= "+index, "= "+value)
                                end
                        end
                        equation = equation.gsub(text, e)
                        result = self.sum(text, lp)
                        equation = equation.gsub("sum("+text+")", result)
                end
        end
        return(equation)
end
substitute_data(text, lp) click to toggle source
# File lib/opl.rb, line 577
def self.substitute_data(text, lp)
        helper = self
        potential_things_to_substitute = helper.variables(text, lp)
        data_names = lp.data.map{|d|d.name}
        things_to_substitute = {}
        data_values = {}
        lp.data.each do |data|
                dname = data.name
                dvalue = data.value
                targets = potential_things_to_substitute.find_all do |ptts|
                        dname == ptts[0]
                end
                things_to_substitute[dname] = targets
                targets.each do |target|
                        indices = target.scan(/\d+/).map{|ind|ind.to_i}
                        indices = "" if indices.empty?
                        if dvalue.is_a?(Array)
                                value = dvalue.values_at_a(indices)
                        else
                                value = dvalue
                        end
                        data_values[dname+indices.to_s.gsub(",","][").gsub(" ","")] = value
                end
        end
        data_values.keys.each do |key|
                name = key
                value = data_values[key]
                text = text.gsub(name, value.to_s)
        end
        plus_minus = text.scan(/\+[\ ]+-/)
        plus_minus.each do |pm|
                text = text.gsub(pm,"-")
        end
        return(text)
end
sum(text, lp, indexvalues={:indices => [], :values => []}) click to toggle source
# File lib/opl.rb, line 193
def self.sum(text, lp, indexvalues={:indices => [], :values => []})
        #in: "i in [0,1], j in [4,-5], 3x[i][j]"
        #out: "3x[0][4] + 3x[0][-5] + 3x[1][4] + 3x[1][-5]"
        text = text.sub_paren_with_array
        if text.scan(/\(\d+\+\d+\)/).size > 0
                text.scan(/\(\d+\+\d+\)/).each {|e| text = text.gsub(e,eval(e.gsub("(","").gsub(")","")).to_s) }
        end
        text = text.sub_paren_with_array
        if (text.gsub(" ","")).scan(/\]\,/).size != text.scan(/in/).size
                raise "The following sum() constraint is incorrectly formatted: #{text}. Please see the examples in test.rb for sum() constraints. I suspect you are missing a comma somewhere."
        elsif (text.gsub(" ","").include?("=") || text.gsub(" ","").include?("<") || text.gsub(" ","").include?(">"))
                raise "The following sum() constraint cannot have a equalities in it (a.k.a. =, <, >): #{text}"
        end
        final_text = ""
        element = text.split(",")[-1].gsub(" ","")
        indices = text.scan(/[a-z] in/).map{|sc|sc[0]}
        input_indices = indexvalues[:indices] - indices
        if not input_indices.empty?
                input_values = input_indices.map{|ii|indexvalues[:values][indexvalues[:indices].index(ii)]}
        else
                input_values = []
        end
        values = text.scan(/\s\[[\-\s\d+,]+\]/).map{|e|e.gsub(" ", "").scan(/[\-\d]+/)}
        indices += input_indices
        values += input_values
        index_value_pairs = indices.zip(values)
        variable = text.scan(/[a-z]\[/)[0].gsub("[","")
        coefficient_a = text.split(",")[-1].split("[")[0].scan(/\-?[\d\*]+[a-z]/)
        if coefficient_a.empty?
                if text.split(",")[-1].split("[")[0].include?("-")
                        coefficient = "-1"
                else
                        coefficient = "1"
                end
        else
                coefficient = coefficient_a[0].scan(/[\d\-]+/)
        end
        value_combinations = OPL::Helper.mass_product(values)
        value_combinations.each_index do |vc_index|
                value_combination = value_combinations[vc_index]
                e = element
                value_combination = [value_combination] unless value_combination.is_a?(Array)
                value_combination.each_index do |i|
                        index = indices[i]
                        value = value_combination[i]
                        e = e.gsub("("+index, "("+value)
                        e = e.gsub(index+")", value+")")
                        e = e.gsub("["+index, "["+value)
                        e = e.gsub(index+"]", value+"]")
                        e = e.gsub("=>"+index, "=>"+value)
                        e = e.gsub("<="+index, "<="+value)
                        e = e.gsub(">"+index, ">"+value)
                        e = e.gsub("<"+index, "<"+value)
                        e = e.gsub("="+index, "="+value)
                        e = e.gsub("=> "+index, "=> "+value)
                        e = e.gsub("<= "+index, "<= "+value)
                        e = e.gsub("> "+index, "> "+value)
                        e = e.gsub("< "+index, "< "+value)
                        e = e.gsub("= "+index, "= "+value)
                end
                e = "+"+e unless (coefficient.include?("-") || vc_index==0)
                final_text += e
        end
        final_text
end
sum_constants(text) click to toggle source
# File lib/opl.rb, line 388
def self.sum_constants(text)
        #in: "100+ 10-3"
        #out: "107"
        constants = self.get_constants(text)[:formatted]
        if constants.to_s.include?(".")
                constants.map{|c|c.to_f}.inject("+").to_s
        else
                constants.map{|c|c.to_i}.inject("+").to_s
        end
end
sum_indices(constraint) click to toggle source
# File lib/opl.rb, line 473
def self.sum_indices(constraint)
        # pieces_to_sub = constraint.scan(/[a-z]\[\d[\d\+\-]+\]/)
        # pieces_to_sub = constraint.scan(/[a-z\]]\[\d[\d\+\-]+\]/)
        pieces_to_sub = constraint.scan(/\[[\d\+\-]+\]/)
        pieces_to_sub.each do |piece|
                characters_to_sum = piece.scan(/[\d\+\-]+/)[0]
                index_sum = self.sum_constants(characters_to_sum)
                new_piece = piece.gsub(characters_to_sum, index_sum)
                constraint = constraint.gsub(piece, new_piece)
        end
        return(constraint)
end
sum_variables(formatted_constraint, lp) click to toggle source
# File lib/opl.rb, line 508
def self.sum_variables(formatted_constraint, lp)
        #in: x + y - z + x[3] + z + y - z + x - y <= 0
        #out: 2*x + y - z + x[3] <= 0
        helper = self
        lhs = helper.sides(formatted_constraint)[:lhs]
        formatted_lhs = helper.add_ones(lhs, lp)
        vars = helper.variables(formatted_lhs, lp)
        coefs = helper.coefficients(formatted_lhs, lp)
        var_coef_hash = {}
        vars.each_index do |i|
                var = vars[i]
                coef = coefs[i]
                if var_coef_hash[var]
                        var_coef_hash[var] += coefs[i].to_f
                else
                        var_coef_hash[var] = coefs[i].to_f
                end
        end
        new_lhs = ""
        var_coef_hash.keys.each do |key|
                coef = var_coef_hash[key].to_s
                var = key
                coef = "+"+coef unless coef.include?("-")
                new_lhs += coef+"*"+var
        end
        if new_lhs[0] == "+"
                new_lhs = new_lhs[1..-1]
        end
        formatted_constraint.gsub(lhs, new_lhs)
end
variables(text, lp) click to toggle source
# File lib/opl.rb, line 307
def self.variables(text, lp)#parameter is one side of the equation
        text = self.add_ones(text, lp)
        text = text.gsub("abs","").gsub("(","").gsub(")","")
        variables = text.scan(/[a-z][\[\]\d]*/)
        raise("The variable letter a is reserved for special processes. Please rename your variable to something other than a.") if variables.join.include?("a")
        raise("The variable letter m is reserved for special processes. Please rename your variable to something other than m.") if variables.join.include?("m")
        return variables
end