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
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
|