簡體   English   中英

如何使用Boost Graph Library將對象附加到圖形的節點和邊緣?

[英]How do I attach objects to the nodes and edges of a graph using the Boost Graph Library?

我想通過將正確封裝的類附加到圖形節點和邊上來更有效地使用Boost Graph Library。 我對附加int或POD結構不感興趣。 根據其他StackOverFlow文章的建議,我開發了以下示例應用程序。 有人能告訴我我需要撒在EdgeInfo類上的魔力才能使它編譯嗎?

我將Visual Studio 2010與Boost 1.54.0一起使用。

//------------------------------------------------------------------------
#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));
}
//------------------------------------------------------------------------

當我運行您的代碼時,由於dijkstra中的距離圖導致了numeric_limits錯誤。

“錯誤1錯誤C2440:”:無法從'int'轉換為'D'c:\\ Program Files(x86)\\ Microsoft Visual Studio 10.0 \\ VC \\ include \\ limits 92“可能來自http:// www的這一部分.boost.org / DOC /庫/ 1_55_0 /升壓/圖形/ 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)());

我認為,為節點和邊緣綁定真實類可能是一種更簡單的方法。 創建值得提供大多數提升算法所需的所有必需的標記屬性(索引,權重,顏色等)的頂點和邊屬性類,比其價值更大。

不要忘記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,這意味着向量和邊均以固定順序存儲為向量。

您可能只有一個類,用於存儲Edge和Vertex類以及指向該圖的頂點映射或邊緣映射的指針。

我不知道您對這個項目的目標,但是與在幕后管理所有這些增強功能相比,我肯定有更高層次的課程。 意味着將類存儲在具有索引查找的向量中,對於希望使用漂亮的圖類的應用程序將被隱藏和封裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM