|
1 | 1 | /*++
|
2 |
| -Copyright (c) 2020 Microsoft Corporation |
| 2 | + Copyright (c) 2020 Microsoft Corporation |
3 | 3 |
|
4 |
| -Module Name: |
| 4 | + Module Name: |
5 | 5 |
|
6 |
| - int_branch.cpp |
| 6 | + int_branch.cpp |
7 | 7 |
|
8 |
| -Abstract: |
| 8 | + Abstract: |
9 | 9 |
|
10 |
| - Branch heuristic |
| 10 | + Branch heuristic |
11 | 11 |
|
12 |
| -Author: |
13 |
| - Lev Nachmanson (levnach) |
14 |
| - Nikolaj Bjorner (nbjorner) |
| 12 | + Author: |
| 13 | + Lev Nachmanson (levnach) |
| 14 | + Nikolaj Bjorner (nbjorner) |
15 | 15 |
|
16 |
| -Revision History: |
17 |
| ---*/ |
| 16 | + Revision History: |
| 17 | + --*/ |
18 | 18 |
|
19 | 19 | #include "math/lp/int_solver.h"
|
20 | 20 | #include "math/lp/lar_solver.h"
|
21 | 21 | #include "math/lp/int_branch.h"
|
22 | 22 |
|
23 | 23 | namespace lp {
|
24 | 24 |
|
25 |
| - int_branch::int_branch(int_solver& lia):lia(lia), lra(lia.lra) {} |
26 |
| - |
27 |
| - lia_move int_branch::operator()() { |
28 |
| - int j = find_any_inf_int_column_basis_first(); |
29 |
| - return j == -1? lia_move::sat : create_branch_on_column(j); |
30 |
| - } |
31 |
| - |
32 |
| - int int_branch::find_any_inf_int_column_basis_first() { |
33 |
| - int j = find_inf_int_base_column(); |
34 |
| - return j != -1 ? j : find_inf_int_nbasis_column(); |
35 |
| - } |
| 25 | +int_branch::int_branch(int_solver& lia):lia(lia), lra(lia.lra) {} |
36 | 26 |
|
| 27 | +lia_move int_branch::operator()() { |
| 28 | + int j = find_any_inf_int_column_basis_first(); |
| 29 | + return j == -1? lia_move::sat : create_branch_on_column(j); |
| 30 | +} |
37 | 31 |
|
38 |
| - lia_move int_branch::create_branch_on_column(int j) { |
39 |
| - TRACE("check_main_int", tout << "branching" << std::endl;); |
40 |
| - lp_assert(lia.m_t.is_empty()); |
41 |
| - lp_assert(j != -1); |
42 |
| - lia.m_t.add_monomial(mpq(1), lra.adjust_column_index_to_term_index(j)); |
43 |
| - if (lia.is_free(j)) { |
44 |
| - lia.m_upper = lia.random() % 2; |
45 |
| - lia.m_k = mpq(0); |
46 |
| - } |
47 |
| - else { |
48 |
| - lia.m_upper = lia.random() % 2; |
49 |
| - lia.m_k = lia.m_upper? floor(lia.get_value(j)) : ceil(lia.get_value(j)); |
50 |
| - } |
51 |
| - |
52 |
| - TRACE("int_solver", |
53 |
| - lia.display_column(tout << "branching v" << j << " = " << lia.get_value(j) << "\n", j); |
54 |
| - tout << "k = " << lia.m_k << std::endl;); |
55 |
| - return lia_move::branch; |
56 |
| - } |
| 32 | +int int_branch::find_any_inf_int_column_basis_first() { |
| 33 | + int j = find_inf_int_base_column(); |
| 34 | + return j != -1 ? j : find_inf_int_nbasis_column(); |
| 35 | +} |
57 | 36 |
|
58 |
| - int int_branch::find_inf_int_base_column() { |
59 |
| - unsigned inf_int_count = 0; |
60 |
| - int j = find_inf_int_boxed_base_column_with_smallest_range(inf_int_count); |
61 |
| - if (j != -1) { |
62 |
| - return j; |
63 |
| - } |
64 |
| - if (inf_int_count == 0) |
65 |
| - return -1; |
66 |
| - unsigned k = lia.random() % inf_int_count; |
67 |
| - return get_kth_inf_int(k); |
| 37 | +lia_move int_branch::create_branch_on_column(int j) { |
| 38 | + TRACE("check_main_int", tout << "branching" << std::endl;); |
| 39 | + lp_assert(lia.m_t.is_empty()); |
| 40 | + lp_assert(j != -1); |
| 41 | + lia.m_t.add_monomial(mpq(1), lra.adjust_column_index_to_term_index(j)); |
| 42 | + if (lia.is_free(j)) { |
| 43 | + lia.m_upper = lia.random() % 2; |
| 44 | + lia.m_k = mpq(0); |
68 | 45 | }
|
69 |
| - |
70 |
| - int int_branch::get_kth_inf_int(unsigned k) const { |
71 |
| - for (unsigned j : lra.r_basis()) |
72 |
| - if (lia.column_is_int_inf(j) && k-- == 0) |
73 |
| - return j; |
74 |
| - lp_assert(false); |
75 |
| - return -1; |
| 46 | + else { |
| 47 | + lia.m_upper = lia.random() % 2; |
| 48 | + lia.m_k = lia.m_upper? floor(lia.get_value(j)) : ceil(lia.get_value(j)); |
76 | 49 | }
|
77 |
| - |
78 |
| - int int_branch::find_inf_int_nbasis_column() const { |
79 | 50 |
|
80 |
| - for (unsigned j : lra.r_nbasis()) |
81 |
| - if (lia.column_is_int_inf(j)) { |
82 |
| - return j; |
| 51 | + TRACE("int_solver", |
| 52 | + lia.display_column(tout << "branching v" << j << " = " << lia.get_value(j) << "\n", j); |
| 53 | + tout << "k = " << lia.m_k << std::endl;); |
| 54 | + return lia_move::branch; |
| 55 | +} |
| 56 | + |
| 57 | + |
| 58 | +int int_branch::find_inf_int_nbasis_column() const { |
| 59 | + unsigned n = 0; |
| 60 | + int r = -1; |
| 61 | + for (unsigned j : lra.r_nbasis()) { |
| 62 | + SASSERT(!lia.column_is_int_inf(j) || !lia.is_fixed(j)); |
| 63 | + if (lia.column_is_int_inf(j)) { |
| 64 | + if (n == 0) { |
| 65 | + r = j; |
| 66 | + n = 1; |
| 67 | + } else if (lia.random() % (++n) == 0) { |
| 68 | + r = j; |
83 | 69 | }
|
84 |
| - return -1; |
| 70 | + } |
85 | 71 | }
|
| 72 | + return r; |
| 73 | +} |
86 | 74 |
|
87 |
| - int int_branch::find_inf_int_boxed_base_column_with_smallest_range(unsigned & inf_int_count) { |
88 |
| - inf_int_count = 0; |
89 |
| - int result = -1; |
90 |
| - mpq range; |
91 |
| - mpq new_range; |
92 |
| - mpq small_range_thresold(1024); |
93 |
| - unsigned n = 0; |
94 |
| - lar_core_solver & lcs = lra.m_mpq_lar_core_solver; |
95 |
| - |
96 |
| - for (unsigned j : lra.r_basis()) { |
97 |
| - if (!lia.column_is_int_inf(j)) |
98 |
| - continue; |
99 |
| - inf_int_count++; |
100 |
| - if (!lia.is_boxed(j)) |
| 75 | +int int_branch::find_inf_int_base_column() { |
| 76 | + int result = -1; |
| 77 | + mpq range; |
| 78 | + mpq new_range; |
| 79 | + mpq small_range_thresold(1024); |
| 80 | + unsigned n = 0; |
| 81 | + lar_core_solver & lcs = lra.m_mpq_lar_core_solver; |
| 82 | + bool small = false; |
| 83 | + for (unsigned j : lra.r_basis()) { |
| 84 | + SASSERT(!lia.column_is_int_inf(j) || !lia.is_fixed(j)); |
| 85 | + if (!lia.column_is_int_inf(j)) |
| 86 | + continue; |
| 87 | + bool boxed = lia.is_boxed(j); |
| 88 | + if (small) { |
| 89 | + if (!boxed) |
101 | 90 | continue;
|
102 |
| - lp_assert(!lia.is_fixed(j)); |
103 | 91 | new_range = lcs.m_r_upper_bounds()[j].x - lcs.m_r_lower_bounds()[j].x;
|
104 |
| - if (new_range > small_range_thresold) |
105 |
| - continue; |
106 |
| - if (result == -1 || new_range < range) { |
107 |
| - result = j; |
108 |
| - range = new_range; |
109 |
| - n = 1; |
110 |
| - } |
111 |
| - else if (new_range == range && lia.random() % (++n) == 0) { |
112 |
| - lp_assert(n > 1); |
113 |
| - result = j; |
| 92 | + if (new_range <= small_range_thresold) { |
| 93 | + if (new_range < range) { |
| 94 | + n = 1; |
| 95 | + result = j; |
| 96 | + range = new_range; |
| 97 | + } else if (new_range == range && lia.random() % (++n) == 0) { |
| 98 | + result = j; |
| 99 | + } |
114 | 100 | }
|
| 101 | + } else if (boxed && |
| 102 | + (new_range = lcs.m_r_upper_bounds()[j].x - lcs.m_r_lower_bounds()[j].x) |
| 103 | + <= small_range_thresold) { |
| 104 | + small = true; |
| 105 | + result = j; |
| 106 | + range = new_range; |
| 107 | + n = 1; |
| 108 | + } else if (result == -1) { |
| 109 | + result = j; |
| 110 | + n = 1; |
| 111 | + } else if (lia.random() % (++n) == 0) { |
| 112 | + result = j; |
115 | 113 | }
|
116 |
| - return result; |
117 | 114 | }
|
| 115 | + return result; |
| 116 | +} |
118 | 117 |
|
119 | 118 | }
|
0 commit comments