简体   繁体   中英

What is a Simple Example for using the Boost Graph Library

I am trying to use theBGL , I find the documentation precise but lacks more examples for simple cases. My goal is described below (after reading the documentation I still couldn't do this):

struct Vertex
{
    double m_d;
    std::size_t m_id;
};

//or

struct Vertex
{
    double m_d;
    std::size_t id() const;
};

Goals :

  1. A directed graph G (what is the difference between a bidirectional and directed other than in_edges please?)
  2. G can hold the vertex type Vertex.
  3. get the vertex by id from G and change the value m_d in the Vertex struct when I want.
  4. add, remove verticies and edges between verticies and also supports costs ie cost(edge).

Could you please write me an example on how to do this with BGL please? I beleive I need MutableBidirectionalGraph ?

  1. A directed graph G

    Straight-away:

     struct Vertex { double m_d = 0; size_t m_id = -1; // or std::size_t id() const; }; struct Edge { double cost = 0; }; using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Vertex, Edge>;

    (what is the difference between a bidirectional and directed other than in_edges please?)

    There is no other difference, except of course the complexity guarantees for enumerating incoming edges, and a linear overhead upon insertion of edges

  2. G can hold the vertex type Vertex .

    See 0.

  3. get the vertex by id from G

     auto find_by_id = [&g](size_t id) -> Vertex& { auto vv = boost::make_iterator_range(vertices(g)); auto vd = find_if(vv, [&, id](auto vd) { return g[vd].m_id == id; }); return g[*vd]; };

    and change the value m_d in the Vertex struct when I want.

     if (i_want()) { g[vd].m_id += 1; }

    Or,

     auto idmap = boost::get(&Vertex::m_id, g); if (i_want()) { idmap[vd] += 1; }

    or even

    put(idmap, vd, 42);

    or even more unmarked:

     get(boost::vertex_bundle, g, vd).m_id = 999;
  4. add, remove vertices

     remove_vertex(vd, g);

    and edges between vertices

     clear_vertex(vd, g);

    and also supports costs ie cost(edge).

    Wow that really has nothing to do with any of the above. But it's really the same as with vertex ids:

     if (i_want()) { g[ed].cost = new_cost; }

    Or,

     auto cost = boost::get(&Edge::cost, g); if (i_want()) { cost[ed] = new_cost; }

    or even

    put(cost, ed, new_cost);

    or even more unmarked:

     get(boost::edge_bundle, g, ed).cost = new_cost;

Live Demo

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>

struct Vertex {
    double m_d  = 0;
    size_t m_id = -1;
    // or std::size_t id() const;
};

struct Edge {
    double cost = 0;
};

using Graph =
    boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Vertex, Edge>;

using boost::make_iterator_range;

int main(){
    Graph g;
    auto v0 = add_vertex({0.1, 100}, g);
    auto v1 = add_vertex({0.2, 200}, g);
    auto v2 = add_vertex({0.3, 300}, g);
    auto v3 = add_vertex({0.4, 400}, g);
    auto v4 = add_vertex({0.5, 500}, g);
    auto v5 = add_vertex({0.6, 600}, g);

    add_edge(v0, v2, Edge{1.5}, g);
    add_edge(v1, v3, Edge{2.5}, g);
    add_edge(v4, v1, Edge{3.5}, g);
    add_edge(v2, v5, Edge{4.5}, g);

    auto idmap = boost::get(&Vertex::m_id, g);
    auto cost  = boost::get(&Edge::cost, g);

    auto find_by_id = [&g](size_t id) -> Vertex& {
        auto vv = boost::make_iterator_range(vertices(g));
        auto vd = find_if(vv, [&, id](auto vd) { return g[vd].m_id == id; });
        return g[*vd];
    };

    print_graph(g, idmap, std::cout << "original: ");

    auto i_want = [](auto vd) {
        return (vd % 2); // when I want
    };

    for (auto vd : make_iterator_range(vertices(g))) {
        if (i_want(vd))
            g[vd].m_id += 1;
        if (i_want(vd))
            idmap[vd] += 1;
        //put(idmap, vd, 42);
        //get(boost::vertex_bundle, g, vd).m_id = 999;
    }

    print_graph(g, idmap, std::cout << "altered: ");

    clear_vertex(v3, g);
    remove_vertex(v3, g); // undefined behaviour unless edges cleared

    print_graph(g, idmap, std::cout << "removed: ");

    for (auto ed : make_iterator_range(edges(g))) {
        std::cout << ed << " cost " << cost[ed] << "\n";
    }

    for (auto ed : make_iterator_range(edges(g))) {
        cost[ed] *= 111;
    }

    for (auto ed : make_iterator_range(edges(g))) {
        std::cout << ed << " cost " << cost[ed] << "\n";
    }
};

Prints

original: 100 --> 300 
200 --> 400 
300 --> 600 
400 --> 
500 --> 200 
600 --> 
altered: 100 --> 300 
202 --> 402 
300 --> 602 
402 --> 
500 --> 202 
602 --> 
removed: 100 --> 300 
202 --> 
300 --> 602 
500 --> 202 
602 --> 
(0,2) cost 1.5
(3,1) cost 3.5
(2,4) cost 4.5
(0,2) cost 166.5
(3,1) cost 388.5
(2,4) cost 499.5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM