Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Aleph::Network_Simplex< Net > Class Template Reference

Network Simplex algorithm for minimum cost flow. More...

#include <tpl_netcost.H>

Collaboration diagram for Aleph::Network_Simplex< Net >:
[legend]

Public Types

using Node = typename Net::Node
 
using Arc = typename Net::Arc
 
using Flow_Type = typename Net::Flow_Type
 
using Node_Info = Simplex_Node_Info< Flow_Type >
 
using Arc_Info = Simplex_Arc_Info< Flow_Type >
 

Public Member Functions

 Network_Simplex (Net &network)
 Construct Network Simplex solver.
 
void set_lower_bound (Arc *a, Flow_Type lower_bound)
 Set lower bound for an arc.
 
Flow_Type get_lower_bound (Arc *a) const
 Get lower bound for an arc.
 
bool is_at_lower_bound (Arc *a) const
 Check if arc flow is at lower bound.
 
bool is_at_upper_bound (Arc *a) const
 Check if arc flow is at upper bound (capacity).
 
Flow_Type residual_capacity (Arc *a) const
 Get residual capacity (room to increase flow).
 
Flow_Type residual_lower (Arc *a) const
 Get residual lower (room to decrease flow).
 
size_t run (Flow_Type unused=0)
 Execute Network Simplex algorithm.
 
size_t get_num_pivots () const
 Return number of pivots performed in last run.
 
const NetworkSimplexStatsget_stats () const noexcept
 Return execution statistics from last run.
 
void print_stats () const
 Print execution statistics to stdout.
 
size_t force_partial_arcs_into_tree ()
 Phase I: Force all partial-flow arcs into the spanning tree.
 
bool is_valid_basic_solution () const
 Check if current solution is a valid basic feasible solution.
 
size_t count_non_tree_partial_arcs () const
 Count arcs with partial flow not in tree.
 
bool verify_tree_reduced_costs () const
 Verify that tree arcs have zero reduced cost.
 
bool verify_tree_integrity () const
 Verify tree integrity - all parent_arcs should be Tree arcs.
 
void print_diagnostics () const
 Print diagnostic information about current state.
 

Private Member Functions

Node_Infoninfo (Node *p)
 Get node info reference.
 
const Node_Infoninfo (Node *p) const
 Get node info const reference.
 
Arc_Infoainfo (Arc *a)
 Get arc info reference.
 
const Arc_Infoainfo (Arc *a) const
 Get arc info const reference.
 
Nodeparent (Node *p) const
 Get parent node.
 
Arcparent_arc (Node *p) const
 Get parent arc.
 
long depth (Node *p) const
 Get depth.
 
Flow_Type potential (Node *p) const
 Get potential.
 
bool is_zero (Flow_Type x) const
 Check if value is effectively zero.
 
Flow_Type reduced_cost (Arc *a) const
 Compute reduced cost of an arc.
 
void init_structures ()
 Initialize data structures.
 
bool is_partial_flow (Arc *a) const
 Check if arc has partial flow (strictly between bounds).
 
void build_spanning_tree ()
 Build initial spanning tree from source.
 
Arcfind_entering_arc ()
 Find entering arc using most negative reduced cost.
 
Nodefind_lca (Node *u, Node *v)
 Find the lowest common ancestor of two nodes.
 
bool augment_and_find_leaving (Arc *entering, Flow_Type &delta, Arc *&leaving, bool &leaving_goes_lower)
 Augment flow around the cycle and find leaving arc.
 
void pivot_tree (Arc *entering, Arc *leaving, bool leaving_goes_lower)
 Update tree structure after pivot.
 

Static Private Member Functions

static Flow_Type eps ()
 Epsilon for floating-point comparisons.
 

Private Attributes

Netnet
 
DynArray< Node_Infonode_info
 
DynArray< Arc_Infoarc_info
 
DynMapTree< Node *, size_tnode_to_idx
 
DynMapTree< Arc *, size_tarc_to_idx
 
Noderoot = nullptr
 
size_t num_pivots = 0
 
long lca_mark = 0
 
NetworkSimplexStats stats
 
bool support_lower_bounds = false
 

Static Private Attributes

static constexpr Flow_Type Inf = std::numeric_limits<Flow_Type>::max()
 

Detailed Description

template<class Net>
class Aleph::Network_Simplex< Net >

Network Simplex algorithm for minimum cost flow.

This class implements the Network Simplex algorithm, a specialized version of the Simplex method for minimum cost network flow problems. It maintains a spanning tree of basic arcs and iteratively improves the solution through pivoting operations.

Algorithm Overview

The algorithm uses a two-phase approach:

Phase I: Establish Basic Feasible Solution

After Ford-Fulkerson, some arcs may have partial flow (0 < flow < cap). For a valid basic solution, these arcs MUST be in the spanning tree (non-basic arcs must be at their bounds). Phase I forces all partial-flow arcs into the tree through pivots.

Phase II: Cost Optimization

Standard Network Simplex that iteratively:

  1. Finds an entering arc with negative reduced cost
  2. Identifies the cycle created by adding this arc
  3. Determines the leaving arc (blocking arc in the cycle)
  4. Performs the pivot: updates flows and tree structure

Implementation Notes

This implementation follows the presentation in Sedgewick's "Algorithms" with some adaptations for the Aleph-w graph representation and the addition of Phase I to handle the basic feasibility requirement.

The algorithm assumes the network already has a feasible flow (typically from a max-flow algorithm like Ford-Fulkerson). It then optimizes the cost while maintaining the same flow value.

Template Parameters
NetNetwork type (must be Net_Cost_Graph or compatible).
See also
max_flow_min_cost_by_network_simplex
max_flow_min_cost_by_cycle_canceling

Definition at line 1040 of file tpl_netcost.H.

Member Typedef Documentation

◆ Arc

Definition at line 1044 of file tpl_netcost.H.

◆ Arc_Info

Definition at line 1047 of file tpl_netcost.H.

◆ Flow_Type

◆ Node

Definition at line 1043 of file tpl_netcost.H.

◆ Node_Info

Definition at line 1046 of file tpl_netcost.H.

Constructor & Destructor Documentation

◆ Network_Simplex()

template<class Net >
Aleph::Network_Simplex< Net >::Network_Simplex ( Net network)
inlineexplicit

Construct Network Simplex solver.

Parameters
[in,out]networkThe network to optimize.

Definition at line 1765 of file tpl_netcost.H.

Member Function Documentation

◆ ainfo() [1/2]

◆ ainfo() [2/2]

template<class Net >
const Arc_Info & Aleph::Network_Simplex< Net >::ainfo ( Arc a) const
inlineprivate

◆ augment_and_find_leaving()

template<class Net >
bool Aleph::Network_Simplex< Net >::augment_and_find_leaving ( Arc entering,
Flow_Type delta,
Arc *&  leaving,
bool leaving_goes_lower 
)
inlineprivate

Augment flow around the cycle and find leaving arc.

When entering arc is added, it creates a cycle. This function:

  1. Finds the bottleneck (minimum slack) in the cycle
  2. Updates flows around the cycle
  3. Identifies the leaving arc

For a valid cycle that allows flow redistribution, we need arcs going in both directions (considering the entering arc). If all arcs in the cycle go in the same "global" direction (e.g., all from source towards sink), then we cannot redistribute flow without changing the total flow value.

Parameters
[in]enteringThe entering arc.
[out]deltaFlow change amount.
[out]leavingThe leaving arc (becomes non-basic).
[out]leaving_goes_lowerTrue if leaving arc goes to lower bound.
Returns
true if a valid augmentation was performed.

Definition at line 1394 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Simplex_Node_Info< Ftype >::arc_from_parent, Aleph::Network_Simplex< Net >::find_lca(), Aleph::Lower, Aleph::maps(), Aleph::Network_Simplex< Net >::ninfo(), Aleph::Network_Simplex< Net >::parent(), Aleph::Network_Simplex< Net >::parent_arc(), and Aleph::Simplex_Arc_Info< Ftype >::state.

Referenced by Aleph::Network_Simplex< Net >::force_partial_arcs_into_tree(), and Aleph::Network_Simplex< Net >::run().

◆ build_spanning_tree()

◆ count_non_tree_partial_arcs()

template<class Net >
size_t Aleph::Network_Simplex< Net >::count_non_tree_partial_arcs ( ) const
inline

◆ depth()

template<class Net >
long Aleph::Network_Simplex< Net >::depth ( Node p) const
inlineprivate

◆ eps()

◆ find_entering_arc()

template<class Net >
Arc * Aleph::Network_Simplex< Net >::find_entering_arc ( )
inlineprivate

Find entering arc using most negative reduced cost.

Scans all non-tree arcs and selects the one with the largest violation of the optimality conditions:

  • Arc at Lower bound (flow=0): should have reduced_cost >= 0
  • Arc at Upper bound (flow=cap): should have reduced_cost <= 0

This implementation checks BOTH directions for each arc:

  • Forward direction: increase flow (requires flow < cap, benefits if rc < 0)
  • Backward direction: decrease flow (requires flow > 0, benefits if rc > 0)

This is essential for finding all negative cycles, including those that require reversing flow through arcs with flow > 0.

Returns
Entering arc, or nullptr if optimal.

Definition at line 1298 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::eps(), Aleph::Lower, Aleph::maps(), Aleph::Network_Simplex< Net >::net, Aleph::Network_Simplex< Net >::reduced_cost(), Aleph::Simplex_Arc_Info< Ftype >::state, Aleph::Tree, and Aleph::Upper.

Referenced by Aleph::Network_Simplex< Net >::run().

◆ find_lca()

template<class Net >
Node * Aleph::Network_Simplex< Net >::find_lca ( Node u,
Node v 
)
inlineprivate

Find the lowest common ancestor of two nodes.

Uses marking to efficiently find the LCA in O(d) where d is depth.

Parameters
[in]uFirst node.
[in]vSecond node.
Returns
LCA of u and v.

Definition at line 1355 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::lca_mark, Aleph::maps(), Aleph::Simplex_Node_Info< Ftype >::mark, Aleph::Network_Simplex< Net >::ninfo(), and Aleph::Network_Simplex< Net >::parent().

Referenced by Aleph::Network_Simplex< Net >::augment_and_find_leaving().

◆ force_partial_arcs_into_tree()

template<class Net >
size_t Aleph::Network_Simplex< Net >::force_partial_arcs_into_tree ( )
inline

Phase I: Force all partial-flow arcs into the spanning tree.

For a valid basic feasible solution in Network Simplex, all arcs with flow strictly between bounds (0 < flow < cap) MUST be in the spanning tree. Non-basic arcs must be at their bounds.

This method identifies arcs with partial flow that are not in the tree and forces pivots to include them. Each pivot replaces one tree arc with the entering arc, maintaining exactly N-1 tree arcs.

Returns
Number of forced pivots performed.

Definition at line 1960 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::augment_and_find_leaving(), Aleph::Network_Simplex< Net >::eps(), Aleph::Network_Simplex< Net >::is_partial_flow(), Aleph::Lower, Aleph::maps(), Aleph::Network_Simplex< Net >::net, Aleph::Network_Simplex< Net >::pivot_tree(), Aleph::Simplex_Arc_Info< Ftype >::state, Aleph::Tree, and Aleph::Upper.

Referenced by Aleph::Network_Simplex< Net >::run().

◆ get_lower_bound()

template<class Net >
Flow_Type Aleph::Network_Simplex< Net >::get_lower_bound ( Arc a) const
inline

Get lower bound for an arc.

Parameters
[in]aArc to query.
Returns
Lower bound value (0 if not set).

Definition at line 1788 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), and Aleph::Simplex_Arc_Info< Ftype >::lower_bound.

◆ get_num_pivots()

template<class Net >
size_t Aleph::Network_Simplex< Net >::get_num_pivots ( ) const
inline

Return number of pivots performed in last run.

Definition at line 1926 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::num_pivots.

◆ get_stats()

template<class Net >
const NetworkSimplexStats & Aleph::Network_Simplex< Net >::get_stats ( ) const
inlinenoexcept

Return execution statistics from last run.

Definition at line 1929 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::stats.

◆ init_structures()

◆ is_at_lower_bound()

template<class Net >
bool Aleph::Network_Simplex< Net >::is_at_lower_bound ( Arc a) const
inline

Check if arc flow is at lower bound.

Parameters
[in]aArc to check.
Returns
true if flow equals lower bound.

Definition at line 1798 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::eps(), and Aleph::lower_bound().

◆ is_at_upper_bound()

template<class Net >
bool Aleph::Network_Simplex< Net >::is_at_upper_bound ( Arc a) const
inline

Check if arc flow is at upper bound (capacity).

Parameters
[in]aArc to check.
Returns
true if flow equals capacity.

Definition at line 1808 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::eps().

◆ is_partial_flow()

◆ is_valid_basic_solution()

template<class Net >
bool Aleph::Network_Simplex< Net >::is_valid_basic_solution ( ) const
inline

Check if current solution is a valid basic feasible solution.

A valid BFS requires:

  1. All tree arcs can have any flow
  2. All non-tree arcs must be at their bounds (flow=0 or flow=cap)
Returns
true if valid BFS, false otherwise.

Definition at line 2042 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::is_partial_flow(), Aleph::Network_Simplex< Net >::net, and Aleph::Tree.

◆ is_zero()

template<class Net >
bool Aleph::Network_Simplex< Net >::is_zero ( Flow_Type  x) const
inlineprivate

Check if value is effectively zero.

Definition at line 1097 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::eps().

◆ ninfo() [1/2]

◆ ninfo() [2/2]

template<class Net >
const Node_Info & Aleph::Network_Simplex< Net >::ninfo ( Node p) const
inlineprivate

◆ parent()

◆ parent_arc()

◆ pivot_tree()

template<class Net >
void Aleph::Network_Simplex< Net >::pivot_tree ( Arc entering,
Arc leaving,
bool  leaving_goes_lower 
)
inlineprivate

◆ potential()

template<class Net >
Flow_Type Aleph::Network_Simplex< Net >::potential ( Node p) const
inlineprivate

◆ print_diagnostics()

◆ print_stats()

◆ reduced_cost()

template<class Net >
Flow_Type Aleph::Network_Simplex< Net >::reduced_cost ( Arc a) const
inlineprivate

Compute reduced cost of an arc.

Reduced cost = c_ij - pi_i + pi_j For optimality: reduced cost >= 0 for arcs at lower bound (flow = 0) reduced cost <= 0 for arcs at upper bound (flow = cap)

Definition at line 1109 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ninfo(), and Aleph::Simplex_Node_Info< Ftype >::potential.

Referenced by Aleph::Network_Simplex< Net >::build_spanning_tree(), Aleph::Network_Simplex< Net >::find_entering_arc(), Aleph::Network_Simplex< Net >::print_diagnostics(), and Aleph::Network_Simplex< Net >::verify_tree_reduced_costs().

◆ residual_capacity()

template<class Net >
Flow_Type Aleph::Network_Simplex< Net >::residual_capacity ( Arc a) const
inline

Get residual capacity (room to increase flow).

Parameters
[in]aArc to query.
Returns
Available capacity above current flow.

Definition at line 1818 of file tpl_netcost.H.

◆ residual_lower()

template<class Net >
Flow_Type Aleph::Network_Simplex< Net >::residual_lower ( Arc a) const
inline

Get residual lower (room to decrease flow).

Parameters
[in]aArc to query.
Returns
Available decrease to lower bound.

Definition at line 1828 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), and Aleph::Simplex_Arc_Info< Ftype >::lower_bound.

◆ run()

template<class Net >
size_t Aleph::Network_Simplex< Net >::run ( Flow_Type  unused = 0)
inline

Execute Network Simplex algorithm.

Computes minimum cost flow. If the network already has a feasible flow (e.g., from Ford-Fulkerson), it optimizes starting from there.

Parameters
[in]unusedKept for API compatibility.
Returns
Number of pivots performed.

Definition at line 1843 of file tpl_netcost.H.

References ah_domain_error_if, Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::augment_and_find_leaving(), Aleph::Network_Simplex< Net >::build_spanning_tree(), Aleph::Network_Simplex< Net >::count_non_tree_partial_arcs(), Aleph::NetworkSimplexStats::degenerate_pivots, Aleph::Network_Simplex< Net >::eps(), GraphCommon< GT, Node, Arc >::esize(), Aleph::Network_Simplex< Net >::find_entering_arc(), Aleph::Network_Simplex< Net >::force_partial_arcs_into_tree(), Aleph::NetworkSimplexStats::forced_into_tree, Aleph::Network_Simplex< Net >::init_structures(), Aleph::NetworkSimplexStats::initial_partial_arcs, Aleph::Net_Graph< NodeT, ArcT >::is_single_sink(), Aleph::Net_Graph< NodeT, ArcT >::is_single_source(), Aleph::maps(), Aleph::Network_Simplex< Net >::net, Aleph::Network_Simplex< Net >::num_pivots, Aleph::NetworkSimplexStats::phase1_pivots, Aleph::NetworkSimplexStats::phase1_time_ms, Aleph::NetworkSimplexStats::phase2_pivots, Aleph::NetworkSimplexStats::phase2_time_ms, Aleph::Network_Simplex< Net >::pivot_tree(), Aleph::NetworkSimplexStats::reset(), Aleph::Simplex_Arc_Info< Ftype >::skip, Aleph::Simplex_Arc_Info< Ftype >::state, Aleph::Network_Simplex< Net >::stats, Aleph::NetworkSimplexStats::total_pivots, Aleph::NetworkSimplexStats::total_time_ms, Aleph::Tree, Aleph::NetworkSimplexStats::tree_arcs, and GraphCommon< GT, Node, Arc >::vsize().

◆ set_lower_bound()

template<class Net >
void Aleph::Network_Simplex< Net >::set_lower_bound ( Arc a,
Flow_Type  lower_bound 
)
inline

Set lower bound for an arc.

Sets the minimum flow that must pass through an arc. Default lower bound is 0.

Parameters
[in]aArc to set lower bound for.
[in]lower_boundMinimum flow value.
Note
Must be called before run().

Definition at line 1777 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::lower_bound(), Aleph::Simplex_Arc_Info< Ftype >::lower_bound, and Aleph::Network_Simplex< Net >::support_lower_bounds.

◆ verify_tree_integrity()

template<class Net >
bool Aleph::Network_Simplex< Net >::verify_tree_integrity ( ) const
inline

Verify tree integrity - all parent_arcs should be Tree arcs.

Returns
true if tree structure is consistent.

Definition at line 2096 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::maps(), Aleph::Network_Simplex< Net >::net, Aleph::Network_Simplex< Net >::parent_arc(), Aleph::Network_Simplex< Net >::root, and Aleph::Tree.

◆ verify_tree_reduced_costs()

template<class Net >
bool Aleph::Network_Simplex< Net >::verify_tree_reduced_costs ( ) const
inline

Verify that tree arcs have zero reduced cost.

In a valid basic solution, all tree arcs must have reduced cost = 0. This is a consistency check for the potential values.

Returns
true if all tree arcs have rc=0, false otherwise.

Definition at line 2077 of file tpl_netcost.H.

References Aleph::Network_Simplex< Net >::ainfo(), Aleph::Network_Simplex< Net >::eps(), Aleph::maps(), Aleph::Network_Simplex< Net >::net, Aleph::Network_Simplex< Net >::reduced_cost(), and Aleph::Tree.

Referenced by Aleph::Network_Simplex< Net >::print_diagnostics().

Member Data Documentation

◆ arc_info

◆ arc_to_idx

◆ Inf

template<class Net >
constexpr Flow_Type Aleph::Network_Simplex< Net >::Inf = std::numeric_limits<Flow_Type>::max()
staticconstexprprivate

Definition at line 1061 of file tpl_netcost.H.

◆ lca_mark

template<class Net >
long Aleph::Network_Simplex< Net >::lca_mark = 0
private

Definition at line 1057 of file tpl_netcost.H.

Referenced by Aleph::Network_Simplex< Net >::find_lca().

◆ net

◆ node_info

◆ node_to_idx

◆ num_pivots

template<class Net >
size_t Aleph::Network_Simplex< Net >::num_pivots = 0
private

◆ root

◆ stats

◆ support_lower_bounds

template<class Net >
bool Aleph::Network_Simplex< Net >::support_lower_bounds = false
private

Definition at line 1059 of file tpl_netcost.H.

Referenced by Aleph::Network_Simplex< Net >::set_lower_bound().


The documentation for this class was generated from the following file: