179 mutable size_t n = 0;
288 auto q =
blk.insert_node(p->get_info());
469 path_ptr->append_directed(table.
find(i.get_current_node_ne()));
523 auto q =
blk.insert_node();
531 if (
blk.get_num_nodes() == 1)
535 for (
typename GT::Node_Iterator j(
blk); j.has_curr(); j.next_ne())
537 auto bsrc = j.get_curr();
543 auto ga =
k.get_curr();
549 auto ta =
blk.insert_arc(
bsrc, ptr->second);
631 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
640 GT &
blk = i.get_curr();
641 for (
typename GT::Node_Iterator j(
blk); j.has_curr(); j.next_ne())
643 auto bsrc = j.get_curr();
649 auto ga =
k.get_curr();
702 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
754 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
812 GT & curr = it.get_curr();
819 arc_list.
append(it.get_curr());
837 it.has_curr(); it.next_ne())
841 auto &
blk = it.get_curr();
861 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
903 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
929 <<
"compute_cycle: source node cannot be null";
956 for (
typename GT::Node_Iterator it(g);
df_count <
n; it.next_ne())
1047 return tarjan.compute_cycle(g, path);
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Determines if a digraph contains a cycle and constructs it.
bool operator()(const GT &g, Path< GT > &path) const
Invokes the computation of a cycle in a digraph.
Compute_Cycle_In_Digraph(SA __sa=SA())
Constructs a cycle computation instance with an arc filter.
bool has_curr() const noexcept
Return true if the iterator has current item.
Dynamic doubly linked list with O(1) size and bidirectional access.
T & append(const T &item)
Append a copied item at the end of the list.
Dynamic stack of elements of generic type T based on a singly linked list.
bool is_empty() const noexcept
Check if the stack is empty.
T pop()
Remove and return the top item of the stack.
T & push(const T &data)
Push an item by copy onto the top of the stack.
void empty() noexcept
Remove all elements from the stack.
Iterator on the items of list.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Append a new item by copy.
Dynamic map implemented with an AVL 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.
bool has_curr() const noexcept
Return true if iterator has current item.
constexpr bool is_empty() const noexcept
Return true if list is empty.
size_t size() const noexcept
Count the number of elements of the list.
Arc * get_first_arc(Node *node) const
Return any arc adjacent to a node.
void swap(List_Graph &g) noexcept
Swap in constant time this with g
Filtered iterator for outcoming arcs of a node.
Iterator on nodes and arcs of a path.
void empty()
Clean the path: all the nodes and arc are removed.
void set_graph(const GT &__g, Node *start_node=nullptr)
Set the graph of the path.
Computes strongly connected components (SCCs) in a directed graph using Tarjan's algorithm.
void init_tarjan(const GT &g)
Initialize internal state for a Tarjan traversal.
bool has_computation() const noexcept
Check if a computation has been performed.
SA & get_filter() noexcept
Returns the arc filter used by this instance.
DynList< DynList< typename GT::Node * > > connected_components(const GT &g)
Tarjan_Connected_Components(const Tarjan_Connected_Components &)=delete
Tarjan instances should not be copied (they hold internal traversal state)
void init_node_and_push_in_stack(typename GT::Node *p)
Initialize a node and push it onto the traversal stack.
bool is_node_in_stack(typename GT::Node *p) const noexcept
Check if a node is currently on the traversal stack.
bool build_cycle(typename GT::Node *v)
Recursive DFS to find and construct a cycle starting from v.
Tarjan_Connected_Components & operator=(const Tarjan_Connected_Components &)=delete
void connected_components(const GT &g, DynList< DynList< typename GT::Node * > > &blks)
Computes the strongly connected components of a digraph.
bool test_connectivity(const GT &g)
Tests whether the digraph is strongly connected.
bool has_cycle(typename GT::Node *v)
Recursive DFS to detect if a cycle exists starting from v.
void connected_components(const GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc * > &arc_list)
Computes the strongly connected components of a digraph.
bool compute_cycle(const GT &g, typename GT::Node *src, Path< GT > &path)
Finds and constructs a cycle starting from a specific node, if one exists.
void scc_by_lists(typename GT::Node *v, DynList< DynList< typename GT::Node * > > &blks)
Recursive DFS to find SCCs and collect nodes into lists.
bool compute_cycle(const GT &g, Path< GT > &path)
Finds and constructs a cycle in the digraph, if one exists.
void build_path(const GT &block, DynMapAvlTree< typename GT::Node *, typename GT::Node * > &table)
Build a cycle path from a strongly connected block.
GT * get_graph() const noexcept
Get the graph of the last computation.
const SA & get_filter() const noexcept
Returns the arc filter used by this instance (const version).
bool has_cycle(const GT &g)
Determines whether the digraph contains at least one cycle.
Tarjan_Connected_Components(Tarjan_Connected_Components &&)=default
Move is allowed.
bool is_dag(const GT &g)
Determines whether the directed graph is acyclic (a DAG).
Tarjan_Connected_Components(SA __sa=SA()) noexcept
Constructs a Tarjan algorithm instance for computing strongly connected components.
void scc_by_len(typename GT::Node *v, DynList< size_t > &sizes)
Recursive DFS to find SCCs and count their sizes.
GT::Node * pop_from_stack()
Pop a node from the traversal stack.
DynListStack< typename GT::Node * > stack
void connected_components(const GT &g, DynList< size_t > &blks)
Computes the strongly connected components of a digraph.
void operator()(const GT &g, DynList< GT > &blk_list, DynList< typename GT::Arc * > &arc_list)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void scc_by_blocks(typename GT::Node *v, DynList< GT > &blk_list)
Recursive DFS to find SCCs and build mapped subgraphs.
Tarjan_Connected_Components & operator=(Tarjan_Connected_Components &&)=default
bool is_connected(typename GT::Node *v)
Recursive DFS to test if the graph is strongly connected.
size_t num_connected_components(const GT &g)
Returns the number of strongly connected components in the graph.
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.
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.
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
#define NODE_COUNTER(p)
Get the counter of a node.
#define IS_NODE_VISITED(p, bit)
Determine whether the control bit is set or not to one.
#define NODE_COOKIE(p)
Return the node cookie
#define NODE_BITS(p)
Get the control bits of a node.
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Default filter for filtered iterators on arcs.
Functor to initialize node metadata for Tarjan traversal.
void operator()(const GT &g, typename GT::Node *p) const noexcept
Dynamic stack implementation based on linked lists.
Dynamic set implementations based on balanced binary search trees.
Path finding algorithms in graphs.
Utility algorithms and operations for graphs.