|
|
|
|
|
#ifndef DLIB_GENERAL_FLOW_GRaPH_Hh_ |
|
#define DLIB_GENERAL_FLOW_GRaPH_Hh_ |
|
|
|
#include "../graph_utils.h" |
|
|
|
namespace dlib |
|
{ |
|
|
|
|
|
|
|
namespace impl |
|
{ |
|
|
|
template < |
|
typename directed_graph_type |
|
> |
|
class general_flow_graph |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
directed_graph_type& g; |
|
|
|
typedef typename directed_graph_type::node_type node_type; |
|
typedef typename directed_graph_type::type node_label; |
|
|
|
public: |
|
|
|
general_flow_graph( |
|
directed_graph_type& g_ |
|
) : g(g_) |
|
{ |
|
} |
|
|
|
class out_edge_iterator |
|
{ |
|
friend class general_flow_graph; |
|
unsigned long idx; |
|
unsigned long cnt; |
|
public: |
|
|
|
out_edge_iterator( |
|
):idx(0),cnt(0) {} |
|
|
|
out_edge_iterator( |
|
unsigned long idx_, |
|
unsigned long cnt_ |
|
):idx(idx_),cnt(cnt_) |
|
{} |
|
|
|
bool operator!= ( |
|
const out_edge_iterator& item |
|
) const { return cnt != item.cnt; } |
|
|
|
out_edge_iterator& operator++( |
|
) |
|
{ |
|
++cnt; |
|
return *this; |
|
} |
|
}; |
|
|
|
class in_edge_iterator |
|
{ |
|
|
|
friend class general_flow_graph; |
|
unsigned long idx; |
|
unsigned long cnt; |
|
public: |
|
|
|
in_edge_iterator( |
|
):idx(0),cnt(0) {} |
|
|
|
in_edge_iterator( |
|
unsigned long idx_, |
|
unsigned long cnt_ |
|
):idx(idx_),cnt(cnt_) |
|
{} |
|
|
|
bool operator!= ( |
|
const in_edge_iterator& item |
|
) const { return cnt != item.cnt; } |
|
|
|
in_edge_iterator& operator++( |
|
) |
|
{ |
|
++cnt; |
|
return *this; |
|
} |
|
}; |
|
|
|
unsigned long number_of_nodes ( |
|
) const { return g.number_of_nodes(); } |
|
|
|
out_edge_iterator out_begin( |
|
const unsigned long& it |
|
) const { return out_edge_iterator(it, 0); } |
|
|
|
in_edge_iterator in_begin( |
|
const unsigned long& it |
|
) const { return in_edge_iterator(it, 0); } |
|
|
|
out_edge_iterator out_end( |
|
const unsigned long& it |
|
) const { return out_edge_iterator(it, g.node(it).number_of_children()); } |
|
|
|
in_edge_iterator in_end( |
|
const unsigned long& it |
|
) const { return in_edge_iterator(it, g.node(it).number_of_parents()); } |
|
|
|
unsigned long node_id ( |
|
const out_edge_iterator& it |
|
) const { return g.node(it.idx).child(it.cnt).index(); } |
|
unsigned long node_id ( |
|
const in_edge_iterator& it |
|
) const { return g.node(it.idx).parent(it.cnt).index(); } |
|
|
|
typedef typename directed_graph_type::edge_type edge_type; |
|
|
|
edge_type get_flow (const unsigned long& it1, const unsigned long& it2) const |
|
{ |
|
return edge(g, it1, it2); |
|
} |
|
edge_type get_flow (const out_edge_iterator& it) const |
|
{ |
|
return g.node(it.idx).child_edge(it.cnt); |
|
} |
|
edge_type get_flow (const in_edge_iterator& it) const |
|
{ |
|
return g.node(it.idx).parent_edge(it.cnt); |
|
} |
|
|
|
void adjust_flow ( |
|
const unsigned long& it1, |
|
const unsigned long& it2, |
|
const edge_type& value |
|
) |
|
{ |
|
edge(g, it1, it2) += value; |
|
edge(g, it2, it1) -= value; |
|
} |
|
|
|
void set_label ( |
|
const unsigned long& it, |
|
node_label value |
|
) |
|
{ |
|
g.node(it).data = value; |
|
} |
|
|
|
node_label get_label ( |
|
const unsigned long& it |
|
) const |
|
{ |
|
return g.node(it).data; |
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|