gpt4 book ai didi

c++ - 如何使用 Boost Graph Library 将对象附加到图形的节点和边缘?

转载 作者:太空宇宙 更新时间:2023-11-04 13:53:32 26 4
gpt4 key购买 nike

我想通过将正确封装的类附加到图形节点和边来更有效地使用 Boost 图形库。我对附加 int 或 POD 结构不感兴趣。根据对其他 StackOverFlow 文章的建议,我开发了以下示例应用程序。任何人都可以告诉我我需要在 EdgeInfo 类上施展魔法才能使它编译吗?

我正在使用带有 Boost 1.54.0 的 Visual Studio 2010。

//------------------------------------------------------------------------
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <iostream>
//------------------------------------------------------------------------
struct VertexInfo
{
struct Tag
{
typedef boost::vertex_property_tag kind;
static std::size_t const num; // ???
};
typedef boost::property<Tag, VertexInfo> Property;
};
std::size_t const VertexInfo::Tag::num = reinterpret_cast<std::size_t> (&VertexInfo::Tag::num);
//------------------------------------------------------------------------
class EdgeInfo
{
int _nWeight;
public:
int getWeight () const {return _nWeight;}
struct Tag
{
typedef boost::edge_property_tag kind;
static std::size_t const num; // ???
};
typedef boost::property<boost::edge_weight_t, int> Weight;
typedef boost::property<Tag, EdgeInfo> Property;
EdgeInfo (int nWeight = 9999) : _nWeight (nWeight) {}
};
std::size_t const EdgeInfo::Tag::num = reinterpret_cast<std::size_t> (&EdgeInfo::Tag::num);
//------------------------------------------------------------------------
typedef boost::property<boost::edge_weight_t, int> EdgeProperty;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexInfo::Property, EdgeProperty> GraphWorking;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexInfo::Property, EdgeInfo::Property> GraphBroken;
//------------------------------------------------------------------------
template<typename GraphType, typename EdgeType> void
dijkstra (GraphType g, EdgeType e)
{
typedef boost::graph_traits<GraphType>::vertex_descriptor VertexDesc;
typedef boost::graph_traits<GraphType>::edge_descriptor EdgeDesc;

VertexDesc u = add_vertex (g);
VertexDesc v = add_vertex (g);
std::pair<EdgeDesc, bool> result = add_edge (u, v, e, g);
std::vector<VertexDesc> vecParent (num_vertices (g), 0);

dijkstra_shortest_paths (g, u, boost::predecessor_map (&vecParent[0]));
}
//------------------------------------------------------------------------
int
main (int argc, char** argv)
{
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
std::cout << "Buy a new compiler\n";
#else
std::cout << "Your compiler is fine\n";
#endif
GraphWorking gWorking;
GraphBroken gBroken;

dijkstra (gWorking, 3);
dijkstra (gBroken, EdgeInfo (4));
}
//------------------------------------------------------------------------

最佳答案

当我运行您的代码时,我在 numeric_limits 中收到错误,这是由 dijkstra 中的距离图引起的。

"错误 1 ​​error C2440: '' : 无法从 'int' 转换为 'D' c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\limits 92“可能来自 http://www.boost.org/doc/libs/1_55_0/boost/graph/dijkstra_shortest_paths.hpp 的这一部分

 typedef typename property_traits<DistanceMap>::value_type D;
D inf = choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)());

我认为可能有一种更简单的方法可以为您的节点和边缘绑定(bind)一个真实的类。创建顶点和边属性类将提供大多数 boost 算法所需的所有必需的标记属性(索引、权重、颜色等),这比它的值(value)更麻烦。

不要忘记 Edge 类!= Edge 属性。

边缘类实际上是 graph_traits::edge_discriptor。

属性是与每条边关联的数据。顶点相同。

我会使用捆绑属性并在每个属性中添加一个指向您的类的指针。

举个例子

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/property_map/property_map.hpp>
#include <iostream>

//Fancy Edge class
class EdgeData
{
int _data;
public:
EdgeData(){
_data=0;
}

EdgeData(int data){
_data= data;
}

void printHello(){
std::cout << "hello " << _data << std::endl;
}


};


//Fancy Vert class
class VertexData
{
int _data;
public:
VertexData(){
_data=0;
}

VertexData(int data){
_data= data;
}

void printHello(){
std::cout << "hello " << _data << std::endl;
}


};

//bundled properties
struct VertexProps
{
VertexData* data;
};

struct EdgeProps
{
size_t weight;
EdgeData* data;
};


//Graph
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
VertexProps,EdgeProps> Graph;

//helpers
//Vertex
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
//Edge
typedef boost::graph_traits<Graph>::edge_descriptor Edge;



//------------------------------------------------------------------------
template<typename GraphType> void
templateFunction (GraphType g)
{
typedef boost::graph_traits<GraphType>::edge_iterator edge_iter;
std::pair<edge_iter, edge_iter> ep;
edge_iter ei, ei_end;
ep = edges(g);
ei_end = ep.second;

for (ei = ep.first; ei != ei_end; ++ei){
g[*ei].data->printHello();
}

}

//if you want to alter the graph use referenced &graph
template<typename GraphType,typename EdgePropType> void
templateFuctionProps(GraphType &g, EdgePropType e)
{
typedef boost::graph_traits<GraphType>::vertex_descriptor VertexDesc;

VertexDesc v = add_vertex(g);
VertexDesc u = add_vertex(g);

//add an edge with the Edge property
add_edge(v,u,e,g);
}
//------------------------------------------------------------------------
int
main (int argc, char** argv)
{
Graph g;

//vertex holder
std::vector<Vertex> verts;

//add some verts
for(size_t i = 0; i < 5; ++i){
Vertex v = add_vertex(g);
g[v].data = new VertexData(i%2);
verts.push_back(v);
}

//add some edges
for(size_t i = 0; i < 4; ++i){
std::pair<Edge,bool> p = add_edge(verts.at(i),verts.at(i+1),g);
Edge e = p.first;
g[e].data = new EdgeData(i%3);
g[e].weight = 5;
}

//iterate edges and call a class function
typedef boost::graph_traits<Graph>::edge_iterator edge_iter;
std::pair<edge_iter, edge_iter> ep;
edge_iter ei, ei_end;
ep = edges(g);
ei_end = ep.second;
for (ei = ep.first; ei != ei_end; ++ei){
g[*ei].data->printHello();
}


std::cout << "Iterate with template with template " << std::endl;
templateFunction(g);


//Use an edge property in a function
EdgeProps edgeProp;
edgeProp.weight = 5;
edgeProp.data = new EdgeData(150);
std::cout << "Modity graph with template function " << std::endl;
templateFuctionProps(g,edgeProp);

std::cout << "Iterate again with template" << std::endl;
templateFunction(g);

//getting the weight property
boost::property_map<Graph,size_t EdgeProps::*>::type w
= get(&EdgeProps::weight, g);


std::cout << "Print weights" << std::endl;
ep = edges(g);
ei_end = ep.second;
for (ei = ep.first; ei != ei_end; ++ei){
std::cout << w[*ei] << std::endl;
}

std::cin.get();
}
//------------------------------------------------------------------------

我还看到您正在使用 vecS,这意味着 vector 和边都存储为具有固定顺序的 vector 。

您可以只使用一个类来存储您的 Edge 和 Vertex 类,并带有指向图形的顶点图或边图的指针。

我不知道您对该项目的目标,但我肯定会开设更高级别的类(class),而不是在幕后管理所有这些 boost 内容。这意味着将类存储在一个带有索引查找的 vector 中将被隐藏并封装在想要使用你的漂亮图形类的应用程序中。

关于c++ - 如何使用 Boost Graph Library 将对象附加到图形的节点和边缘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22546588/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com