Class: Cbc::ConflictSolver

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

Instance Method Summary collapse

Constructor Details

#initialize(problem) ⇒ ConflictSolver

Returns a new instance of ConflictSolver.



5
6
7
8
9
10
11
# File 'lib/ruby-cbc/conflict_solver.rb', line 5

def initialize(problem)
  # clone the model minus the objective
  @model = Model.new
  @model.vars = problem.model.vars
  @model.constraints = problem.model.constraints
  @problem = problem
end

Instance Method Details

#find_conflictObject



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
# File 'lib/ruby-cbc/conflict_solver.rb', line 13

def find_conflict
  crs = Util::CompressedRowStorage.from_model(@model)
  continuous = is_continuous_conflict?(crs)
  unless continuous
    p = Problem.from_compressed_row_storage(crs, continuous: false)
    return [] unless infeasible?(p)
  end
  clusters = [crs.nb_constraints]
  max_iter = 1
  conflict_set_size = 0
  loop do
    range_idxs = first_failing(conflict_set_size, crs, continuous: continuous, max_iterations: max_iter)
    break if range_idxs.nil?
    puts "RANGE #{range_idxs}"
    crs = crs.restrict_to_n_constraints(range_idxs.max + 1)
    crs.move_constraint_to_start(range_idxs)
    clusters.insert(0, range_idxs.size)
    clusters[-1] = range_idxs.min - conflict_set_size
    conflict_set_size += range_idxs.size

    # Test conflict set
    crs2 = crs.restrict_to_n_constraints(conflict_set_size)
    problem = Problem.from_compressed_row_storage(crs2, continuous: continuous)
    if infeasible?(problem)
      puts "CONFLICT"
      clusters.delete_at(-1)
      break if clusters.size == conflict_set_size

      crs = crs2
    end

    nb_clusters_one_constraint = 0
    clusters.reverse_each do |nb_constraints|
      break if nb_constraints > 1
      nb_clusters_one_constraint += 1
    end
    if nb_clusters_one_constraint > 0
      crs.move_constraint_to_start((crs.nb_constraints - nb_clusters_one_constraint)..(crs.nb_constraints - 1))
      clusters[nb_clusters_one_constraint, clusters.size - nb_clusters_one_constraint] =
        clusters[0, clusters.size - nb_clusters_one_constraint]
      clusters[0, nb_clusters_one_constraint] = Array.new(nb_clusters_one_constraint, 1)
    end

    conflict_set_size = crs.nb_constraints - clusters[-1]
    puts "CLUSTERS #{clusters.inspect}"
    puts "VARS #{crs.col_idx.uniq.size}"
  end
  crs.model.constraints[0, conflict_set_size]
end

#is_continuous_conflict?(crs) ⇒ Boolean

Returns:

  • (Boolean)


63
64
65
66
# File 'lib/ruby-cbc/conflict_solver.rb', line 63

def is_continuous_conflict?(crs)
  problem = Problem.from_compressed_row_storage(crs, continuous: true)
  infeasible?(problem)
end