Class: Cbc::Problem

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-cbc/problem.rb

Defined Under Namespace

Classes: VarData

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, continuous: false) ⇒ Problem

Returns a new instance of Problem.



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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ruby-cbc/problem.rb', line 6

def initialize(model, continuous: false)

  @int_arrays = []
  @double_arrays = []

  @model = model
  @variables = {}
  vars = model.vars
  vars_data = {}
  vars.each_with_index do |v, idx|
    @variables[v] = idx
    vars_data[v] = VarData.new(v, idx, [], [])
  end

  model.constraints.each_with_index do |c, idx|
    c.terms.each do |term|
      v_data = vars_data[term.var]
      v_data.constraints << idx
      v_data.coefs << term.mult
    end
  end

  indexes = []
  rows = []
  coefs = []

  vars.each_with_index do |v, idx|
    v_data = vars_data[v]
    indexes[idx] = rows.count
    rows.concat v_data.constraints
    coefs.concat v_data.coefs
  end

  indexes << rows.count

  objective = Array.new(vars.count, 0)
  if model.objective
    model.objective.terms.each do |term|
      objective[vars_data[term.var].col_idx] = term.mult
    end
  end

  @cbc_model = Cbc_wrapper.Cbc_newModel
  Cbc_wrapper.Cbc_loadProblem(@cbc_model, model.vars.count, model.constraints.count,
                             to_int_array(indexes), to_int_array(rows),
                             to_double_array(coefs), nil, nil, to_double_array(objective),
                             nil, nil)

  # Segmentation errors when setting name
  # Cbc_wrapper.Cbc_setProblemName(@cbc_model, model.name) if model.name

  if model.objective
    obj_sense = model.objective.objective_function == Ilp::Objective::MINIMIZE ? 1 : -1
    Cbc_wrapper.Cbc_setObjSense(@cbc_model, obj_sense)
  end

  model.constraints.each_with_index do |c, idx|
    case c.type
    when Ilp::Constraint::LESS_OR_EQ
      Cbc_wrapper.Cbc_setRowUpper(@cbc_model, idx, c.bound)
    when Ilp::Constraint::GREATER_OR_EQ
      Cbc_wrapper.Cbc_setRowLower(@cbc_model, idx, c.bound)
    when Ilp::Constraint::EQUALS
      Cbc_wrapper.Cbc_setRowUpper(@cbc_model, idx, c.bound)
      Cbc_wrapper.Cbc_setRowLower(@cbc_model, idx, c.bound)
    end
  end
  model.vars.each_with_index do |v, idx|
    if continuous
      Cbc_wrapper.Cbc_setContinuous(@cbc_model, idx)
    else
      case v.kind
      when Ilp::Var::INTEGER_KIND, Ilp::Var::BINARY_KIND
        Cbc_wrapper.Cbc_setInteger(@cbc_model, idx)
      when Ilp::Var::CONTINUOUS_KIND
        Cbc_wrapper.Cbc_setContinuous(@cbc_model, idx)
      end
    end
    Cbc_wrapper.Cbc_setColLower(@cbc_model, idx, v.lower_bound) unless v.lower_bound.nil?
    Cbc_wrapper.Cbc_setColUpper(@cbc_model, idx, v.upper_bound) unless v.upper_bound.nil?
  end

  ObjectSpace.define_finalizer(self, self.class.finalizer(@cbc_model, @int_arrays, @double_arrays))

  @default_solve_params = {
      log: 0,
    }

end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



4
5
6
# File 'lib/ruby-cbc/problem.rb', line 4

def model
  @model
end

Class Method Details

.finalizer(cbc_model, int_arrays, double_arrays) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/ruby-cbc/problem.rb', line 151

def self.finalizer(cbc_model, int_arrays, double_arrays)
  proc do
    Cbc_wrapper.Cbc_deleteModel(cbc_model)
    int_arrays.each { |ar| Cbc_wrapper.delete_intArray(ar) }
    double_arrays.each { |ar| Cbc_wrapper.delete_doubleArray(ar) }
  end
end

Instance Method Details

#best_boundObject

Returns the best know bound so far



139
140
141
# File 'lib/ruby-cbc/problem.rb', line 139

def best_bound
  Cbc_wrapper.Cbc_getBestPossibleObjValue(@cbc_model)
end

#find_conflictObject



143
144
145
# File 'lib/ruby-cbc/problem.rb', line 143

def find_conflict
  @conflict_set ||= ConflictSolver.new(model).find_conflict
end

#find_conflict_varsObject



147
148
149
# File 'lib/ruby-cbc/problem.rb', line 147

def find_conflict_vars
  @conflict_vars ||= find_conflict.map(&:vars).flatten.uniq
end

#objective_valueObject



134
135
136
# File 'lib/ruby-cbc/problem.rb', line 134

def objective_value
  Cbc_wrapper.Cbc_getObjValue(@cbc_model)
end

#proven_infeasible?Boolean

Returns:

  • (Boolean)


122
123
124
# File 'lib/ruby-cbc/problem.rb', line 122

def proven_infeasible?
  Cbc_wrapper.Cbc_isProvenInfeasible(@cbc_model) == 1
end

#proven_optimal?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'lib/ruby-cbc/problem.rb', line 118

def proven_optimal?
  Cbc_wrapper.Cbc_isProvenOptimal(@cbc_model) == 1
end

#set_time_limit(seconds) ⇒ Object



114
115
116
# File 'lib/ruby-cbc/problem.rb', line 114

def set_time_limit(seconds)
  @default_solve_params[:sec] = seconds
end

#solution_limit_reached?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/ruby-cbc/problem.rb', line 130

def solution_limit_reached?
  Cbc_wrapper.Cbc_isSolutionLimitReached(@cbc_model) == 1
end

#solve(params = {}) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/ruby-cbc/problem.rb', line 96

def solve(params = {})
  @default_solve_params.merge(params).each do |name, value|
    Cbc_wrapper.Cbc_setParameter(@cbc_model, name.to_s, value.to_s)
  end
  Cbc_wrapper.Cbc_solve(@cbc_model)
  @solution = Cbc_wrapper::DoubleArray.frompointer(Cbc_wrapper.Cbc_getColSolution(@cbc_model))
end

#time_limit_reached?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/ruby-cbc/problem.rb', line 126

def time_limit_reached?
  Cbc_wrapper.Cbc_isSecondsLimitReached(@cbc_model) == 1
end

#value_of(var) ⇒ Object



104
105
106
107
108
109
110
111
112
# File 'lib/ruby-cbc/problem.rb', line 104

def value_of(var)
  idx = @variables[var]
  return nil if idx.nil?
  if var.kind == Ilp::Var::CONTINUOUS_KIND
    @solution[idx]
  else
    @solution[idx].round
  end
end

#writeObject



159
160
161
# File 'lib/ruby-cbc/problem.rb', line 159

def write
  Cbc_wrapper.Cbc_writeMps(@cbc_model, "test")
end