Modifying vertex properties in a Boost::Graph

前端 未结 5 1884
执念已碎
执念已碎 2020-12-04 09:40

I am trying to figure out how to use boost::graph to store some information. However, there is information I want tied to each vertex. Staring at the documentation for the l

5条回答
  •  盖世英雄少女心
    2020-12-04 09:48

    I don't like the nested-template property approach of boost::graph, so I wrote a small wrapper around everything, that basically allows to put any struct/class as a vertex/edge property. One can access properties accessing the struct members.

    To keep it flexible these structs are defined as template parameter.

    Here the Code:

    /* definition of basic boost::graph properties */
    enum vertex_properties_t { vertex_properties };
    enum edge_properties_t { edge_properties };
    namespace boost {
        BOOST_INSTALL_PROPERTY(vertex, properties);
        BOOST_INSTALL_PROPERTY(edge, properties);
    }
    
    
    /* the graph base class template */
    template < typename VERTEXPROPERTIES, typename EDGEPROPERTIES >
    class Graph
    {
    public:
    
        /* an adjacency_list like we need it */
        typedef adjacency_list<
            setS, // disallow parallel edges
            listS, // vertex container
            bidirectionalS, // directed graph
            property,
            property
        > GraphContainer;
    
    
        /* a bunch of graph-specific typedefs */
        typedef typename graph_traits::vertex_descriptor Vertex;
        typedef typename graph_traits::edge_descriptor Edge;
        typedef std::pair EdgePair;
    
        typedef typename graph_traits::vertex_iterator vertex_iter;
        typedef typename graph_traits::edge_iterator edge_iter;
        typedef typename graph_traits::adjacency_iterator adjacency_iter;
        typedef typename graph_traits::out_edge_iterator out_edge_iter;
    
        typedef typename graph_traits::degree_size_type degree_t;
    
        typedef std::pair adjacency_vertex_range_t;
        typedef std::pair out_edge_range_t;
        typedef std::pair vertex_range_t;
        typedef std::pair edge_range_t;
    
    
        /* constructors etc. */
        Graph()
        {}
    
        Graph(const Graph& g) :
            graph(g.graph)
        {}
    
        virtual ~Graph()
        {}
    
    
        /* structure modification methods */
        void Clear()
        {
            graph.clear();
        }
    
        Vertex AddVertex(const VERTEXPROPERTIES& prop)
        {
            Vertex v = add_vertex(graph);
            properties(v) = prop;
            return v;
        }
    
        void RemoveVertex(const Vertex& v)
        {
            clear_vertex(v, graph);
            remove_vertex(v, graph);
        }
    
        EdgePair AddEdge(const Vertex& v1, const Vertex& v2, const EDGEPROPERTIES& prop_12, const EDGEPROPERTIES& prop_21)
        {
            /* TODO: maybe one wants to check if this edge could be inserted */
            Edge addedEdge1 = add_edge(v1, v2, graph).first;
            Edge addedEdge2 = add_edge(v2, v1, graph).first;
    
            properties(addedEdge1) = prop_12;
            properties(addedEdge2) = prop_21;
    
            return EdgePair(addedEdge1, addedEdge2);
        }
    
    
        /* property access */
        VERTEXPROPERTIES& properties(const Vertex& v)
        {
            typename property_map::type param = get(vertex_properties, graph);
            return param[v];
        }
    
        const VERTEXPROPERTIES& properties(const Vertex& v) const
        {
            typename property_map::const_type param = get(vertex_properties, graph);
            return param[v];
        }
    
        EDGEPROPERTIES& properties(const Edge& v)
        {
            typename property_map::type param = get(edge_properties, graph);
            return param[v];
        }
    
        const EDGEPROPERTIES& properties(const Edge& v) const
        {
            typename property_map::const_type param = get(edge_properties, graph);
            return param[v];
        }
    
    
        /* selectors and properties */
        const GraphContainer& getGraph() const
        {
            return graph;
        }
    
        vertex_range_t getVertices() const
        {
            return vertices(graph);
        }
    
        adjacency_vertex_range_t getAdjacentVertices(const Vertex& v) const
        {
            return adjacent_vertices(v, graph);
        }
    
        int getVertexCount() const
        {
            return num_vertices(graph);
        }
    
        int getVertexDegree(const Vertex& v) const
        {
            return out_degree(v, graph);
        }
    
    
        /* operators */
        Graph& operator=(const Graph &rhs)
        {
            graph = rhs.graph;
            return *this;
        }
    
    protected:
        GraphContainer graph;
    };
    

    Using this you can access properties like this:

    struct VertexProperties {
        int i;
    };
    
    struct EdgeProperties {
    };
    
    typedef Graph MyGraph;
    
    MyGraph g;
    
    VertexProperties vp;
    vp.i = 42;
    
    MyGraph::Vertex v = g.AddVertex(vp);
    
    g.properties(v).i = 23;
    

    Of course you may have other needs for your graph's structure, but modification of the code above should be pretty easy.

提交回复
热议问题