boost graph lib记录

boost graph lib记录

	简单记录一下BGL库的使用

1 BGL库的数据结构

​ BGL有三种数据结构:

​ The BGL currently provides two graph classes and an edge list adaptor:

一般只用邻接表

1.1 邻接表

​ 如何使用 adjacency_list class 的教程在这:Using adjacency_list.

​ 创建一个邻接表需要使用类模板:

adjacency_list<OutEdgeList, VertexList, Directed,
               VertexProperties, EdgeProperties,
               GraphProperties, EdgeList>
ParameterDescriptionDefault
OutEdgeListThe selector for the container used to represent the edge-list for each of the vertices.vecS
VertexListThe selector for the container used to represent the vertex-list of the graph.vecS
DirectedA selector to choose whether the graph is directed, undirected, or directed with bidirectional edge access (access to both out-edges and in-edges). The options are directedS, undirectedS, and bidirectionalS.directedS
VertexPropertiesfor specifying internal property storage.no_property
EdgePropertiesfor specifying internal property storage.no_property
GraphPropertiesfor specifying property storage for the graph object.no_property
EdgeListThe selector for the container used to represent the edge-list for the graph.listS

(1)OutEdgeList和VertexList

​ OutEdgeList和VertexList,它们控制用于表示图形的底层数据结构(使用std的vector,list之类)。OutEdgeList和VertexList的选择会影响图形操作的时间复杂度和空间复杂度。

  • vecS selects std::vector.
  • listS selects std::list.
  • slistS selects std::slist.
  • setS selects std::set.
  • multisetS selects std::multiset.
  • hash_setS selects boost::unordered_set.

​ 通常,如果需要快速添加和删除顶点,列表是一个不错的选择。与选择vec相比,这样做的代价是额外的空间开销。

​ Directed有directedS, undirectedS, and bidirectionalS几个选项。这区分了无向图(undirectedS)和有向图(bidirectionalS,directedS),其中bidirectionalS可以调用in_edges(),out_edges()函数。

(2)Internal Properties

​ 属性表示了图中顶点和边的属性,BGL中建议使用捆绑属性 bundled properties

​ 以城市(顶点)与路网(边)的关系为例子,可以给点和边定义属性,如何定义BGL中的图:

struct City
{
  string name;
  int population;
  vector<int> zipcodes;
};

struct Highway
{
  string name;
  double miles;
  int speed_limit;
  int lanes;
  bool divided;
};

typedef boost::adjacency_list<
    boost::listS, boost::vecS, boost::bidirectionalS,
    City, Highway>
  Map;

​ 访问图中顶点和边的方式如下:

Map map; // load the map
Map::vertex_descriptor v = *vertices(map).first;
map[v].name = "Troy";
map[v].population = 49170;
map[v].zipcodes.push_back(12180);
Map::edge_descriptor e = *out_edges(v, map).first;
map[e].name = "I-87";
map[e].miles = 10.;
map[e].speed_limit = 65;
map[e].lanes = 4;
map[e].divided = true;

**(3)稳定性 **

​ 某些操作会导致顶点或边的描述符无效,需要注意。

​ Some care must be taken when changing the structure of a graph (via adding or removing edges). Depending on the type of adjac

ency_list and on the operation, some of the iterator or descriptor objects that point into the graph may become invalid.

​ In general, if you want your vertex and edge descriptors to be stable (never invalidated) then use listS or setS for the VertexList and OutEdgeList template parameters of adjacency_list. If you are not as concerned about descriptor and iterator stability, and are more concerned about memory consumption and graph traversal speed, use vecS for the VertexList and/or OutEdgeList template parameters.

Table: Summary of Descriptor and Iterator Invalidation.

FunctionVertex DescEdge DescVertex IterEdge IterAdj Iter
add_edge()OKOKOKEL=vecS &&Directed=directedSEL=vecS
remove_edge() remove_edge_if() remove_out_edge_if() remove_in_edge_if() clear_vertex()OKOKOKEL=vecS &&Directed=directedSEL=vecS
add_vertex()OKOKOKVL=vecS &&Directed=directedSVL=vecS &&Directed=directedS
remove_vertex()VL=vecSVL=vecSVL=vecSVL=vecSVL=vecS

代码

由于资料不够清楚且例子较少,BGL实在是不好用,vertex设置为listS时无法得知怎么设置 boost::make_iterator_property_map,只能设置为vector。

“pathMap.h”

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/properties.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/named_function_params.hpp>

#include <iostream>
#include <vector>
#include <utility>                   // for std::pair
#include <algorithm>                 // for std::for_each
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>


struct VertexData
{
  std::string first_name;
  int num;
};

struct EdgeData
{
  std::string edge_name;
  double dist;
};

namespace pathPlan {

  struct vertexData {

      std::string name;
      bool omni;
      float x;
      float y;
      float theta;
  };

  struct edgeData {
      bool omni;
      float weight;
      float theta;
      std::string right_node, left_node;
  };


  typedef boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, 
    vertexData,  edgeData > pathGraph;
  typedef boost::graph_traits<pathGraph>::vertex_descriptor path_vertex_descriptor;
  typedef boost::graph_traits<pathGraph>::edge_descriptor path_edge_descriptor;

  class graphPath {

  public:
    std::string path_id;
    pathGraph pathG;
    std::map<std::string,vertexData> all_vertex;
    std::vector<edgeData> all_edge;

    graphPath(const std::map<std::string,vertexData> &all_vertex1, const std::vector<edgeData> &all_edge1);
    // get shortest path
    bool getShortestPath( std::string start_name, std::string end_name, std::vector<std::string> &path );

  private:
    std::map< std::string, path_vertex_descriptor> vertexID2descriptor;
    // generate graph
    bool generate_graph();
  };
void input_data( std::map<std::string,vertexData> &all_vertex, std::vector<edgeData> &all_edge );

}


“pathMap.cpp”

#include "pathMap.h"
#include <iostream>

using namespace pathPlan;
using namespace boost;



graphPath::graphPath(const std::map<std::string, vertexData> &all_vertex1, const std::vector<edgeData> &all_edge1) :
        all_vertex(all_vertex1), all_edge(all_edge1) {
    // check input

    // generate
    generate_graph();
}

bool graphPath::generate_graph() {
    std::map<std::string, vertexData>::iterator iter;
    // add vertex
    for (iter = all_vertex.begin(); iter != all_vertex.end(); ++iter) {
        path_vertex_descriptor ds = boost::add_vertex(iter->second, pathG);
        vertexID2descriptor.insert(std::make_pair(iter->second.name, ds));

        std::cout << " name =  " << iter->second.name << " descri = " << ds << std::endl;
    }
    // add edge
    std::vector<edgeData>::iterator iter2;
    for (iter2 = all_edge.begin(); iter2 != all_edge.end(); ++iter2) {
        boost::add_edge(vertexID2descriptor[iter2->left_node], vertexID2descriptor[iter2->right_node], *iter2, pathG);
    }
    //
    std::cout << " size edge =  " << boost::num_edges(pathG) << std::endl;
    std::cout << " size vertex =  " << boost::num_vertices(pathG) << std::endl;

    return true;
}

bool graphPath::getShortestPath(std::string start_name, std::string end_name, std::vector<std::string> &path) {

    path_vertex_descriptor R, L;
    L = vertexID2descriptor[start_name];
    R = vertexID2descriptor[end_name];

    pathGraph pathG1;

    std::vector<path_vertex_descriptor> p(num_vertices(pathG));
    std::vector<path_edge_descriptor> q(num_vertices(pathG));
    std::vector<float> d(num_vertices(pathG));
    auto distance_iterator = boost::make_iterator_property_map(d.begin(), boost::get(boost::vertex_index, pathG));
    boost::dijkstra_shortest_paths(pathG, L, predecessor_map(&p[0]).
            weight_map(boost::get(&edgeData::weight, pathG)).
            distance_map(distance_iterator));

    std::cout << " d size =  " << d.size() << std::endl;
    graph_traits<pathGraph>::vertex_iterator vi, vend;
    for (boost::tie(vi, vend) = boost::vertices(pathG); vi != vend; ++vi) {
        std::cout << "distance(" << pathG[*vi].name << ") = " << d[*vi] << ", ";
        std::cout << "parent(" << pathG[*vi].name << ") = " << pathG[p[*vi]].name << std::endl;
    }

    /*
    path_vertex_descriptor vi,vend;
    for (boost::tie(vi, vend) = boost::vertices(pathG); vi != vend; vi++ ) {
      std::cout<<" d "<< vi<<" = "<< d[vi] << "  , "<<p[vi] << std::endl ;
    }
    */

    /*
    
      std::vector<float> distances(boost::num_vertices(g));
      auto weight_map=boost::weight_map(boost::get(&udi::TopoEdgeProperty::weight ,g));
      auto index_map = boost::get(boost::vertex_index, g);
      std::vector<VertexDescriptor > predecessor_map(num_vertices(g));
      auto distance_iterator = boost::make_iterator_property_map(distances.begin() ,       boost::get(boost::vertex_index , g));
      
    ​
      boost::dijkstra_shortest_paths(g, source,
                                     weight_map.
                                         distance_map(distance_iterator).
                                         predecessor_map(&predecessor_map[0]));
    */

}


void pathPlan::input_data(std::map<std::string, vertexData> &all_vertex, std::vector<edgeData> &all_edge) {
    all_vertex.clear();
    all_edge.clear();
    vertexData v;
    for (int i = 0; i < 12; ++i) {
        v.name = std::to_string(i);
        v.omni = false;
        v.theta = 0;
        v.x = 0.5 * i;
        v.y = i;
        all_vertex.insert(std::make_pair(v.name, v));
    }
    edgeData e;
    for (int i = 0; i < 10; ++i) {
        e.theta = 0;
        e.left_node = std::to_string(i);
        e.right_node = std::to_string(i + 1);
        e.omni = false;
        e.weight = 1;
        all_edge.push_back(e);
    }
}


int
main(int, char *[])
{
  std::map<std::string,vertexData> all_vertex;
  std::vector<edgeData> all_edge;
  input_data( all_vertex, all_edge );
  graphPath pG(all_vertex, all_edge);
  std::vector<std::string> path;
  pG.getShortestPath( "1", "4", path);

}


cmakelists

cmake_minimum_required (VERSION 2.9)
project (test)

find_package(Boost COMPONENTS regex system REQUIRED)

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
)

#add_executable(test src/pathMap.cpp)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值