我对BGL(增强图库)非常陌生。当我试图使用平面地图遍历时,我遇到以下编译问题,有人可以向我解释我做错了什么吗?导致错误的代码是:
put(e_index, *ei, edge_count++);
planar_face_traversal(g, &embedding[0], v_vis);
planar_face_traversal(g, &embedding[0], e_vis);
/usr/include/boost/property_map/property_map.hpp:361: error: no match for 'operator=' in '(&((const boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, boost::detail::error_property_not_found&, long unsigned int, boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>&)pa))->boost::adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property, Tag>::operator[] [with Directed = boost::undirected_tag, Value = boost::detail::error_property_not_found, Ref = boost::detail::error_property_not_found&, Vertex = long unsigned int, Property = boost::property<boost::edge_bundle_t, Edge, boost::no_property>, Tag = boost::edge_index_t, boost::adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property, Tag>::key_type = boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>](k) = v'
/usr/include/boost/property_map/property_map.hpp:391: error: no match for 'operator+' in '((const boost::iterator_property_map<__gnu_cxx::__normal_iterator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >*, std::vector<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::allocator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > > > > >, boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >&>*)this)->boost::iterator_property_map<__gnu_cxx::__normal_iterator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >*, std::vector<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::allocator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > > > > >, boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >&>::iter + boost::get [with PropertyMap = boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>, Reference = const boost::detail::error_property_not_found&, K = boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>]((*(const boost::put_get_helper<const boost::detail::error_property_not_found&, boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t> >*)(&((const boost::iterator_property_map<__gnu_cxx::__normal_iterator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >*, std::vector<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::allocator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > > > > >, boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >&>*)this)->boost::iterator_property_map<__gnu_cxx::__normal_iterator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >*, std::vector<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::allocator<std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > > > > >, boost::adj_list_edge_property_map<boost::undirected_tag, boost::detail::error_property_not_found, const boost::detail::error_property_not_found&, long unsigned int, const boost::property<boost::edge_bundle_t, Edge, boost::no_property>, boost::edge_index_t>, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >, std::map<long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, std::less<long unsigned int>, std::allocator<std::pair<const long unsigned int, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int> > > >&>::index)), (*(const boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>*)(& v)))'
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/ref.hpp>
#include <vector>
#include <boost/graph/planar_face_traversal.hpp>
#include <boost/graph/boyer_myrvold_planar_test.hpp> using namespace boost;
// Some planar face traversal visitors that will // print the vertices and edges on the faces
class Vertex{ public:
int i;//just some variable
Vertex(){}
Vertex(int val){
i = val;
} };
class Edge{ public:
int i;//just some variable
Edge(){}
Edge(int val){
i = val;
} };
struct output_visitor : public planar_face_traversal_visitor { void begin_face() { std::cout << "New face: "; } void end_face() { std::cout << std::endl; } };
struct vertex_output_visitor : public output_visitor { void next_vertex(Vertex v) {
std::cout << v.i << " "; } };
struct edge_output_visitor : public output_visitor { void next_edge(Edge e) {
std::cout << e.i << " "; } };
int main(int argc, char** argv) {
typedef adjacency_list
< vecS,
vecS,
undirectedS,
Vertex,
Edge
>
graph;
// Create a graph - this is a biconnected, 3 x 3 grid. // It should have four small (four vertex/four edge) faces and // one large face that contains all but the interior vertex graph g;
typedef boost::graph_traits<graph>::vertex_descriptor VertexDescriptor; typedef boost::graph_traits<graph>::edge_descriptor EdgeDescriptor;
VertexDescriptor v0 = add_vertex(g); VertexDescriptor v1 = add_vertex(g); VertexDescriptor v2 = add_vertex(g); VertexDescriptor v3 = add_vertex(g); VertexDescriptor v4 = add_vertex(g); add_edge(v0,v1,g); add_edge(v1,v2,g); add_edge(v2,v3,g); add_edge(v3,v4,g); add_edge(v4,v0,g);
add_edge(v0,v2,g); add_edge(v0,v3,g);
add_edge(v1,v4,g); add_edge(v1,v3,g);
add_edge(v2, v4, g);
// Initialize the interior edge index property_map<graph, edge_index_t>::type e_index = get(edge_index, g);
graph_traits<graph>::edges_size_type edge_count = 0; graph_traits<graph>::edge_iterator ei, ei_end; for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
put(e_index, *ei, edge_count++);
std::cout << *ei << std::endl; }
// Test for planarity - we know it is planar, we just want to // compute the planar embedding as a side-effect
typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t; std::vector<vec_t> embedding(num_vertices(g)); std::cout << num_vertices(g) << std::endl; if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
boyer_myrvold_params::embedding =
&embedding[0]
)
)
std::cout << "Input graph is planar" << std::endl; else
std::cout << "Input graph is not planar" << std::endl;
std::cout << std::endl << "Vertices on the faces: " << std::endl; vertex_output_visitor v_vis; planar_face_traversal(g, &embedding[0], v_vis);
std::cout << std::endl << "Edges on the faces: " << std::endl; output_visitor e_vis; planar_face_traversal(g, &embedding[0], e_vis);
return 0; }
答案 0 :(得分:2)
您的代码有几个问题。导致编译器错误的一个原因是您的图形没有内部edge_index
属性,并且您正在尝试使用它。将EdgeProperty
更改为property<edge_index_t,std::size_t,Edge>
可以轻松解决。您的xxx_output_visitors
也存在问题。 next_vertex
和next_edge
分别指望vertex_descriptor和edge_descriptor。我在下面更改了它们以做一些“有用”的事情。最后一个问题是boyer_myrvold_planarity_test
为您的图表返回false。由于我真的不知道有关问题域的事情,我只是使用找到的here更改了图表。
更新:如果您想避免使用property<edge_index_t,std::size_t,Edge>
,只需创建外部属性地图,然后将其传递给planar_face_traversal
即可。除非您还使用参数boyer_myrvold_planarity_test
,否则kuratowski_subgraph
不需要传递边缘索引图。
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/ref.hpp>
#include <vector>
#include <boost/graph/planar_face_traversal.hpp>
#include <boost/graph/boyer_myrvold_planar_test.hpp>
using namespace boost;
// Some planar face traversal visitors that will
// print the vertices and edges on the faces
class Vertex
{
public:
int i;//just some variable
Vertex(){}
Vertex(int val){
i = val;
}
};
class Edge
{
public:
int i;//just some variable
Edge(){}
Edge(int val){
i = val;
}
};
typedef adjacency_list
< vecS,
vecS,
undirectedS,
Vertex,
Edge
>
graph_type;
struct output_visitor : public planar_face_traversal_visitor
{
void begin_face() { std::cout << "New face: "; }
void end_face() { std::cout << std::endl; }
};
struct vertex_output_visitor : public output_visitor
{
vertex_output_visitor(const graph_type& g_):g(g_){}
template <typename VertexDesc>
void next_vertex(VertexDesc v)
{
//std::cout << g[v].i << " "; //This would do what you wanted if you initialize "i"
std::cout << get(vertex_index,g,v) << " ";
}
const graph_type& g;
};
struct edge_output_visitor : public output_visitor
{
edge_output_visitor(const graph_type& g_):g(g_){}
template <typename EdgeDesc>
void next_edge(EdgeDesc e)
{
//std::cout << g[e].i << " "; //This would do what you wanted
std::cout << source(e,g) << "-" << target(e,g) << " ";
}
const graph_type& g;
};
int main() {
// Create a graph - this is a biconnected, 3 x 3 grid.
// It should have four small (four vertex/four edge) faces and
// one large face that contains all but the interior vertex
graph_type g;
typedef boost::graph_traits<graph_type>::vertex_descriptor VertexDescriptor;
typedef boost::graph_traits<graph_type>::edge_descriptor EdgeDescriptor;
VertexDescriptor A = add_vertex(g);
VertexDescriptor B = add_vertex(g);
VertexDescriptor C = add_vertex(g);
VertexDescriptor D = add_vertex(g);
VertexDescriptor E = add_vertex(g);
add_edge(A,B,g);
add_edge(A,C,g);
add_edge(A,D,g);
add_edge(A,E,g);
add_edge(B,D,g);
add_edge(B,E,g);
add_edge(C,D,g);
add_edge(C,E,g);
add_edge(D,E,g);
typedef std::map<EdgeDescriptor, size_t> EdgeIndexMap;
EdgeIndexMap mapIndex;
boost::associative_property_map<EdgeIndexMap> my_edge_index_map(mapIndex);
graph_traits<graph_type>::edges_size_type current_index=0;
BGL_FORALL_EDGES(e,g,graph_type)
{
put(my_edge_index_map,e,current_index++);
std::cout << e << std::endl;
}
// Test for planarity - we know it is planar, we just want to
// compute the planar embedding as a side-effect
typedef std::vector< graph_traits<graph_type>::edge_descriptor > vec_t;
std::vector<vec_t> embedding(num_vertices(g));
std::cout << num_vertices(g) << std::endl;
//if you use the parameter "kuratowski_subgraph" you'll need to pass also my_edge_index_map
if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
boyer_myrvold_params::embedding =
&embedding[0]
)
)
std::cout << "Input graph is planar" << std::endl;
else
std::cout << "Input graph is not planar" << std::endl;
std::cout << std::endl << "Vertices on the faces: " << std::endl;
vertex_output_visitor v_vis(g);
planar_face_traversal(g, &embedding[0], v_vis, my_edge_index_map);
std::cout << std::endl << "Edges on the faces: " << std::endl;
edge_output_visitor e_vis(g);
planar_face_traversal(g, &embedding[0], e_vis, my_edge_index_map);
return 0;
}