Class: Opt::Solvers::GlopSolver

Inherits:
AbstractSolver show all
Defined in:
lib/opt/solvers/glop_solver.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractSolver

supports_semi_continuous_variables?, supports_semi_integer_variables?, supports_type?

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/opt/solvers/glop_solver.rb', line 47

def self.available?
  defined?(ORTools)
end

.supported_typesObject



51
52
53
# File 'lib/opt/solvers/glop_solver.rb', line 51

def self.supported_types
  [:lp]
end

Instance Method Details

#solve(sense:, col_lower:, col_upper:, obj:, offset:, verbose:, time_limit:, constraints_by_var:, vars:) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/opt/solvers/glop_solver.rb', line 4

def solve(sense:, col_lower:, col_upper:, obj:, offset:, verbose:, time_limit:, constraints_by_var:, vars:, **)
  solver = ORTools::Solver.new("GLOP")

  # create vars
  vars2 =
    vars.map.with_index do |v, i|
      solver.num_var(col_lower[i], col_upper[i], v.name)
    end

  var_index = vars.map.with_index.to_h

  # add constraints
  constraints_by_var.each do |left, op, right|
    expr = left.sum { |k, v| vars2[var_index[k]] * v }
    case op
    when :<=
      solver.add(expr <= right)
    when :>=
      solver.add(expr >= right)
    else
      solver.add(expr == right)
    end
  end

  # add objective
  objective = vars2.zip(obj).sum { |v, o| v * o }

  if sense == :maximize
    solver.maximize(objective)
  else
    solver.minimize(objective)
  end

  solver.time_limit = time_limit if time_limit
  status = solver.solve

  {
    status: status,
    objective: solver.objective.value + offset,
    x: vars2.map(&:solution_value)
  }
end