您的位置:首页 > 其它

Learning about boost libary---boost库学习

2015-07-17 22:05 435 查看
<span style="font-family: Arial, Helvetica, sans-serif;">最近工作上使用到boost库相关的工具类以及函数,因此有了下边这个博客,一个人的学习过程一定是借鉴他人的已有成果,</span>

因此,在本博客中引用的内容和代码就不具名出处,但是一定感谢背后人的付出。

boost库的相关安装

直接百度下载,解压到任意路径

假设解压目录为D:\software\boost_1_58_0

在vs2012的项目工程右键,选择属性,

选中左边的VC++ Directories选项,

在Include Directories选项,编辑,将上述的解压目录添加进来即可。

添加目录添加到父目录D:\software\boost_1_58_0即可。


1. boost图算法相关

        图相关的理论和算法是经典数据结构的一部分,但是本部分内容不会涉及图所有相关的算法,不如最短路径等,

    毕竟我也是一个新手,没有那么高的水平。因此本篇文章只能起到入门的作用,甚至只是起到稍微了解的地步,废话

    不多说了开始正文部分。
    本部分引入的头文件

<pre name="code" class="cpp">#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <fstream>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
using namespace boost;

/*below is one function object, which used to iter the graph by the vertex*/
template <class Graph>
class exercise_vertex
{
public:
/*here define the 顶点描述符,是对应的顶点迭代器解引用之后的类型

*/
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
exercise_vertex(Graph& g_) : g(g_) {}
Graph& g;
public:
void operator()(const Vertex & v) const
{
typedef typename graph_traits<Graph> GraphTraits;
/*主函数有一定的说明*/
typename property_map<Graph, vertex_index_t>::type index = get(vertex_index, g);
std::cout << "Deal with the " << index[v] << " vertex" << std::endl;
/*迭代所有从本端点出去的边, 其迭代器的解引用是对应的边描述符edge_descriptor*/
std::cout << "first way out-edges: ";
typename GraphTraits::out_edge_iterator out_i, out_end;
typename GraphTraits::edge_descriptor e;
/*
out_edges函数除了可以使用顶点描述符作为参数之外,也可以使用顶点的类型作为参数,
也有可能这两者是同一种类型,因为这是boost根据图自行推导的数据类型。
如out_edges(0, g);or out_edges(A, g); //A is enum
*/
for (tie(out_i, out_end) = out_edges(v, g); out_i != out_end; ++out_i)
{
e = *out_i;
/*source函数获取对应边的源头断点描述符,target函数获取对应边的目的断点描述符*/
Vertex src = source(e, g), targ = target(e, g);
std::cout << "(" << index[src] << "," << index[targ] << ") ";
}
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
std::cout << "second way out-edges: ";
/*this method used c++11*/
for (auto const& e : boost::make_iterator_range(boost::out_edges(v, g)))
{
Vertex src = source(e, g), targ = target(e, g);
std::cout << "(" << index[src] << "," << index[targ] << ") ";
}
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
/*迭代所有从本端点进来的边, 其迭代器的解引用是对应的边描述符edge_descriptor*/
std::cout << "first way in-edges: ";
//typedef typename graph_traits<Graph> GraphTraits;
typename GraphTraits::in_edge_iterator in_i, in_end;
for (tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
{
e = *in_i;
Vertex src = source(e, g), targ = target(e, g);
std::cout << "(" << index[src] << "," << index[targ] << ") ";
}
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
std::cout << "first way in-edges: ";
/*this method used c++11*/
for (auto const& e : boost::make_iterator_range(boost::in_edges(v, g)))
{
Vertex src = source(e, g), targ = target(e, g);
std::cout << "(" << index[src] << "," << index[targ] << ") ";
}
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
/*相邻节点的查找*/
std::cout << "first way adjacent vertices: ";
typename graph_traits<Graph>::adjacency_iterator ai;
typename graph_traits<Graph>::adjacency_iterator ai_end;
/*tie函数实现的功能是将adjacent_vertices返回的pair对象分别赋值到ai, ai_end*/
for (tie(ai, ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai)
std::cout << index[*ai] << " ";
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
/*相邻节点的查找*/
std::cout << "second way adjacent vertices: ";
/*tie函数实现的功能是将adjacent_vertices返回的pair对象分别赋值到ai, ai_end*/
for (auto const& e : boost::make_iterator_range(adjacent_vertices(v, g)))
std::cout << index[e] << " ";
std::cout << std::endl;
std::cout << "------------------------------------------------" << std::endl;
}
};

/*This function are quoted from boost document*/
int test()
{
/*建立有权重的图*/
typedef adjacency_list < listS, vecS, directedS,
no_property, property < edge_weight_t, int > > graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
typedef std::pair<int, int> Edge;

const int num_nodes = 5;
enum nodes { A, B, C, D, E };
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
/*带有权重的图构建*/
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
property_map<graph_t, edge_weight_t>::type weightmap = get(edge_weight, g);
std::vector<vertex_descriptor> p(num_vertices(g));
std::vector<int> d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
dijkstra_shortest_paths(g, s, predecessor_map(&p[0]).distance_map(&d[0]));

std::cout << "distances and parents:" << std::endl;
graph_traits < graph_t >::vertex_iterator vi, vend;
for (tie(vi, vend) = vertices(g); vi != vend; ++vi) {
std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
endl;
}
std::cout << std::endl;

std::ofstream dot_file("dijkstra-eg.dot");

dot_file << "digraph D {\n"
<< " rankdir=LR\n"
<< " size=\"4,3\"\n"
<< " ratio=\"fill\"\n"
<< " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";

graph_traits < graph_t >::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
graph_traits < graph_t >::edge_descriptor e = *ei;
graph_traits < graph_t >::vertex_descriptor
u = source(e, g), v = target(e, g);
dot_file << name[u] << " -> " << name[v]
<< "[label=\"" << get(weightmap, e) << "\"";
if (p[v] == u)
dot_file << ", color=\"black\"";
else
dot_file << ", color=\"grey\"";
dot_file << "]";
}
dot_file << "}";
dot_file.close();
return EXIT_SUCCESS;
}
typedef struct device_s{
int a;
int b;
void toString(){
std::cout << a << "," << b << std::endl;
}
}device_s;

typedef struct connection_s{
int a;
int b;
}connection_s;
void test1(){

typedef boost::adjacency_list<
boost::vecS //OutEdgeList
, boost::vecS //VertexList
, boost::undirectedS
, device_s //VertexProperties
, connection_s //EdgeProperties
> graph_t;
enum device_e{
A,
B,
C,
D,
E
};
graph_t a(5);
a[A].toString();
device_e m2 = A;

}

int main()
{
/*adjacency_list邻接表有五个模板形参,
第一个表示存储从图的顶点出去边的集合类型
第二个参数表示存储顶点的集合类型
第三个参数表示图的类型,有向图或者无向图等
第四个参数表示图的顶点所对应的特定类结构,可以不提供
第五个参数表示图的边所对应的特定类结构,可以不提供
*/
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
// Make convenient labels for the vertices
enum { A, B, C, D, E, N }; //代表 0 ,1,2,3,4 顶点,使用枚举来表示图中的顶点
const int num_vertices = N;
//图中的边,使用标准库的pair结构存储
typedef std::pair<int, int> Edge;
/*
即 a->b, a->d, c->a etc.
*/
Edge edge_array[] = { Edge(A, B), Edge(A, D), Edge(C, A), Edge(D, C),
Edge(C, E), Edge(B, D), Edge(D, E) };
const int num_edges = sizeof(edge_array) / sizeof(edge_array[0]);
// 创建一个拥有5个顶点的图对象,constructed with the vertex number;
Graph g(num_vertices);
// 给图对象添加边
for (int i = 0; i < num_edges; ++i)
add_edge(edge_array[i].first, edge_array[i].second, g);

typedef property_map<Graph, vertex_index_t>::type IndexMap;
/*with this property_map can iter the graph*/
IndexMap index = get(vertex_index, g);
/*使用boost库中的vertices的函数遍历图中的顶点,返回值是包含开始和结束迭代器的pair,
迭代器的解引用是对应的顶点描述符,在后边会论述。
*/
std::cout << "vertices(g) = ";
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
std::pair<vertex_iter, vertex_iter> vp;
for (vp = vertices(g); vp.first != vp.second; ++vp.first)
std::cout << index[*vp.first] << " ";
std::cout << std::endl;
/*使用boost库中的edges的函数遍历图中的顶点,返回值是包含开始和结束迭代器的pair
迭代器的解引用是对应的边描述符,在后边会论述。
*/
std::cout << "edges(g) = ";
graph_traits<Graph>::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
std::cout << "(" << index[source(*ei, g)] << "," << index[target(*ei, g)] << ") ";
std::cout << std::endl;

/*可以使用标准库中的算法,操作图数据结构,我们定义exercise_vertex函数对象来处理*/
std::cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
std::for_each(vertices(g).first, vertices(g).second, exercise_vertex<Graph>(g));
std::cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;

test();
test1();
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vs2012 boost