""" graph_properties(graph::DAG) Return the graph's properties, a named tuple with fields `.data`, `.compute_effort`, `.compute_intensity`, `.nodes` (number of nodes) and `.edges` (number of edges). """ function graph_properties(graph::DAG) # make sure the graph is fully generated apply_all!(graph) d = 0 ce = 0 ed = 0 for node in graph.nodes d += data(node.task) * length(node.parents) ce += compute_effort(node.task) ed += length(node.parents) end ci = ce / d result = ( data = d, compute_effort = ce, compute_intensity = ci, nodes = length(graph.nodes), edges = ed, ) return result end """ get_exit_node(graph::DAG) Return the graph's exit node. This assumes the graph only has a single exit node. If the graph has multiple exit nodes, the one encountered first will be returned. """ function get_exit_node(graph::DAG) for node in graph.nodes if (is_exit_node(node)) return node end end @assert false "The given graph has no exit node! It is either empty or not acyclic!" end