8 #ifndef GRAPH_INFOS_HPP
9 #define GRAPH_INFOS_HPP
15 #include "utils/graph_typedefs.hpp"
17 #include "utils/scaffolding_typedefs.hpp"
21 namespace scaffold{
namespace graph_infos{
22 using namespace predicates;
23 using namespace scoring;
26 template<
class Graph,
class Information>
32 bool up_to_date =
false;
37 StructuralInfo(
const Graph& _g,
const Information& _payload): g(_g), payload(_payload), up_to_date(true) {}
43 virtual void update(
const bool force =
false) = 0;
58 const Information&
get()
60 if(!up_to_date) update();
77 using ComponentsAndNum = std::pair<ComponentMap<Graph>,
unsigned>;
87 bool num_up_to_date =
false;
88 bool consolidated =
false;
104 unsigned merge_from(
const ComponentMap<Graph>& source,
105 unsigned num_comps = payload.second,
106 const Matching<Graph>*
const vert_translate = NULL)
108 boost::unordered_map<unsigned, unsigned> comp_translate;
109 for(
const auto& i: source){
111 const Vertex<Graph>& v = i.first;
112 unsigned comp_of_v = i.second;
114 const auto emplace_result = comp_translate.emplace(comp_of_v, num_comps);
116 if(emplace_result.second) ++num_comps;
118 comp_of_v = emplace_result.first->second;
120 const Vertex<Graph> translated_v = vert_translate ? vert_translate->at(v) : v;
122 payload.first[translated_v] = comp_of_v;
129 void consolidate(
const unsigned offset = 0)
131 if(!consolidated || (offset != 0) || !num_up_to_date){
133 payload.second = merge_from(payload.first, offset, NULL);
134 num_up_to_date =
true;
140 void change_component(
const Vertex<Graph>& v,
const unsigned comp,
const unsigned avoid = UINT_MAX)
142 ComponentMap<Graph>& components = payload.first;
143 VertexQueue<Graph> next;
145 while(!next.empty()){
146 while(components.at(next.front()) == avoid) next.pop();
147 const Vertex<Graph>& w = next.front();
148 components[w] = comp;
149 for(
auto range = boost::adjacent_vertices(w, g); range.first != range.second; ++range.first){
150 const Vertex<Graph>& x = *range.first;
151 const unsigned x_comp = components.at(x);
153 if((x_comp != avoid) && (x_comp != comp)) next.push(x);
164 if(force || !up_to_date){
165 if(boost::num_vertices(g) == 0){
166 payload.first.clear();
168 }
else payload.second = graph_parameters::num_connected_components<Graph>(g, payload.first);
170 num_up_to_date =
true;
182 payload.first.clear();
187 for(
const auto& i: infos.
payload.first) payload.first.emplace(translate.at(i.first), i.second);
189 num_up_to_date &= infos.num_up_to_date;
191 payload.second = infos.
payload.second;
198 if(num_up_to_date) --payload.second;
199 consolidated =
false;
210 assert(num_up_to_date);
212 payload.second = merge_from(info.
payload.first, payload.second, &translate);
213 num_up_to_date =
true;
216 num_up_to_date &= info.num_up_to_date;
217 if(num_up_to_date && info.num_up_to_date)
218 payload.second += info.
payload.second;
224 if(up_to_date && num_up_to_date && consolidated){
225 payload.first[u] = payload.second;
228 consolidated =
false;
234 void add_edge(
const Vertex<Graph>& u,
const Vertex<Graph>& v)
238 ComponentMap<Graph>& components = payload.first;
239 const unsigned u_comp = components.at(u);
240 if(u_comp != components.at(v)){
242 change_component(v, u_comp, u_comp);
246 }
else num_up_to_date =
false;
250 void delete_edge(
const VertexPair<Graph>& uv,
const bool is_bridge)
255 change_component(uv.second, payload.second);
266 return num_up_to_date;
272 if(!num_up_to_date) update();
273 return payload.second;
280 return payload.second;
291 template<
class Graph>
299 void update_from_vertex(
const Vertex<Graph>& u){
300 const unsigned u_deg = boost::degree(u, g);
301 if(u_deg > payload.second)
302 payload = VertexAndDegree<Graph>(u, u_deg);
308 if(force || !up_to_date){
309 if(boost::num_edges(g) == 0){
311 if(boost::num_vertices(g))
312 payload.first = *(boost::vertices(g).first);
313 }
else payload = graph_parameters::get_max_degree(g);
327 payload.first = translate.at(infos.
payload.first);
328 payload.second = infos.
payload.second;
336 const typename Matching<Graph>::const_iterator i = translate.find(info.
payload.first);
337 if(i != translate.cend()){
338 payload.first = i->second;
339 payload.second = info.
payload.second;
341 }
else up_to_date =
false;
349 if(info.
payload.second > payload.second)
350 payload = VertexAndDegree<Graph>(translate.at(info.
payload.first), info.
payload.second);
355 void add_edge(
const Vertex<Graph>& u,
const Vertex<Graph>& v)
358 update_from_vertex(u);
359 update_from_vertex(v);
379 template<
class Graph>
389 if(force || !up_to_date){
390 if(boost::num_edges(g)){
391 DEBUG5(std::cout <<
"running bridge finder"<<std::endl);
393 mark_bridges(g, payload);
411 update_disjoint_union(infos, translate);
425 for(
const auto& i: info.
payload)
426 payload.emplace(std::piecewise_construct,
427 std::tuple<Vertex<Graph>, Vertex<Graph> >(translate.at(i.first.first), translate.at(i.first.second)),
428 std::tuple<unsigned>(i.second));
432 void add_edge(
const Vertex<Graph>& u,
const Vertex<Graph>& v)
441 const typename BridgeMap<Graph>::iterator uv_iter = payload.find(uv);
443 if(uv_iter != payload.cend())
444 payload.erase(uv_iter);
451 bool is_bridge(
const Vertex<Graph>& u,
const Vertex<Graph>& v)
454 return contains(payload, VertexPair<Graph>(u, v)) ||
contains(payload, VertexPair<Graph>(v, u));
460 return contains(payload, VertexPair<Graph>(u, v)) ||
contains(payload, VertexPair<Graph>(v, u));
466 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
467 void _get_non_bridges(std::list<WeightedBridge<Graph>>& non_bridges,
const EdgePredicate& predicate)
const
469 for(EdgeIterRange<Graph> er = boost::edges(g); er.first != er.second; ++er.first){
470 const Edge<Graph>& e = *er.first;
472 const EdgeProperty<Graph>& e_info = g[e];
473 const Vertex<Graph>& u = boost::source(e, g);
474 const Vertex<Graph>& v = boost::target(e, g);
475 const VertexPair<Graph> uv(u, v);
477 non_bridges.emplace_back(uv, e_info.weight);
480 DEBUG5(std::cout <<
"found "<<non_bridges.size()<<
" non-bridges"<<std::endl);
485 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
486 void get_non_bridges(std::list<WeightedBridge<Graph>>& non_bridges,
const EdgePredicate& predicate = EdgePredicate())
488 if(!up_to_date) update();
489 _get_non_bridges(non_bridges, predicate);
493 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
494 void get_non_bridges_const(std::list<WeightedBridge<Graph>>& non_bridges,
const EdgePredicate& predicate = EdgePredicate())
const
497 _get_non_bridges(non_bridges, predicate);
504 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
507 std::list<WeightedBridge<Graph>> non_bridges;
508 _get_non_bridges(non_bridges, predicate);
510 assert(!non_bridges.empty());
512 return *(std::min_element(non_bridges.cbegin(), non_bridges.cend()));
517 #warning TODO: explain what 'lightest bridge' means for the documentation
518 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
521 if(!up_to_date) update();
522 return _get_cheapest_nonbridge(predicate);
526 template<
class EdgePredicate = TruePredicate<Edge<Graph> > >
530 return _get_cheapest_nonbridge(predicate);
537 for(AdjIterRange<Graph> r = boost::adjacent_vertices(u, g); r.first != r.second; ++r.first){
538 const Vertex<Graph>& v = *r.first;
539 if(!
contains(payload, VertexPair<Graph>(u, v)) && !
contains(payload, VertexPair<Graph>(v, u)))
return true;
548 if(!up_to_date) update();
549 return _has_incident_nonbridge(u);
556 return _has_incident_nonbridge(v);
561 template<
class Scoring = IdentityScore<VertexPair<Graph> > >
565 WeightedBridge<Graph>* best_b = NULL;
566 unsigned best_score = UINT_MAX;
567 for(cBridgeIter<Graph> bi = payload.cbegin(); bi != payload.cend(); ++bi){
568 const VertexPair<Graph>& b = bi->first;
569 const unsigned new_score = score(bi->second);
570 if(new_score < best_score){
571 best_score = new_score;
580 template<
class Scoring = IdentityScore<VertexPair<Graph> > >
583 if(!up_to_date) update();
584 return _get_best_bridge(score);
588 template<
class Scoring = IdentityScore<VertexPair<Graph> > >
592 return _get_best_bridge(score);
603 template<
class Graph>
612 GraphInfos(
const Graph& _g,
const bool update_values =
false): g(_g), comps(_g), max_deg(_g), bridges(_g)
614 if(update_values) update_all();
620 comps(g, infos.comps, translate),
621 max_deg(g, infos.max_deg, translate),
622 bridges(g, infos.bridges, translate)
654 void add_edge(
const Vertex<Graph>& u,
const Vertex<Graph>& v)
712 if(max_deg.
get().second <= 2){
713 const unsigned V = boost::num_vertices(g);
714 const unsigned E = boost::num_edges(g);
715 const unsigned cycles = E + cc - V;
716 const unsigned paths = V - E;
725 return _get_paths_and_cycles(comps.
get_num());
737 return compute_FES(boost::num_vertices(g), boost::num_edges(g), comps.
get_num());
743 return compute_FES(num_vertices(g), num_edges(g), comps.
get_num_const());
750 return (get_FES_const() == 0);
752 return bridges.
get().size() == boost::num_edges(*g);
759 return (get_FES_const() == 0);
761 return bridges.
get_const().size() == boost::num_edges(*g);
768 const unsigned E = boost::num_edges(*g);
770 if(E == 0)
return true;
772 const unsigned V = boost::num_vertices(*g);
773 if(V >= 2 * E)
return true;
780 if(is_max_deg_two_easy_cases())
return true;
781 return (max_deg.
get().second < 3);
787 if(is_max_deg_two_easy_cases())
return true;
a graph property for the maximum degree in g
Definition: graph_infos.hpp:292
PathsAndCycles _get_paths_and_cycles(const unsigned cc)
get the number of paths and cycles in the graph, assuming its max degree is 2
Definition: graph_infos.hpp:710
const WeightedBridge< Graph > * get_best_bridge(const Scoring &score=Scoring()) const
get non-matching bridge that minimizes the given scoring function without updating the bridge map ...
Definition: graph_infos.hpp:589
void delete_edge(const VertexPair< Graph > &uv)
react to deletion of edge uv
Definition: graph_infos.hpp:662
a graph property for the set of bridges in g
Definition: graph_infos.hpp:380
void read_from_split_off_component(const GraphInfos< Graph > &infos, const Matching< Graph > &translate)
react to splitting off this connected component g from a graph h
Definition: graph_infos.hpp:688
StructuralInfo(const Graph &_g)
constructor
Definition: graph_infos.hpp:35
unsigned paths
maximum number of paths that a solution graph should consist of
Definition: command_line.hpp:56
void read_from_infos(const GraphInfos< Graph > &infos, const Matching< Graph > &translate)
update the infos from the graph h of which g has just been copied
Definition: graph_infos.hpp:677
bool up_to_date
indicate whether the property needs to be recomputed due to changes in the graph
Definition: graph_infos.hpp:32
void read_from_infos(const BridgeInfo< Graph > &infos, const Matching< Graph > &translate)
read from translated information
Definition: graph_infos.hpp:406
unsigned cycles
maximum number of cycles that a solution graph should consist of
Definition: command_line.hpp:58
bool is_max_deg_two_easy_cases() const
return whether g has maximum degree 2 using only queries to |V| and |E|
Definition: graph_infos.hpp:766
unsigned get_FES_const() const
return the feedback edge set number of the graph without updating its infos
Definition: graph_infos.hpp:741
void read_from_infos(const MaxDegreeInfo< Graph > &infos, const Matching< Graph > &translate)
read from translated information
Definition: graph_infos.hpp:322
const Graph & g
a reference to the graph
Definition: graph_infos.hpp:30
Definition: read_adj_list.hpp:22
bool has_incident_nonbridge_const(const Vertex< Graph > &v) const
return whether a vertex has an incident nonbridge without updating the bridge map ...
Definition: graph_infos.hpp:553
bool _has_incident_nonbridge(const Vertex< Graph > &u) const
return whether a vertex has an incident nonbridge
Definition: graph_infos.hpp:535
an exception for the case that a graph property is read that is not up to date
Definition: exceptions.hpp:17
const WeightedBridge< Graph > get_cheapest_nonbridge(const EdgePredicate &predicate=EdgePredicate())
return the lightest non-bridge, updating the bridge map if necessary
Definition: graph_infos.hpp:519
void update(const bool force=false)
update the connected components
Definition: graph_infos.hpp:162
Information payload
the actual graph property
Definition: graph_infos.hpp:31
void add_edge(const Vertex< Graph > &u, const Vertex< Graph > &v)
react to addition of edge uv
Definition: graph_infos.hpp:654
StructuralInfo(const Graph &_g, const Information &_payload)
constructor
Definition: graph_infos.hpp:37
PathsAndCycles get_paths_and_cycles()
get the number of paths and cycles in the graph, assuming its max degree is 2, updating infos if nece...
Definition: graph_infos.hpp:723
const unsigned get_num_const() const
return the number of connected components without updating
Definition: graph_infos.hpp:277
a graph property for the number of connected components and a map of vertices to components (represen...
Definition: graph_infos.hpp:81
bool is_valid() const
return whether the property is up-to-date
Definition: graph_infos.hpp:52
const WeightedBridge< Graph > get_cheapest_nonbridge(const EdgePredicate &predicate=EdgePredicate()) const
return the lightest non-bridge without updating the bridge map
Definition: graph_infos.hpp:527
void read_from_split_off_component(const ComponentInfo< Graph > &info)
react to splitting off a connected component of the graph g
Definition: graph_infos.hpp:196
void delete_edge(const Vertex< Graph > &u, const Vertex< Graph > &v)
react to the deletion of the edge uv
Definition: graph_infos.hpp:364
void read_from_split_off_component(const BridgeInfo< Graph > &info, const Matching< Graph > &translate)
read from given infos, assuming that g is a single connected component that has been split off ...
Definition: graph_infos.hpp:415
void delete_edge(const VertexPair< Graph > &uv, const bool is_bridge)
react to the deletion of the edge uv, depending on whether it was a bridge or not ...
Definition: graph_infos.hpp:250
const WeightedBridge< Graph > * get_best_bridge(const Scoring &score=Scoring())
get non-matching bridge that minimizes the given scoring function, updating the bridge map if necessa...
Definition: graph_infos.hpp:581
an exception for the case that some assumption that is made is not true
Definition: exceptions.hpp:30
const WeightedBridge< Graph > _get_cheapest_nonbridge(const EdgePredicate &predicate) const
return the non-bridge of least weight
Definition: graph_infos.hpp:505
bool is_max_deg_two()
return whether the graph has max degree 2, updating its max-degree info if necessary ...
Definition: graph_infos.hpp:778
void update(const bool force=false)
update bridges
Definition: graph_infos.hpp:387
const WeightedBridge< Graph > * _get_best_bridge(const Scoring &score) const
get non-matching bridge that minimizes the given scoring function
Definition: graph_infos.hpp:562
bool is_acyclic_const() const
return whether the graph is acyclic without updating its infos
Definition: graph_infos.hpp:756
prototype class for structural graph properties
Definition: graph_infos.hpp:27
void read_from_split_off_component(const MaxDegreeInfo< Graph > &info, const Matching< Graph > &translate)
read from given infos, assuming that g is a single connected component that has been split off ...
Definition: graph_infos.hpp:333
bool is_bridge_const(const Vertex< Graph > &u, const Vertex< Graph > &v) const
return whether the edge uv is a bridge, avoiding updating the bridge map
Definition: graph_infos.hpp:457
void update_disjoint_union(const MaxDegreeInfo< Graph > &info, const Matching< Graph > &translate)
update infos, assuming that g is the disjoint union of a graph with our infos and a graph with the gi...
Definition: graph_infos.hpp:345
unsigned get_FES()
return the feedback edge set number of the graph, updating its infos if necessary ...
Definition: graph_infos.hpp:735
void add_edge(const Vertex< Graph > &u, const Vertex< Graph > &v)
react to addition of the edge uv
Definition: graph_infos.hpp:355
void update(const bool force=false)
update the max degree
Definition: graph_infos.hpp:306
void read_from_infos(const ComponentInfo< Graph > &infos, const Matching< Graph > &translate)
read from translated information
Definition: graph_infos.hpp:180
void delete_edge(const VertexPair< Graph > &uv)
react to the deletion of the edge uv
Definition: graph_infos.hpp:438
bool num_is_valid() const
return whether the number of connected components is up to date
Definition: graph_infos.hpp:264
GraphInfos(const Graph &_g, const bool update_values=false)
constructor: needs a graph to initalize the EdgeHasher of the bridgs; updates all values on construct...
Definition: graph_infos.hpp:612
bool is_acyclic()
return whether the graph is acyclic, updating its infos if necessary
Definition: graph_infos.hpp:747
void add_vertex(const Vertex< Graph > &u)
react to the addition of a single vertex u to g
Definition: graph_infos.hpp:222
void update_disjoint_union(const ComponentInfo< Graph > &info, const Matching< Graph > &translate)
react to forming the disjoint union of g with a graph h, given the corresponding property of h ...
Definition: graph_infos.hpp:203
const VertexAndDegree< Graph > & get()
get the current value of the property, updating if necessary
Definition: graph_infos.hpp:58
bool is_max_deg_two_const() const
return whether the graph has max degree 2 without updating infos
Definition: graph_infos.hpp:785
void update_disjoint_union(const BridgeInfo< Graph > &info, const Matching< Graph > &translate)
update infos, assuming that g is the disjoint union of a graph with our infos and a graph with the gi...
Definition: graph_infos.hpp:421
void invalidate_all()
invalidate all infos
Definition: graph_infos.hpp:628
PathsAndCycles get_paths_and_cycles_const() const
get the number of paths and cycles in the graph, assuming its max degree is 2, without updating the i...
Definition: graph_infos.hpp:729
bool is_bridge(const Vertex< Graph > &u, const Vertex< Graph > &v)
return whether the edge uv is a bridge, updating the infos if necessary
Definition: graph_infos.hpp:451
bool has_incident_nonbridge(const Vertex< Graph > &u)
return whether a vertex has an incident nonbridge, updating the bridge map if necessary ...
Definition: graph_infos.hpp:546
void add_edge(const Vertex< Graph > &u, const Vertex< Graph > &v)
react to the addition of the edge uv to g
Definition: graph_infos.hpp:234
void invalidate()
set the property to "not up-to-date"
Definition: graph_infos.hpp:46
void add_vertex(const Vertex< Graph > &u)
react to addition of vertex u
Definition: graph_infos.hpp:647
void get_non_bridges_const(std::list< WeightedBridge< Graph >> &non_bridges, const EdgePredicate &predicate=EdgePredicate()) const
return the set of non-bridges without updating the bridge map
Definition: graph_infos.hpp:494
const unsigned get_num()
return the number of connected components, updating if necessary
Definition: graph_infos.hpp:270
bool contains(const Set &s, const Element &el)
a more readable containment check
Definition: utils.hpp:171
void update_disjoint_union(const GraphInfos< Graph > &infos, const Matching< Graph > &translate)
react to forming a disjoint union with g with another graph h, given the infos of h and a translate m...
Definition: graph_infos.hpp:699
GraphInfos(const Graph &_g, const GraphInfos &infos, const Matching< Graph > &translate)
constructor
Definition: graph_infos.hpp:618
void _get_non_bridges(std::list< WeightedBridge< Graph >> &non_bridges, const EdgePredicate &predicate) const
store all non-bridges with their weights in the parameter
Definition: graph_infos.hpp:467
void update_all(const bool force=false)
update all values
Definition: graph_infos.hpp:638
void get_non_bridges(std::list< WeightedBridge< Graph >> &non_bridges, const EdgePredicate &predicate=EdgePredicate())
return the set of non-bridges in g, updating the bridge map if necessary
Definition: graph_infos.hpp:486
const Information & get_const() const
get the current value of the property without updating
Definition: graph_infos.hpp:66
an accumulator class for different graph properties
Definition: graph_infos.hpp:604
void add_edge(const Vertex< Graph > &u, const Vertex< Graph > &v)
react to the addition of the edge uv to g
Definition: graph_infos.hpp:432
Definition: graph_typedefs.hpp:26