class RAMS::Solvers::SCIP

Interface to SCIP

Public Instance Methods

solve_and_parse(model, model_path, solution_path) click to toggle source
# File lib/rams/solvers/scip.rb, line 8
def solve_and_parse(model, model_path, solution_path)
  output = call_solver model, model_path, solution_path
  parse_solution model, output
end
solver_command(model_path, _solution_path, args) click to toggle source
# File lib/rams/solvers/scip.rb, line 13
def solver_command(model_path, _solution_path, args)
  ['scip', '-c', "read #{model_path}"] + args +
    ['-c', 'optimize', '-c', 'display solution', '-c', 'display dualsolution', '-c', 'quit']
end

Private Instance Methods

dual_value(model, dual) click to toggle source
# File lib/rams/solvers/scip.rb, line 58
def dual_value(model, dual)
  model.sense == :max ? -dual : dual
end
parse_dual(model, lines) click to toggle source
# File lib/rams/solvers/scip.rb, line 44
def parse_dual(model, lines)
  dual = model.constraints.values.map { |c| [c, 0.0] }.to_h
  dual.merge(solution_lines(lines).map do |l|
    comps = l.split
    model.constraints[comps[0]].nil? ? [] : [model.constraints[comps[0]], dual_value(model, comps[1].to_f)]
  end.reject(&:empty?).to_h)
end
parse_objective(_model, lines) click to toggle source
# File lib/rams/solvers/scip.rb, line 30
def parse_objective(_model, lines)
  status = (lines.select { |l| l =~ /^objective value:/ }.first || '').split
  return nil if status.size < 3
  status[2].to_f
end
parse_primal(model, lines) click to toggle source
# File lib/rams/solvers/scip.rb, line 36
def parse_primal(model, lines)
  primal = model.variables.values.map { |v| [v, 0.0] }.to_h
  primal.merge(solution_lines(lines).map do |l|
    comps = l.split
    model.variables[comps[0]].nil? ? [] : [model.variables[comps.first], comps[1].to_f]
  end.reject(&:empty?).to_h)
end
parse_status(_model, lines) click to toggle source
# File lib/rams/solvers/scip.rb, line 20
def parse_status(_model, lines)
  return :undefined if lines.count < 1
  status = lines.select { |l| l =~ /^SCIP Status/ }.first
  return :optimal if status =~ /optimal/i
  return :unknown if status =~ /(unknown|infeasible or unbounded)/i
  return :infeasible if status =~ /infeasible/i
  return :unbounded if status =~ /unbounded/i
  :feasible
end
solution_lines(lines) click to toggle source
# File lib/rams/solvers/scip.rb, line 52
def solution_lines(lines)
  start_idx = lines.index { |l| l =~ /^objective value:/ }
  return [] unless start_idx
  lines[start_idx, lines.count]
end