44# ifndef TPL_GRAPH_UTILS_H
45# define TPL_GRAPH_UTILS_H
75 template <
class GT>
inline static bool
105 template <
class GT>
inline size_t
120 template <
class GT>
inline
191 auto arc = it.get_current_arc_ne();
196 if (
__dft (it.get_tgt_node_ne(), arc))
260 return dft(g, sn, op);
265 template <
class GT>
inline static bool
278 if (
visit !=
nullptr)
279 if ((*
visit)(g, node, arc))
285 for (
auto it = g.
get_arc_it(node); it.has_curr(); it.next_ne())
287 auto arc = it.get_current_arc_ne();
325 template <
class GT>
inline size_t
334 for (
auto it = g.
get_arc_it(start); it.has_curr(); it.next_ne())
335 q.
put(it.get_current_arc_ne());
340 if (
visit !=
nullptr)
341 if ((*
visit)(g, start,
nullptr))
356 if (
visit !=
nullptr)
365 auto curr_arc = it.get_current_arc_ne();
381 template <
class GT>
inline size_t
426 q.
put(it.get_current_arc_ne());
431 if (op (g, start,
nullptr))
447 if (op (g, curr, arc))
455 auto curr_arc = it.get_current_arc_ne();
512 return bft(g, p, op);
527 return bft(g, p, op);
553 template <
class GT>
inline
558 <<
"find_path_breadth_first(): start and end must be non-null";
568 for (
auto it = g.
get_arc_it(start); it.has_curr(); it.next_ne())
569 q.
put(it.get_current_arc_ne());
597 for (
auto it = g.
get_arc_it(tgt); it.has_curr(); it.next_ne())
599 auto a = it.get_current_arc_ne();
640 template <
class GT>
inline
644 <<
"test_connectivity() does not work on digraphs";
658 template <
class GT>
inline static
678 template <
class GT>
inline
682 <<
"test_for_cycle(): src must be non-null";
686 for (
auto it = g.
get_arc_it(src); it.has_curr(); it.next_ne())
688 auto arc = it.get_curr();
701 template <
class GT>
inline static bool
712 for (
auto it = g.
get_arc_it(curr); it.has_curr(); it.next_ne())
714 auto arc = it.get_curr();
727 template <
class GT>
inline static
737 auto arc = it.get_current_arc_ne();
769 template <
class GT>
inline
773 <<
"is_graph_acyclique() does not work for digraphs";
780 <<
"is_graph_acyclique(): start_node must be non-null";
809 template <
class GT>
inline
813 <<
"is_graph_acyclique() does not work for digraphs";
828 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
830 auto current_node = it.get_current_node_ne();
872 template <
class GT>
inline
877 <<
"test_for_path(): start_node and end_node must be non-null";
887 auto arc = it.get_current_arc_ne();
898 template <
class GT>
inline static
912 auto arc = it.get_current_arc_ne();
925 template <
class GT>
inline
929 template <
class GT>
inline
952 template <
class GT>
inline
963 auto curr = it.get_current_node_ne();
996 template <
class GT>
inline
1016 auto arc = it.get_current_arc_ne();
1021 auto g_tgt = it.get_tgt_node_ne();
1038 template <
class GT>
inline static
1064 template <
class GT>
inline
1079 auto arc = it.get_current_arc_ne();
1095 template <
class GT>
inline
1102 template <
class GT>
inline static
1124 auto arc = it.get_current_arc_ne();
1157 template <
class GT>
inline
1171 for (
auto it = g.
get_arc_it(
gp); it.has_curr(); it.next_ne())
1172 q.
put(it.get_curr());
1206 auto current_arc = it.get_current_arc_ne();
1285 template <
class GT>
inline static
1293 template <
class GT>
inline static
1300 template <
class GT>
inline static
1337 <<
"compute_cut_nodes() does not work on digraphs";
1343 <<
"compute_cut_nodes(): start must be non-null";
1347 std::vector<Node*>
nodes;
1349 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
1350 nodes.push_back(it.get_curr());
1354 for (
size_t i = 0; i <
nodes.size(); ++i)
1364 std::vector<Node*> &
nodes;
1368 for (
auto p :
nodes)
1383 auto tgt = it.get_tgt_node_ne();
1387 auto arc = it.get_current_arc_ne();
1414 template <
class GT>
inline static
1423 for (
auto it = g.
get_arc_it(p); it.has_curr(); it.next_ne())
1425 auto arc = it.get_current_arc_ne();
1429 auto tgt = it.get_tgt_node_ne();
1467 template <
class GT>
inline static
1474 template <
class GT>
inline static
1481 template <
class GT>
inline static
1488 template <
class GT>
inline static
1495 template <
class GT>
inline static
1502 template <
class GT>
inline static
1509 template <
class GT>
inline static
1516 template <
class GT>
inline static
1523 template <
class GT>
inline static
1530 template <
class GT>
inline static
1540 for (
auto it = g.
get_arc_it(p); it.has_curr(); it.next_ne())
1542 auto arc = it.get_current_arc_ne();
1546 auto tgt = it.get_tgt_node_ne();
1557 template <
class GT>
inline static
1564 for (
auto it = g.
get_arc_it(p); it.has_curr(); it.next_ne())
1566 auto arc = it.get_current_arc_ne();
1570 auto tgt_node = it.get_tgt_node_ne();
1626 template <
class GT>
inline long
1640 template <
class GT>
inline static
1651 auto garc = it.get_current_arc_ne();
1657 auto gtgt = it.get_tgt_node_ne();
1705 typename GT::Node * first =
nullptr;
1706 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
1709 first = it.get_current_node_ne();
1714 <<
"Color does not exist in the graph";
1748 std::tuple<GT, DynList<typename GT::Arc*>>
1756 auto gp = it.get_curr();
1766 for (
auto it = g.
get_arc_it(); it.has_curr(); it.next_ne())
1768 auto garc = it.get_current_arc_ne();
1781 assert(src !=
nullptr and tgt !=
nullptr);
1783 auto arc =
cut_graph.insert_arc(src, tgt,
garc->get_info());
1800 template <
class GT,
class Distance>
1835 <<
"invert_digraph() requires a digraph (or a graph temporarily treated as a digraph)";
1842 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
1844 auto gp = it.get_curr();
1845 auto ip =
gi.insert_node(
gp->get_info());
1849 for (
auto it = g.
get_arc_it(); it.has_curr(); it.next_ne())
1851 auto arc = it.get_curr();
1881 template <
class GT,
class SA = Dft_Show_Arc<GT>>
1901 <<
"Invert_Digraph requires a digraph (or a graph temporarily treated as a digraph)";
1908 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
1910 auto gp = it.get_curr();
1911 auto ip =
gi.insert_node(
gp->get_info());
1917 auto arc = it.get_curr();
1971 std::numeric_limits<typename Dft_Dist<GT>::Distance_Type>
::max();
1989 template <
class GT,
class SA = Dft_Show_Arc<GT>>
1995 assert(src !=
nullptr and tgt !=
nullptr);
1999 std::swap(tgt, src);
2004 if (it.get_tgt_node_ne() != tgt)
2007 auto arc = it.get_current_arc_ne();
2020 template <
class GT,
class Distance = Dft_Dist<GT>>
2027 <<
"get_min_path(): s and end must be non-null";
2029 Distance_Type dist{};
2047 <<
"get_min_path(): broken cookie chain (nullptr)";
2052 <<
"get_min_path(): no arc connecting nodes in path";
2055 dist += distance(arc);
2063 auto & [node, arc] = it.get_curr();
2111 sum +=
dist(it.get_current_arc_ne());
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_unless(C)
Throws std::domain_error if condition does NOT hold.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
WeightedDigraph::Node Node
Stateful breadth-first traversal functor.
Breadth_First_Traversal(SA __sa=SA())
Construct a traversal functor using the arc filter __sa.
size_t operator()(const GT &g, Operation op)
Traverse starting from the first node of the graph.
size_t bft(const GT &g, typename GT::Node *start, Operation &op)
RAII guard that clears graph cookies on destruction.
~Cookie_Guard()
Destructor - clears cookies if guard is still active.
Stateful depth-first traversal functor.
bool __dft(typename GT::Node *node, typename GT::Arc *arc=nullptr)
Depth_First_Traversal(SA __sa=SA())
Construct a traversal functor using the arc filter __sa.
size_t operator()(const GT &g, Operation op=Operation())
Traverse starting from the first node of the graph.
size_t dft(const GT &g, typename GT::Node *start_node, Operation &__op)
Default distance accessor for arc weights.
static const Distance_Type Max_Distance
Distance_Type & operator()(typename GT::Arc *a) const
GT::Arc_Type Distance_Type
static const Distance_Type Zero_Distance
static void set_zero(typename GT::Arc *a)
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.
void empty() noexcept
Empty the queue.
bool is_empty() const noexcept
Return true if this is empty.
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
Insert a new item by copy.
T & append(const T &item)
Append a new item by copy.
T & get_last() const
Return the last item of the list.
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.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Functor for computing the transposed digraph, filtering arcs.
Invert_Digraph(SA __sa)
Construct a functor using the arc filter __sa.
GT operator()(const GT &g) const
Compute the transposed graph.
Node * get_first_node() const
Return any node in the graph.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Graph_Node< int > Node
The graph type.
Graph_Arc< int > Arc
The node class type.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
typename Arc::Arc_Type Arc_Type
The type of data stored in the arc.
void insert(Arc *arc)
Insert an arc as the first of a path.
void empty()
Clean the path: all the nodes and arc are removed.
void init(Node *start_node)
Set the first node of a path.
void append(Arc *arc)
Append an arc to the path.
const GT & get_graph() const noexcept
Get a constant reference to the graph.
Compute the total cost (sum of arc weights) of a graph.
Distance::Distance_Type total_cost(GT &g)
Compute the total cost.
Distance::Distance_Type sum
Distance::Distance_Type operator()(GT &g)
Total_Cost(Distance __dist=Distance(), SA __sa=SA())
Distance::Distance_Type value() const noexcept
Return the accumulated value (after using operator()(Arc*)).
void reset() noexcept
Reset the internal accumulator used by operator()(Arc*).
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
size_t num_arcs
data associated to the node. Access it with get_info()
void reset_bit_nodes(int bit) const noexcept
Reset bit to zero for all the nodes of graph.
void reset_arcs() const
Reset all the arcs of graph (the control bits, the state, the counter and the cookie)
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Node * get_node() const
Return any node in the graph.
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
void set_bit(Node *node, int bit, int value) const noexcept
Set the control bit of node to value
bool is_digraph() const noexcept
Return true if the graph this is directed.
static void map_arcs(A1 *p, A2 *q) noexcept
Map the arcs through their cookies.
void reset_counter_nodes() const noexcept
Reset all the counters to zero for all the nodes of graph.
void reset_bit_arcs(int bit) const noexcept
Reset bit to zero for all the arcs of graph.
constexpr size_t get_num_arcs() const noexcept
void reset_counter_arcs() const noexcept
Reset all the counters to zero for all the arcs of graph.
void reset_nodes() const
Reset all the nodes of graph (the control bits, the state, the counter and the cookie)
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.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
List_Graph< Graph_Node< int >, Graph_Arc< int > > GT
__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)
DynArray< Graph::Node * > nodes
DynArray< Graph::Arc * > arcs
size_t depth_first_traversal(const GT &g, typename GT::Node *start_node, bool(*visit)(const GT &g, typename GT::Node *, typename GT::Arc *))
Depth-first traversal starting from a given node.
GT build_spanning_tree(const DynArray< typename GT::Arc * > &arcs)
Build a graph from a list of arcs (typically a spanning tree).
#define ARC_COOKIE(p)
Return the arc cookie
bool has_cycle(const GT &g)
Return true if an undirected graph has at least one cycle.
#define NODE_COUNTER(p)
Get the counter of a node.
DynList< GT > inconnected_components(const GT &g)
Forward declaration for inconnected_components().
bool test_for_cycle(const GT &g, typename GT::Node *src)
Search for a cycle reachable from a given node.
GT find_breadth_first_spanning_tree(GT &g, typename GT::Node *gp)
Build a breadth-first spanning tree (mapped to the original graph).
#define ARC_COUNTER(p)
Return the counter of arc p.
#define IS_NODE_VISITED(p, bit)
Determine whether the control bit is set or not to one.
GT invert_digraph(const GT &g)
Compute the transpose (arc-reversed) digraph.
DynList< typename GT::Node * > compute_cut_nodes(const GT &g, typename GT::Node *start)
Compute articulation points (cut vertices) of an undirected graph.
bool test_connectivity(const GT &g)
Connectivity test for undirected graphs.
#define ARC_BITS(p)
Return the control bits of arc p.
#define NODE_COOKIE(p)
Return the node cookie
long paint_subgraphs(const GT &g, const DynList< typename GT::Node * > &cut_node_list)
Paint connected blocks around articulation points.
Path< GT > find_path_breadth_first(const GT &g, typename GT::Node *start, typename GT::Node *end)
Breadth-first search of a (shortest-by-edges) path between two nodes.
bool test_for_path(const GT &g, typename GT::Node *start_node, typename GT::Node *end_node)
Return true if there is a path between two nodes.
size_t breadth_first_traversal(const GT &g, typename GT::Node *start, bool(*visit)(const GT &, typename GT::Node *, typename GT::Arc *))
Breadth-first traversal starting from a given node.
void build_subgraph(const GT &g, GT &sg, typename GT::Node *g_src, size_t &node_count)
Forward declaration for build_subgraph().
#define IS_ARC_VISITED(p, bit)
Determine whether the bit field is or not set to one.
GT find_depth_first_spanning_tree(const GT &g, typename GT::Node *gnode)
Build a depth-first spanning tree (mapped to the original graph).
bool is_graph_acyclique(const GT &g, typename GT::Node *start_node)
Return true if an undirected graph is acyclic.
std::tuple< GT, DynList< typename GT::Arc * > > map_cut_graph(const GT &g, const DynList< typename GT::Node * > &cut_node_list)
Extract the cut graph and cross-arc list.
#define NODE_BITS(p)
Get the control bits of a node.
GT map_subgraph(const GT &g, const long color)
Extract a mapped subgraph containing a given color.
Main namespace for Aleph-w library functions.
static bool __test_cycle(const GT &g, typename GT::Node *, typename GT::Node *)
Internal helper used by test_for_cycle().
const long Cross_Arc
Special marker for arcs connecting a cut node to a non-cut block.
static void paint_arc(typename GT::Arc *a, const long &color)
Set the arc color (stored in ARC_COUNTER).
GT::Arc * search_spanning_tree_arc(const GT &g, typename GT::Node *src, typename GT::Node *tgt, SA sa=SA()) noexcept
Helper to find the spanning tree arc between two nodes in a multigraph.
static long & low(typename GT::Node *p)
Internal helper: low-link value stored directly in NODE_COOKIE(p).
static bool is_node_painted(typename GT::Node *p)
Return true if the node has a positive color.
static const long & get_color(typename GT::Node *p)
Return the node color (stored in NODE_COUNTER).
static void __paint_subgraph(const GT &g, typename GT::Node *p, long current_color)
Internal DFS that paints a non-cut block with current_color.
static bool __test_for_path(const GT &g, typename GT::Node *curr_node, typename GT::Node *end_node)
Internal recursive DFS used by test_for_path().
static void paint_node(typename GT::Node *p, const long &color)
Set the node color (stored in NODE_COUNTER).
static bool is_a_cross_arc(typename GT::Arc *a)
Return true if the arc is marked as a cross-arc by paint_subgraphs().
Distance::Distance_Type get_min_path(typename GT::Node *s, typename GT::Node *end, Path< GT > &path)
static bool is_arc_painted(typename GT::Arc *arc)
Return true if the arc has a positive color.
static long & df(typename GT::Node *p)
Internal helper: DFS discovery time stored in NODE_COUNTER(p).
static bool is_an_cut_arc(typename GT::Arc *a)
Return true if the arc is marked as a cut-arc (between cut nodes).
static void __paint_from_cut_node(const GT &g, typename GT::Node *p, long ¤t_color)
Internal step that paints all blocks adjacent to a cut node.
static bool __is_graph_acyclique(const GT &g, typename GT::Node *curr_node)
Internal DFS used by is_graph_acyclique().
static void __map_subgraph(const GT &g, GT &sg, typename GT::Node *gsrc, const long color)
Internal recursive step used by map_subgraph().
static void __compute_cut_nodes(const GT &g, DynList< typename GT::Node * > &list, typename GT::Node *p, typename GT::Arc *a, long &curr_df)
Internal DFS step used by compute_cut_nodes().
static bool __depth_first_traversal(const GT &g, typename GT::Node *node, typename GT::Arc *arc, bool(*visit)(const GT &g, typename GT::Node *, typename GT::Arc *), size_t &count)
Internal recursive DFS used by depth_first_traversal().
static bool is_a_cut_node(typename GT::Node *p)
Return true if the node is marked as an articulation point.
static bool __find_depth_first_spanning_tree(const GT &g, typename GT::Node *gnode, typename GT::Arc *garc, GT &tree, typename GT::Node *tnode)
Internal recursive DFS used by find_depth_first_spanning_tree().
static long & color(typename GT::Node *p)
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.
Filtered iterator on all the arcs of a graph.
Default visit operation for traversals (never stops).
bool operator()(const GT &, typename GT::Node *, typename GT::Arc *)
Always continues the traversal (never stops early).
Default filter for filtered iterators on arcs.
Comparison functor for arc weights/distances.
Distance_Compare(Distance __dist=Distance())
bool operator()(typename GT::Arc *a1, typename GT::Arc *a2) const
Arc of graph implemented with double-linked adjacency lists.
Filtered iterator of adjacent arcs of a node.
Array-based graph implementation.
Dynamic queue implementation based on linked lists.