dfs Class Reference

Depth-First-Search (DFS) algorithm. More...

Inheritance diagram for dfs:

Inheritance graph
[legend]
Collaboration diagram for dfs:

Collaboration graph
[legend]

List of all members.

Public Types

typedef list< edge >
::const_iterator 
tree_edges_iterator
 Iterator for the tree edges of the DFS-tree.
typedef list< node >
::const_iterator 
dfs_iterator
 Iterator for the (reached) nodes in DFS-order.
typedef list< edge >
::const_iterator 
non_tree_edges_iterator
 Iterator for the non-tree-edges.
typedef list
< dfs_iterator >
::const_iterator 
roots_iterator
 Iterator for the roots of the DFS-forest.

Public Member Functions

 dfs ()
 Constructor.
virtual ~dfs ()
 Destructor.
int run (graph &G)
 Applies algorithm to graph g.
virtual int check (graph &G)
 Checks whether the preconditions for DFS are satisfied.
virtual void reset ()
 Resets algorithm.
void start_node (const node &n)
 Sets start-node for DFS.
node start_node () const
 Returns start-node for DFS.
void scan_whole_graph (bool set)
 Enables or disables scanning of the whole graph.
bool scan_whole_graph () const
 Returns true iff the whole graph will be scanned.
void calc_comp_num (bool set)
 Enables or Disables the calculation of the completion number.
bool calc_comp_num () const
 Returns true iff completion-numbers will be calculated.
void store_preds (bool set)
 Enables or disables the storing of predecessors.
bool store_preds () const
 Returns true iff the storing of predecessors is enabled.
void store_non_tree_edges (bool set)
 Enables the storing of back-edges.
bool store_non_tree_edges () const
 Returns true iff the storing of non-tree-edges is enabled.
bool reached (const node &n) const
 Checks whether node n was reached in last DFS.
int dfs_num (const node &n) const
 DFS-Number of n.
int operator[] (const node &n) const
 DFS-Number of n.
int comp_num (const node &n) const
 Completion-number of node n, if enabled in last run.
node father (const node &n) const
 Returns father of node n in DFS-forest.
tree_edges_iterator tree_edges_begin () const
 Iterate through all edges picked in last DFS.
tree_edges_iterator tree_edges_end () const
 End-iterator for iteration through all edges picked in last DFS.
dfs_iterator begin () const
 Iterate through all (reached) nodes in DFS-order.
dfs_iterator end () const
 End-Iterator for iteration through all (reached) nodes in DFS-order.
non_tree_edges_iterator non_tree_edges_begin () const
 Iterate through all non-tree-edges (if enabled).
non_tree_edges_iterator non_tree_edges_end () const
 End-iterator for iteration through all non-tree-edges (if enabled).
roots_iterator roots_begin () const
 Iterator pointing towards the first root in the DFS-forest.
roots_iterator roots_end () const
 Iterator pointing to the end of all roots.
int number_of_reached_nodes () const
 Number of nodes reached in last DFS.
virtual void init_handler (graph &G)
 Handler called before the start of DFS.
virtual void end_handler (graph &G)
 Handler called at the end of DFS.
virtual void entry_handler (graph &G, node &n, node &f)
 Handler called when touching node n.
virtual void leave_handler (graph &G, node &n, node &f)
 Handler called after all the adjacent edges of n have been examined.
virtual void before_recursive_call_handler (graph &G, edge &e, node &n)
 Handler called when a unused node n connected to the actual node by e is found.
virtual void after_recursive_call_handler (graph &G, edge &e, node &n)
 Handler called after the algorithm returns from the subtree starting at n connected to the actual node by e.
virtual void old_adj_node_handler (graph &G, edge &e, node &n)
 Handler called when a already marked node n connected to the actual node by e is found during the search of all adjacent edges of the actual node.
virtual void new_start_handler (graph &G, node &n)
 Called when DFS is started with start-node n.


Detailed Description

Depth-First-Search (DFS) algorithm.

Date
Revision

Encapsulates the DFS algoritm together with all the data produced by a run of DFS. Since there exits so much different things which one might want to calculate during a DFS this class provides basically two different customization features. First it is possible to take influence on the behaviour of this algortihm by changing some of the following options:

But the trouble with most DFS-algorithm is that one always wants to add a little bit of code somewhere in the algorithm. And then there are only two ways to get this done. The more efficient one (in terms of runtime) is to implement the DFS anew and add the new code where necessary. The other way (which is more efficient in terms of code-writing) is to take the algorithm as provided and run through the list of nodes it returns (resulting in an extra factor of 2).

Our DFS-algoritm class provides a new method to add small pieces of code to the algorithm: Handler. These are virtual functions called at well-defined, important states of the algorithm (e.g. before a new recursive call). So the only thing to do is to derive your extended DFS from this class and to override the handlers where needed. In detail there are the following handler supported (have a look at the source code for details):

Please note: We do not claim that this set of handlers is sufficient in any way. So if you believe that some new handler is needed urgently please let us know.

There is a lot of information stored during DFS (e.g. nodes in dfs-order, list of non-tree-edges). Some of it can be obtained directly by using the corresponding member-function (e.g. dfs::dfs_num), but all information that can be thought of as a list (e.g. nodes in dfs-order) can be accessed through iterators. In detail these are (of course depending on what options are chosen!):


Member Function Documentation

int dfs::run ( graph g  )  [virtual]

Applies algorithm to graph g.

Parameters:
g graph
Return values:
algorithm::GTL_OK on success
algorithm::GTL_ERROR otherwise

Implements algorithm.

virtual int dfs::check ( graph G  )  [virtual]

Checks whether the preconditions for DFS are satisfied.

Currently there aren't any restricitions for the DFS algorithm.

Parameters:
G graph.
Return values:
algorithm::GTL_OK if algorithm can be applied
algorithm::GTL_ERROR otherwise.

Implements algorithm.

Reimplemented in biconnectivity, components, and topsort.

virtual void dfs::reset (  )  [virtual]

Resets algorithm.

Prepares the algorithm to be applied to another graph. Please note: The options an algorithm may support do not get reset by this. It is just to reset internally used datastructures.

Implements algorithm.

Reimplemented in biconnectivity, components, and topsort.

void dfs::start_node ( const node n  )  [inline]

Sets start-node for DFS.

Parameters:
n start-node.

node dfs::start_node (  )  const [inline]

Returns start-node for DFS.

Returns:
start-node.

void dfs::scan_whole_graph ( bool  set  )  [inline]

Enables or disables scanning of the whole graph.

If enabled and the DFS started at the given start-node stops without having touched all nodes, it will be continued with the next unused node, and so on until all nodes were used. This makes sure that for every node dfs_number is defined.

On the other hand, if this feature is disabled, one will be able to check what nodes can be reached, when starting a DFS at the start-node, because for those not reached dfs_number will be 0.

Parameters:
set if true enable scanning the whole graph.
See also:
dfs::roots_begin

dfs::roots_end

bool dfs::scan_whole_graph (  )  const [inline]

Returns true iff the whole graph will be scanned.

Return values:
true iff the whole graph will be scanned.
See also:
dfs::roots_begin

dfs::roots_end

void dfs::calc_comp_num ( bool  set  ) 

Enables or Disables the calculation of the completion number.

Parameters:
set if true completion-numbers will be calculated.
See also:
dfs::comp_num

bool dfs::calc_comp_num (  )  const [inline]

Returns true iff completion-numbers will be calculated.

Return values:
true iff completion-numbers will be calculated.
See also:
dfs::comp_num

void dfs::store_preds ( bool  set  ) 

Enables or disables the storing of predecessors.

If enabled for every node the predecessor in DFS will be stored.

Parameters:
set if true predecessors will be stored.
See also:
dfs::father

bool dfs::store_preds (  )  const [inline]

Returns true iff the storing of predecessors is enabled.

Return values:
true iff the storing of predecessors is enabled.
See also:
dfs::father

void dfs::store_non_tree_edges ( bool  set  ) 

Enables the storing of back-edges.

If enabled the list of non-tree-edges can be traversed in the order they occured using non_tree_edges_iterator.

Parameters:
set if true non_tree_edges will be stored.
See also:
dfs::non_tree_edges_begin

dfs::non_tree_edges_end

bool dfs::store_non_tree_edges (  )  const [inline]

Returns true iff the storing of non-tree-edges is enabled.

Returns:
true iff the storing of non-tree-edges is enabled.
See also:
dfs::non_tree_edges_begin

dfs::non_tree_edges_end

bool dfs::reached ( const node n  )  const [inline]

Checks whether node n was reached in last DFS.

Parameters:
n node to be checked.
Returns:
true iff n was reached.

int dfs::dfs_num ( const node n  )  const [inline]

DFS-Number of n.

Please note that DFS-Number 0 means that this node wasn't reached.

Parameters:
n node.
Returns:
DFS-Number of n.

int dfs::operator[] ( const node n  )  const [inline]

DFS-Number of n.

Please note that DFS-Number 0 means that this node wasn't reached.

Parameters:
n node.
Returns:
DFS-Number of n.

int dfs::comp_num ( const node n  )  const [inline]

Completion-number of node n, if enabled in last run.

Parameters:
n node.
Returns:
Completion-number of n.
See also:
dfs::calc_comp_num

node dfs::father ( const node n  )  const [inline]

Returns father of node n in DFS-forest.

If n is a root in the forest or wasn't reached the return value is node().

Parameters:
n node.
Returns:
Father of n.
See also:
dfs::store_preds

tree_edges_iterator dfs::tree_edges_begin (  )  const [inline]

Iterate through all edges picked in last DFS.

Please note that this edges not always form a tree. In case the graph is not (strongly) connected they form a forest.

Returns:
start for iteration through all edges followed in DFS.

tree_edges_iterator dfs::tree_edges_end (  )  const [inline]

End-iterator for iteration through all edges picked in last DFS.

Returns:
end for iteration through all edges followed in DFS.

dfs_iterator dfs::begin (  )  const [inline]

Iterate through all (reached) nodes in DFS-order.

Returns:
start for iteration through all nodes in DFS-order.

dfs_iterator dfs::end (  )  const [inline]

End-Iterator for iteration through all (reached) nodes in DFS-order.

Returns:
end for iteration through all (reached) nodes

non_tree_edges_iterator dfs::non_tree_edges_begin (  )  const [inline]

Iterate through all non-tree-edges (if enabled).

Returns:
start for iteration through all non-tree-edges.
See also:
dfs::store_non_tree_edges

non_tree_edges_iterator dfs::non_tree_edges_end (  )  const [inline]

End-iterator for iteration through all non-tree-edges (if enabled).

Returns:
end for iteration through all non-tree-edges.
See also:
dfs::store_non_tree_edges

roots_iterator dfs::roots_begin (  )  const [inline]

Iterator pointing towards the first root in the DFS-forest.

Please note that intstead of pointing directly towards the node (i.e. *it is of type node) the iterator points towards a dfs_iterator, which represents the root (i.e. *it is of type dfs_iterator).

Using this technique makes it possible not only to obtain all the roots in the forest, but also the whole trees associated with each one. This can be achieved because a root_iterator specifies the exact position of the root in the DFS-ordering and by definition of DFS all the descendents of the root, i.e. the whole tree, will come later in DFS, such that by incrementing the dfs_iterator, a roots_iterator points at, one can traverse the whole tree with this given root.

Of course if the root isn't the last node in the DFS-forest on will also traverse all following trees, but since the first node of such a tree one will discover is its root, the successor of the roots_iterator can be used as end-iterator.

Returns:
start for iteration through all roots in DFS-forest.
See also:
dfs::scan_whole_graph

roots_iterator dfs::roots_end (  )  const [inline]

Iterator pointing to the end of all roots.

Returns:
end for iteration through all roots in DFS-forest.
See also:
dfs::scan_whole_graph

int dfs::number_of_reached_nodes (  )  const [inline]

Number of nodes reached in last DFS.

Returns:
number of reached nodes.
See also:
dfs::scan_whole_graph

virtual void dfs::init_handler ( graph G  )  [inline, virtual]

Handler called before the start of DFS.

Parameters:
G graph for which DFS was invoked.

Reimplemented in biconnectivity, and topsort.

virtual void dfs::end_handler ( graph G  )  [inline, virtual]

Handler called at the end of DFS.

Parameters:
G graph for which DFS was invoked.

Reimplemented in biconnectivity.

virtual void dfs::entry_handler ( graph G,
node n,
node f 
) [inline, virtual]

Handler called when touching node n.

Parameters:
G graph for which DFS was invoked.
n actual node.
f predecessor.

Reimplemented in biconnectivity.

virtual void dfs::leave_handler ( graph G,
node n,
node f 
) [inline, virtual]

Handler called after all the adjacent edges of n have been examined.

Parameters:
G graph for which DFS was invoked.
n actual node.
f predecessor.

Reimplemented in biconnectivity, and topsort.

virtual void dfs::before_recursive_call_handler ( graph G,
edge e,
node n 
) [inline, virtual]

Handler called when a unused node n connected to the actual node by e is found.

Parameters:
G graph for which DFS was invoked.
e edge connecting the actual node to the unused one.
n unused node.

Reimplemented in biconnectivity, and components.

virtual void dfs::after_recursive_call_handler ( graph G,
edge e,
node n 
) [inline, virtual]

Handler called after the algorithm returns from the subtree starting at n connected to the actual node by e.

Parameters:
G graph for which DFS was invoked.
e edge connecting the actual node to the unused one.
n unused node.

Reimplemented in biconnectivity.

virtual void dfs::old_adj_node_handler ( graph G,
edge e,
node n 
) [inline, virtual]

Handler called when a already marked node n connected to the actual node by e is found during the search of all adjacent edges of the actual node.

Parameters:
G graph for which DFS was invoked.
e edge connecting the actual node to the old one.
n used node.

Reimplemented in biconnectivity, components, and topsort.

virtual void dfs::new_start_handler ( graph G,
node n 
) [inline, virtual]

Called when DFS is started with start-node n.

This is particularly useful when DFS was invoked with the scan_whole_graph option.

Parameters:
G graph for which DFS was invoked.
n start-node.

Reimplemented in biconnectivity, and components.