mirror of
https://github.com/Z3Prover/z3
synced 2025-04-29 20:05:51 +00:00
Implement three pivot rules
This commit is contained in:
parent
e412d6175d
commit
0d6ffe6b31
3 changed files with 226 additions and 48 deletions
|
@ -129,30 +129,6 @@ namespace smt {
|
|||
TRACE("network_flow", tout << pp_vector("Flows", m_flows, true););
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
bool network_flow<Ext>::choose_entering_edge() {
|
||||
TRACE("network_flow", tout << "choose_entering_edge...\n";);
|
||||
unsigned num_edges = m_graph.get_num_edges();
|
||||
for (unsigned i = 0; i < num_edges; ++i) {
|
||||
node src = m_graph.get_source(i);
|
||||
node tgt = m_graph.get_target(i);
|
||||
if (m_states[i] != BASIS) {
|
||||
numeral cost = m_potentials[src] - m_potentials[tgt] - m_graph.get_weight(i);
|
||||
// TODO: add multiple pivoting strategies
|
||||
if (cost.is_pos()) {
|
||||
m_enter_id = i;
|
||||
TRACE("network_flow", {
|
||||
tout << "Found entering edge " << i << " between node ";
|
||||
tout << src << " and node " << tgt << " with reduced cost = " << cost << "...\n";
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("network_flow", tout << "Found no entering edge...\n";);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
bool network_flow<Ext>::choose_leaving_edge() {
|
||||
TRACE("network_flow", tout << "choose_leaving_edge...\n";);
|
||||
|
@ -191,12 +167,29 @@ namespace smt {
|
|||
m_tree.update(m_enter_id, m_leave_id);
|
||||
}
|
||||
|
||||
// FIXME: should declare pivot as a pivot_rule_impl and refactor
|
||||
template<typename Ext>
|
||||
bool network_flow<Ext>::choose_entering_edge(pivot_rule pr) {
|
||||
if (pr == FIRST_ELIGIBLE) {
|
||||
first_eligible_pivot pivot(m_graph, m_potentials, m_states, m_enter_id);
|
||||
return pivot.choose_entering_edge();
|
||||
}
|
||||
else if (pr == BEST_ELIGIBLE) {
|
||||
best_eligible_pivot pivot(m_graph, m_potentials, m_states, m_enter_id);
|
||||
return pivot.choose_entering_edge();
|
||||
}
|
||||
else {
|
||||
candidate_list_pivot pivot(m_graph, m_potentials, m_states, m_enter_id);
|
||||
return pivot.choose_entering_edge();
|
||||
}
|
||||
}
|
||||
|
||||
// Minimize cost flows
|
||||
// Return true if found an optimal solution, and return false if unbounded
|
||||
template<typename Ext>
|
||||
bool network_flow<Ext>::min_cost() {
|
||||
bool network_flow<Ext>::min_cost(pivot_rule pr) {
|
||||
initialize();
|
||||
while (choose_entering_edge()) {
|
||||
while (choose_entering_edge(pr)) {
|
||||
bool bounded = choose_leaving_edge();
|
||||
if (!bounded) return false;
|
||||
update_flows();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue