mirror of
https://github.com/Z3Prover/z3
synced 2025-04-06 17:44:08 +00:00
Debug Network Simplex implementation
This commit is contained in:
parent
883018b405
commit
53d365bc44
|
@ -271,9 +271,13 @@ namespace smt {
|
|||
if (m_pred[u] == v) {
|
||||
std::swap(u, v);
|
||||
}
|
||||
if ((m_states[m_entering_edge] == UPPER) == m_in_edge_dir) {
|
||||
|
||||
for (node n = p; n != -1; n = m_pred[n]) {
|
||||
// q should be in T_v so swap p and q
|
||||
std::swap(p, q);
|
||||
if (n == v) {
|
||||
std::swap(p, q);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("network_flow", {
|
||||
|
@ -297,60 +301,62 @@ namespace smt {
|
|||
n = next;
|
||||
}
|
||||
|
||||
TRACE("network_flow", tout << "Graft T_q and T_r'\n";);
|
||||
TRACE("network_flow", tout << pp_vector("Predecessors", m_pred, true) << pp_vector("Upwards", m_upwards););
|
||||
|
||||
// Graft T_q and T_r'
|
||||
m_thread[x] = q;
|
||||
m_thread[z] = y;
|
||||
n = q;
|
||||
last = m_final[q];
|
||||
while (n != last && n != -1) {
|
||||
m_depth[n] += 1 + m_depth[p];
|
||||
n = m_pred[n];
|
||||
}
|
||||
|
||||
node gamma = m_thread[m_final[p]];
|
||||
n = p;
|
||||
last = m_pred[gamma];
|
||||
while (n != last && n != -1) {
|
||||
m_final[n] = z;
|
||||
n = m_pred[n];
|
||||
}
|
||||
|
||||
TRACE("network_flow", tout << "Update T_r'\n";);
|
||||
|
||||
// Update T_r'
|
||||
node phi = m_rev_thread[v];
|
||||
// Do this before updating data structures
|
||||
node gamma_p = m_pred[m_thread[m_final[p]]];
|
||||
node gamma_v = m_pred[m_thread[m_final[v]]];
|
||||
node theta = m_thread[m_final[v]];
|
||||
|
||||
gamma = m_thread[m_final[v]];
|
||||
|
||||
// Check that f(u) is not in T_v
|
||||
bool found_final_u = false;
|
||||
for (node n = v; n == m_final[v]; n = m_thread[n]) {
|
||||
for (node n = v; n != theta; n = m_thread[n]) {
|
||||
if (n == m_final[u]) {
|
||||
found_final_u = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node phi = m_rev_thread[v];
|
||||
node delta = found_final_u ? phi : m_final[u];
|
||||
n = u;
|
||||
last = m_pred[gamma];
|
||||
while (n != last && n != -1) {
|
||||
m_final[n] = delta;
|
||||
n = m_pred[n];
|
||||
|
||||
TRACE("network_flow", tout << "Graft T_q and T_r'\n";);
|
||||
|
||||
// Graft T_q and T_r'
|
||||
for (node n = p; n != gamma_p && n != -1; n = m_pred[n]) {
|
||||
TRACE("network_flow", tout << "1: m_final[" << n << "] |-> " << z << "\n";);
|
||||
m_final[n] = z;
|
||||
}
|
||||
|
||||
m_thread[x] = q;
|
||||
m_rev_thread[q] = x;
|
||||
m_thread[z] = y;
|
||||
m_rev_thread[y] = z;
|
||||
// Increase depths of all children in T_q
|
||||
last = m_thread[m_final[q]];
|
||||
for (node n = q; n != last; n = m_thread[n]) {
|
||||
m_depth[n] += 1 + m_depth[p] - m_depth[q];
|
||||
}
|
||||
|
||||
TRACE("network_flow", tout << "Update T_r'\n";);
|
||||
|
||||
// Update T_r'
|
||||
m_thread[phi] = theta;
|
||||
m_rev_thread[theta] = phi;
|
||||
|
||||
for (node n = u; n != gamma_v && n != -1; n = m_pred[n]) {
|
||||
TRACE("network_flow", tout << "2: m_final[" << n << "] |-> " << delta << "\n";);
|
||||
m_final[n] = delta;
|
||||
}
|
||||
|
||||
TRACE("network_flow", tout << pp_vector("Last Successors", m_final, true) << pp_vector("Depths", m_depth););
|
||||
|
||||
// Reroot T_v at q
|
||||
if (v != q) {
|
||||
TRACE("network_flow", tout << "Reroot T_v at q\n";);
|
||||
|
||||
node n = v;
|
||||
last = q;
|
||||
|
||||
node alpha1, alpha2;
|
||||
node prev = q;
|
||||
while (n != last && n != -1) {
|
||||
for (node n = v; n != q && n != -1; n = m_pred[n]) {
|
||||
// Find all immediate successors of n
|
||||
node t1 = m_thread[n];
|
||||
node t2 = m_thread[m_final[t1]];
|
||||
|
@ -370,26 +376,18 @@ namespace smt {
|
|||
m_thread[n] = alpha1;
|
||||
m_thread[m_final[alpha1]] = alpha2;
|
||||
m_thread[m_final[alpha2]] = prev;
|
||||
prev = n;
|
||||
n = m_pred[n];
|
||||
prev = n;
|
||||
}
|
||||
m_thread[m_final[q]] = prev;
|
||||
}
|
||||
|
||||
for (node n = m_thread[v]; m_pred[n] != -1; n = m_pred[n]) {
|
||||
m_depth[n] = m_depth[m_pred[n]] + 1;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_thread.size(); ++i) {
|
||||
m_rev_thread[m_thread[i]] = i;
|
||||
}
|
||||
|
||||
TRACE("network_flow", {
|
||||
tout << pp_vector("Predecessors", m_pred, true) << pp_vector("Threads", m_thread);
|
||||
tout << pp_vector("Reverse Threads", m_rev_thread) << pp_vector("Last Successors", m_final);
|
||||
tout << pp_vector("Depths", m_depth) << pp_vector("Upwards", m_upwards);
|
||||
tout << pp_vector("Threads", m_thread, true) << pp_vector("Reverse Threads", m_rev_thread);
|
||||
});
|
||||
SASSERT(check_well_formed());
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
|
@ -427,8 +425,7 @@ namespace smt {
|
|||
template<typename Ext>
|
||||
bool network_flow<Ext>::min_cost() {
|
||||
initialize();
|
||||
while (choose_entering_edge()) {
|
||||
SASSERT(check_well_formed());
|
||||
while (choose_entering_edge()) {
|
||||
bool bounded = choose_leaving_edge();
|
||||
if (!bounded) return false;
|
||||
update_flows();
|
||||
|
@ -438,6 +435,7 @@ namespace smt {
|
|||
update_spanning_tree();
|
||||
update_potentials();
|
||||
TRACE("network_flow", tout << "Spanning tree:\n" << display_spanning_tree(););
|
||||
SASSERT(check_well_formed());
|
||||
}
|
||||
else {
|
||||
m_states[m_leaving_edge] = m_states[m_leaving_edge] == LOWER ? UPPER : LOWER;
|
||||
|
|
Loading…
Reference in a new issue