value_type operator[](key_type v) const { using boost::out_degree; if (get(pm, v)) { return true; } return out_degree(v, g) != 2; }
inline typename boost::graph_traits<Graph>::vertex_descriptor get_start_vertex(const Graph& g) { using boost::vertices; using boost::out_degree; typename boost::graph_traits<Graph>::vertex_iterator vi, vi_end; for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { if (out_degree(*vi, g) == 1) { return *vi; } } // TODO error process throw std::runtime_error("Graph is not linear."); }
typename AcyclicGraph<LinearGraph, WeightMap>::type convert_linear_graph_to_acyclic_graph (const LinearGraph& g, WeightMap weight, CandidateMap candidate, Combine combine, Multiple multiple) { using boost::vertices; using boost::out_edges; using boost::out_degree; using boost::target; typedef boost::graph_traits<LinearGraph> Traits; typedef typename Traits::vertex_descriptor Vertex; typedef typename Traits::vertex_iterator VIter; typedef typename boost::property_traits<WeightMap>::value_type WeightValue; typedef typename AcyclicGraph<LinearGraph, WeightMap>::type AcyclicGraph; const typename std::iterator_traits<VIter>::difference_type num_v = boost::distance(vertices(g)); const Vertex s = detail::get_start_vertex(g); std::vector<Vertex> new_vertices; new_vertices.reserve(num_v); std::vector<WeightValue> e_weight; e_weight.reserve(num_v - 1); // Collect info about a linear graph new_vertices.push_back(s); Vertex prev = s, now = s; typename Traits::out_edge_iterator ei, ei_end; do { boost::tie(ei, ei_end) = out_edges(now, g); if (target(*ei, g) == prev) { ++ei; } const Vertex next = target(*ei, g); if (get(candidate, next) || out_degree(next, g) == 1) { new_vertices.push_back(next); } if (get(candidate, now) || out_degree(now, g) == 1) { e_weight.push_back(get(weight, *ei)); } else { e_weight.back() = combine(e_weight.back(), get(weight, *ei)); } prev = now; now = next; } while (out_degree(now, g) != 1); // create acyclic graph's edge info const std::vector< std::pair<std::size_t, std::size_t> > new_edges(detail::create_new_edges(new_vertices.size())); const std::vector<WeightValue> new_weight(detail::convert_edge_weight(e_weight, combine, multiple)); AcyclicGraph acyclic_g( boost::edges_are_sorted, new_edges.begin(), new_edges.end(), new_weight.begin(), new_vertices.size()); // set vertex prop; typename boost::graph_traits<AcyclicGraph>::vertex_iterator vi, vi_end; for (boost::tie(vi, vi_end) = vertices(acyclic_g); vi != vi_end; ++vi) { acyclic_g[*vi] = new_vertices[get(boost::vertex_index, acyclic_g, *vi)]; } return acyclic_g; }
void assert_graphs_equal(const G1& g1, const VI1& vi1, const G2& g2, const VI2& vi2, const IsomorphismMap& iso) { using boost::out_degree; BOOST_CHECK (num_vertices(g1) == num_vertices(g2)); BOOST_CHECK (num_edges(g1) == num_edges(g2)); typedef typename boost::graph_traits<G1>::vertex_iterator vertiter1; { vertiter1 i, iend; for (boost::tie(i, iend) = vertices(g1); i != iend; ++i) { typename boost::graph_traits<G1>::vertex_descriptor v1 = *i; typename boost::graph_traits<G2>::vertex_descriptor v2 = iso[v1]; BOOST_CHECK (vi1[v1] == vi2[v2]); BOOST_CHECK (out_degree(v1, g1) == out_degree(v2, g2)); std::vector<std::size_t> edges1(out_degree(v1, g1)); typename boost::graph_traits<G1>::out_edge_iterator oe1, oe1end; for (boost::tie(oe1, oe1end) = out_edges(v1, g1); oe1 != oe1end; ++oe1) { BOOST_CHECK (source(*oe1, g1) == v1); edges1.push_back(vi1[target(*oe1, g1)]); } std::vector<std::size_t> edges2(out_degree(v2, g2)); typename boost::graph_traits<G2>::out_edge_iterator oe2, oe2end; for (boost::tie(oe2, oe2end) = out_edges(v2, g2); oe2 != oe2end; ++oe2) { BOOST_CHECK (source(*oe2, g2) == v2); edges2.push_back(vi2[target(*oe2, g2)]); } std::sort(edges1.begin(), edges1.end()); std::sort(edges2.begin(), edges2.end()); if (edges1 != edges2) { std::cerr << "For vertex " << v1 << std::endl; std::cerr << "edges1:"; for (size_t i = 0; i < edges1.size(); ++i) std::cerr << " " << edges1[i]; std::cerr << std::endl; std::cerr << "edges2:"; for (size_t i = 0; i < edges2.size(); ++i) std::cerr << " " << edges2[i]; std::cerr << std::endl; } BOOST_CHECK (edges1 == edges2); } } { std::vector<std::pair<std::size_t, std::size_t> > all_edges1; std::vector<std::pair<std::size_t, std::size_t> > all_edges2; typename boost::graph_traits<G1>::edge_iterator ei1, ei1end; for (boost::tie(ei1, ei1end) = edges(g1); ei1 != ei1end; ++ei1) all_edges1.push_back(std::make_pair(vi1[source(*ei1, g1)], vi1[target(*ei1, g1)])); typename boost::graph_traits<G2>::edge_iterator ei2, ei2end; for (boost::tie(ei2, ei2end) = edges(g2); ei2 != ei2end; ++ei2) all_edges2.push_back(std::make_pair(vi2[source(*ei2, g2)], vi2[target(*ei2, g2)])); std::sort(all_edges1.begin(), all_edges1.end()); std::sort(all_edges2.begin(), all_edges2.end()); BOOST_CHECK (all_edges1 == all_edges2); } }