156template <AlephGraph
GT,
191 if constexpr (std::is_integral_v<Distance_Type>)
195 <<
"Integer overflow in distance addition: " << a <<
" + " << b;
199 <<
"Integer underflow in distance addition: " << a <<
" + " << b;
221 typename GT::Node_Iterator it(
g_);
222 for (
int i = 0; it.has_curr(); ++i, it.next_ne())
224 auto p = it.get_curr();
252 typename GT::Node_Iterator it(
g_);
253 for (
size_t i = 0; it.has_curr(); ++i, it.next())
257 auto p = it.get_curr();
262 ptr->idx =
static_cast<int>(i);
278 template <
class Info_Type>
281 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next())
283 auto p = it.get_curr();
314 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next_ne())
316 auto node = it.get_curr();
329 if (
auto arc =
ait.get_curr();
384 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next_ne())
400 return s_ !=
nullptr;
432 for (
size_t i = 0; i < n - 1; ++i)
435 auto arc = it.get_curr();
441 auto tgt = it.get_tgt_node_ne();
447 const auto &index =
idx(tgt);
477 auto arc = it.get_curr();
489 const auto &index =
idx(tgt);
501 for (
size_t i = 0; i < n; ++i)
524 bool negative_cycle =
false;
527 auto arc = it.get_curr();
539 negative_cycle =
true;
540 const auto &index =
idx(tgt);
545 return negative_cycle;
553 auto arc = it.get_curr();
576 for (
size_t i = 0; i < n; ++i)
610 if (
not negative_cycle)
615 return negative_cycle;
668 if (
not negative_cycle)
673 return negative_cycle;
687 bool released =
false;
703 if (
dummy !=
nullptr)
725 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next_ne())
727 auto p = it.get_curr();
740 template <
class Info_Type>
768 return negative_cycle;
790 bool released =
false;
826 for (
typename GT::Node_Iterator it(aux); it.has_curr(); it.next_ne())
828 auto p = it.get_curr();
836 for (
typename GT::Node_Iterator it(aux); it.has_curr(); it.next_ne())
843 ret.append_directed(
static_cast<Node *
>(table.
find(it.get_current_node_ne())));
870 if (
not negative_cycle)
879 "Serious inconsistency. Bellman-Ford algorithm has detected\n"
880 "a negative cycle, but Tarjan algorithm executed on partial\n"
881 "graph has not found such cycle\n\n"
882 "Be very careful, this is provably a bug");
984 return std::make_tuple(std::forward<
Path<GT>>(
ret), i);
998 "Serious inconsistency. Bellman-Ford algorithm has detected\n"
999 "a negative cycle, but Tarjan algorithm executed on partial\n"
1000 "graph has not found such cycle\n\n"
1001 "Be very careful, this provably is a bug");
1005 return std::make_tuple(std::forward<
Path<GT>>(
ret), i);
1032 if (src == sentinel)
1048 "Serious inconsistency. Bellman-Ford algorithm has detected\n"
1049 "a negative cycle, but Tarjan algorithm executed on partial\n"
1050 "graph has not found such cycle\n\n"
1051 "Be very careful, this provably is a bug");
1154 if (
auto arc = it.get_curr();
1181 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next_ne())
1183 auto gp = it.get_curr();
1188 for (
typename GT::Node_Iterator it(
g_); it.has_curr(); it.next_ne())
1190 auto gtgt = it.get_curr();
1192 if (
gsrc ==
nullptr)
1199 auto a =
ait.get_curr();
1278 if (
dummy !=
nullptr)
1297 if (src == sentinel)
1312 if (
not negative_cycle)
1313 for (
auto it =
g_.
get_node_it(); it.has_curr(); it.next_ne())
1315 auto p = it.get_curr();
1351template <AlephGraph
GT,
1398 SA &&sa = SA())
const
Tarjan's algorithm for strongly connected components.
Exception handling system with formatted messages for Aleph-w.
#define ah_logic_error_unless(C)
Throws std::logic_error if condition does NOT hold.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
C++20 concepts for the protocol shared by graph algorithms.
#define WARNING(...)
Print a warning message (no-op when MESSAGES is not defined).
RAII guard for exception-safe resource cleanup.
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
Bellman-Ford algorithm for shortest paths with negative weights.
Distance_Type get_distance(typename GT::Node *node)
Get the accumulated distance to a node from a previously painted tree.
DynArray< Arc * > extract_min_spanning_tree()
Extract the shortest paths tree in a compressed form.
void init_with_indexes(Node *start)
Initialize node cookies with predecessor tracking for path reconstruction.
bool has_computation() const noexcept
Check if a shortest-path tree has been computed or painted.
void uninit()
Release the memory associated with the node cookies.
void relax_arcs() noexcept
Relax all arcs n-1 times (standard Bellman-Ford).
void init_simple(Node *start)
Initialize node cookies for simple mode (without predecessor tracking).
bool faster_paint_spanning_tree(Node *start)
Faster shortest paths tree painting from a start node.
void remove_dummy_node(Node *p)
Remove a dummy node and clean up its cookie.
void link_cookies_and_free(typename GT::Node *start) noexcept
Free node cookies and set up predecessor pointers for path reconstruction.
DynMapTree< Node *, Distance_Type > compute_nodes_weights()
Returns a mapping with the shortest distances to each node obtained after executing the Bellman-Ford ...
bool test_negative_cycle(typename GT::Node *s, Path< GT > &cycle)
Test for negative cycle and return it if found.
bool last_relax_and_prepare_check_negative_cycle() noexcept
Perform one more relaxation pass and check for negative cycle.
static GT::Node * get_from_queue(DynListQueue< typename GT::Node * > &q)
Remove a node from the queue and clear its in-queue flag.
bool paint_spanning_tree(Node *start)
Paint the shortest paths tree from a start node.
DynArray< typename GT::Arc * > arcs_
Path< GT > search_negative_cycle(Node *start)
Searches a negative cycle using the faster version of Bellman-Ford algorithm (SPFA variant).
Path< GT > search_negative_cycle()
Path< GT > test_negative_cycle()
Searches and returns a negative cycle (if it exists).
void paint_tree() noexcept
Paint the spanning tree nodes and arcs with the Spanning_Tree bit.
std::tuple< Path< GT >, size_t > search_negative_cycle(double it_factor, const size_t step)
void clear() noexcept
Clear the painted state and reset internal data structures.
bool is_painted() const noexcept
Check if a shortest-path tree has been painted.
bool has_negative_cycle()
Test if a negative cycle exists anywhere in the graph.
bool has_negative_cycle(Node *start)
Test if a negative cycle exists starting from a specific node.
void relax_arcs(typename GT::Node *src, DynListQueue< typename GT::Node * > &q)
Relax outgoing arcs from a source node (SPFA variant).
static void put_in_queue(DynListQueue< typename GT::Node * > &q, typename GT::Node *p)
Insert a node into the queue if not already present (SPFA optimization).
static Distance_Type & accum(Node *p) noexcept
Node * create_dummy_node()
Create a dummy node connected to all nodes with zero-weight edges.
bool check_painted_arcs() noexcept
Check that painted arcs form a valid spanning tree structure.
Distance_Type get_min_path(typename GT::Node *end, Path< GT > &path)
Extract the shortest path to a node from a previously painted tree.
bool test_negative_cycle(Path< GT > &cycle)
Test for negative cycle anywhere in the graph.
static int & idx(Node *p) noexcept
Bellman_Ford(GT &__g, Distance d=Distance(), SA __sa=SA())
Construct a Bellman-Ford executor.
const GT & get_graph() const noexcept
Get reference to the graph.
Node * get_start_node() const noexcept
Get the start node of the last computation.
Path< GT > test_negative_cycle(Node *start)
Search a negative cycle on all possible paths starting from start node.
std::tuple< Path< GT >, size_t > search_negative_cycle(Node *start, double it_factor, const size_t step)
Searches a negative cycle using the faster version of Bellman-Ford algorithm and iteratively searchin...
Distance_Type checked_add(const Distance_Type &a, const Distance_Type &b) const
Path< GT > search_negative_cycle_on_partial_graph()
Build spanning tree from arcs and search for cycle using Tarjan's algorithm.
void build_tree(GT &tree, bool with_map=true)
Extract from the graph a previously painted shortest paths tree.
Distance::Distance_Type Distance_Type
bool last_relax_and_test_negative_cycle() noexcept
Perform one more relaxation pass to detect (but not prepare) negative cycle.
RAII guard that saves and restores graph cookies.
Default distance accessor for arc weights.
bool has_curr() const noexcept
Return true the iterator has an current arc.
void cut(const size_t new_dim=0)
Cut the array to a new dimension; that is, it reduces the dimension of array and frees the remaining ...
T & touch(const size_t i)
Touch the entry i.
void reserve(const size_t l, const size_t r)
Allocate a range of entries.
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
T get()
Remove the oldest item of the queue.
bool is_empty() const noexcept
Return true if this is empty.
Generic key-value map implemented on top of a binary search tree.
Pair * search(const Key &key) const noexcept
Collect all keys.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair.
Data & find(const Key &key)
Find the value associated with key.
RAII guard for graph algorithm initialization.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
virtual void remove_node(Node *node) noexcept
Remove a node from the graph and free its memory.
typename Node::Node_Type Node_Type
The arc class type.
virtual void remove_arc(Arc *arc) noexcept
Remove an arc from the graph and free it.
Graph_Node< Node_Info > Node
The graph type.
Graph_Arc< Arc_Info > Arc
The node class type.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Filtered iterator for outcoming arcs of a node.
Iterator on nodes and arcs of a path.
bool has_current_node() const noexcept
Return true if the iterator has a current node.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
void reset_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
void reset_bit(Node *node, int bit) const noexcept
Reset the bit of node (to zero)
constexpr size_t vsize() const noexcept
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
RAII guards for graph node/arc cookies.
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_max_function > > max(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
#define IS_NODE_VISITED(p, bit)
Determine whether the control bit is set or not to one.
#define ARC_BITS(p)
Return the control bits of arc p.
#define NODE_COOKIE(p)
Return the node cookie
void clear_graph(GT &g) noexcept
Clean a graph: all its nodes and arcs are removed and freed.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
#define IS_ARC_VISITED(p, bit)
Determine whether the bit field is or not set to one.
#define NODE_BITS(p)
Get the control bits of a node.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Filtered iterator on all the arcs of a graph.
Detects if a negative cycle exists and eventually computes it.
Path< GT > operator()(GT &g, typename GT::Node *s, Distance &d, SA &sa) const
Search for a negative cycle starting from a specific node.
bool operator()(GT &g, typename GT::Node *s, Path< GT > &path, Distance &&d=Distance(), SA &&sa=SA()) const
Path< GT > operator()(GT &g, Distance &&d=Distance(), SA &&sa=SA()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool operator()(GT &g, Path< GT > &path, Distance &d, SA &sa) const
Invokes the detection and calculation of a negative cycle.
bool operator()(GT &g, typename GT::Node *s, Path< GT > &path, Distance &d, SA &sa) const
Invokes the detection and calculation of a negative cycle.
Path< GT > operator()(GT &g, Distance &d, SA &sa) const
Search for a negative cycle in the entire graph.
Path< GT > operator()(GT &g, typename GT::Node *s, Distance &&d=Distance(), SA &&sa=SA()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool operator()(GT &g, Path< GT > &path, Distance &&d=Distance(), SA &&sa=SA()) const
Default filter for filtered iterators on arcs.
Filtered iterator of adjacent arcs of a node.
static void set_zero(Arc *a)
TestDigraph::Arc * add_arc(TestDigraph &g, TestDigraph::Node *src, TestDigraph::Node *tgt, int value=0)
Dynamic queue implementation based on linked lists.
Dynamic set implementations based on balanced binary search trees.
Utility algorithms and operations for graphs.