图graph

BGL有3种保存图的数据结构,分别是adjacency_list,adjacency_matrixCSR(compressed_sparse_row_graph)就是中文对应的我觉得是前向星。我觉得CSR挺垃圾的(黑一波),所以尽量不要使用(而且是不是可变图Mutable Graph,太垃圾了!)。

这里主要介绍adjacency_list的使用。adjacency_list的定义有若干个参数

boost::adjacency_list<     boost::listS,          // 出边的数据类型boost::vecS,           // 保存顶点的数据类型boost::undirectedS,    // 边的类型(单向、双向等)boost::no_property,    // 顶点的其他特性(权重,或者ID之类)boost::no_property,    // 边的其他特性boost::no_property,    // 图对象的特性boost::listS>          // 保存边的容器类型(暂时不知道和第一个参数是否冲突或类似)

图有顶点vertex,和边edge。我们可以自定义两种数据类型。

namespace udi{
struct TopoVertexProperty{    //自定义顶点//std::string label;int32_t vertex_id;float position_x;float position_y;float position_z;struct qqq{int xyz;}gg;
};
​
struct TopoEdgeProperty{   //自定义边public:float weight = 1;        //边的信息float weight2 = 3;       //边的信息struct Test{             //边的信息,假设权重是自定义类型Testint x=1;int y=1;} w;
​struct less {bool operator() (const Test& x, const Test & y) const {return x.x<y.x;}typedef Test first_argument_type;typedef Test second_argument_type;typedef bool result_type;};
​struct closed_plus//保证加法不越界{const Test inf;closed_plus() : inf({10000,10000}) { }closed_plus(Test inf) : inf(inf) { }Test operator()(const Test& a, const Test& b) const {using namespace std;if (a.x == inf.x && a.y == inf.y) return inf;if (b.x == inf.x && b.y == inf.y) return inf;return {a.x+b.x,a.y+ b.y};}};
​friend std::ostream& operator << (std::ostream& x, const Test q);
};
​
​
std::ostream& operator << (std::ostream& x, const udi::TopoEdgeProperty::Test q){return x<<"("<<q.x<<" ,"<<q.y<<")";
}
​

那么定义的图的方法如下

  typedef boost::adjacency_list<boost::listS , //边的保存方案,用listboost::vecS ,  //点的保存方案,用vector,可以下标访问boost::directedS , //undirectedSudi::TopoVertexProperty,   //自定义vertexudi::TopoEdgeProperty> Graph;  //自定义edgetypedef Graph::edge_descriptor EdgeDescriptor; //描述边的类型typedef Graph::vertex_descriptor VertexDescriptor; //描述点的类型Graph g;

添加点的方法如下

  VertexDescriptor v1 = boost::add_vertex(udi::TopoVertexProperty(), g); //可以直接带上数值来直接给点赋值。VertexDescriptor v2 = boost::add_vertex(g);VertexDescriptor v3 = boost::add_vertex(g);VertexDescriptor v4 = boost::add_vertex(g);VertexDescriptor v5 = boost::add_vertex(g);
​
//给顶点赋值
​
//集合赋值法auto vertexs =  boost::get(&udi::TopoVertexProperty::gg, g); //得到的是g里所有顶点里gg的属性的集合vertexs[v1].xyz= 5;  //直接赋值
​
//直接访问的方法给顶点赋值g[v1].vertex_id = 0; g[v1].position_x = 11; g[v1].position_y = 111; g[v1].position_z = 11111111;g[v2].vertex_id = 1; g[v2].position_x = 22; g[v2].position_y = 222; g[v2].position_z = 22222222;g[v3].vertex_id = 2; g[v3].position_x = 33; g[v3].position_y = 333; g[v3].position_z = 33333333;g[v4].vertex_id = 3; g[v4].position_x = 44; g[v4].position_y = 444; g[v4].position_z = 44444444;g[v5].vertex_id = 4; g[v5].position_x = 55; g[v5].position_y = 555; g[v5].position_z = 55555555;

添加边与给边赋值的方法

 auto q = boost::add_edge(1,4,udi::TopoEdgeProperty(), g);//std::pair<EdgeDescriptor , bool>EdgeDescriptor e;bool bbb;boost::tie(e,bbb)  = boost::add_edge( v1 , v2 , udi::TopoEdgeProperty(), g);std::pair<EdgeDescriptor , bool> e21 = boost::add_edge(v2 , v1 , g);std::pair<EdgeDescriptor , bool> e23 = boost::add_edge(v2 , v3 , g);std::pair<EdgeDescriptor , bool> e34 = boost::add_edge(v3 , v4 , g);std::pair<EdgeDescriptor , bool> e41 = boost::add_edge(v4 , v1 , g);std::pair<EdgeDescriptor , bool> e13 = boost::add_edge(v1 , v2 , g);std::pair<EdgeDescriptor , bool> e25 = boost::add_edge(v2 , v5 , g);g[q.first].weight = 4;

输出调试信息,边,点等信息。

std::cout << "Graph:" << std::endl;boost::print_graph(g , boost::get(  &udi::TopoVertexProperty::vertex_id, g) );
//上面的print_graph函数,并不能特别优雅的进行输出...也许我方法不对。std::cout << "num_vertex:" << boost::num_vertices(g) << std::endl;std::cout << "num_edges:" << boost::num_edges(g) << std::endl;
​

Dijkstra方法求最短路

boost::graph_traits<Graph>::vertex_iterator it;auto index_map = boost::get(boost::vertex_index, g);std::vector<VertexDescriptor > predecessor_map(num_vertices(g));std::vector<udi::TopoEdgeProperty::Test> distances(boost::num_vertices(g));//距离数组的类型,必须和权重的类型一致。这里我们用的是Test类型(大多数时候是float之类的)auto distance_iterator = boost::make_iterator_property_map(distances.begin() , boost::get(boost::vertex_index , g));
​
source = boost::vertex(1,g);boost::dijkstra_shortest_paths(g,source,&predecessor_map[0],distance_iterator,//&distances[0]都行吗?boost::get(&udi::TopoEdgeProperty::w ,g), //weightindex_map,udi::TopoEdgeProperty::less(),udi::TopoEdgeProperty::closed_plus(),udi::TopoEdgeProperty::Test({10000,10000}), //infudi::TopoEdgeProperty::Test({0,0}), //zeroboost::default_dijkstra_visitor());
​
​
//输出调试信息std::cout << "distances and parents:" << std::endl;
​Graph::vertex_iterator vi, vend;for (boost::tie(vi, vend) = boost::vertices(g); vi != vend; ++ vi) {std::cout << "distance(" << g[*vi].vertex_id <<")=" << distances[*vi] << ",";std::cout << "parent(" << g[*vi].vertex_id <<")=" << g[predecessor_map[*vi]].vertex_id<< std::endl;}

有时候不是自定义类型,是系统类型为权重(比如float,double等),耶就是说不需要提供比较器之类的东西,此时可以用下面的方法来进行求解Dijkstra最短路。

//以float为例
boost::graph_traits<Graph>::vertex_iterator it;source = boost::vertex(1,g);
​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]));

BGL自定义权重,求dijkstra相关推荐

  1. 自定义函数求圆和圆柱体的表面积

    本题要求自定义函数求圆和圆柱体的表面积. 自定义两个area函数,一个形参的实现求圆的面积,两个形参的实现求圆柱体的表面积.PI是全局符号常量. 函数接口定义: double area(double ...

  2. 自定义函数求一元二次方程C语言版

    题目 1028: [编程入门]自定义函数求一元二次方程 时间限制: 1Sec 内存限制: 128MB 题目描述 求方程 的根,用三个函数分别求当b^2-4ac大于0.等于0.和小于0时的根,并输出结果 ...

  3. C语言:1027.自定义函数求最大公约数和最小公倍数

    C语言:1027.自定义函数求最大公约数和最小公倍数 题目描述: 写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果两个整数由键盘输入. 解题思路: 1.利用辗转相 ...

  4. 自定义函数求两个整数的和

    一.自定义函数的构成: 自定义函数就是根据需要自己定义的函数,他的作用就是帮助我们实现我们想实现的功能.在定义函数时,需要注意以下几点: 1.函数名不可忽略.一个函数必须又一个合法的函数名,函数命名时 ...

  5. 一元函数求导C语言,自定义函数求一元二次方程(C语言版)

    注意点: 输出的格式,多少位后小数. scanf后要记得加& <0的情况要记得分类 题目描述 求方程 的根,用三个函数分别求当b^2-4ac大于0.等于0.和小于0时的根,并输出结果.从 ...

  6. C++自定义sobel求梯度

    Mat Sobel_gradient(Mat img, int direction) {Mat oriImage = img;Mat newImage_x = Mat(img.size(), CV_8 ...

  7. [编程入门]自定义函数求一元二次方程

    题目描述 求方程 的根,用三个函数分别求当b^2-4ac大于0.等于0.和小于0时的根,并输出结果.从主函数输入a.b.c的值. 输入 a b c 输出 x1=? x2=? 样例输入 4 1 1 样例 ...

  8. 自定义函数求一元二次方程(C语言)

    题目: 求方程的根,用三个函数分别求当b^2-4ac大于0.等于0.和小于0时的根,并输出结果.从主函数输入a.b.c的值. 一般式:ax²+bx+c=0(a≠0) 其中a是二次项系数,b是一次项系数 ...

  9. 题目 1028: 自定义函数求一元二次方程

    题目描述 求方程 的根,用三个函数分别求当b^2-4ac大于0.等于0.和小于0时的根,并输出结果.从主函数输入a.b.c的值. 输入 a b c 输出 x1=? x2=? 样例输入 4 1 1 样例 ...

最新文章

  1. 【Smart_Point】C/C++ 中智能指针
  2. VASP计算HSE06带隙INCAR
  3. Bzoj3550 [ONTAK2010]Vacation
  4. “非”天才女程序员的人生
  5. React Native 实现FlatList的下拉刷新上拉加载
  6. Java NIO系列教程(十 五)Java NIO Path
  7. 服务器虚拟化相关问题分析,服务器虚拟化后引入的问题分析
  8. 毕设日志5.12凌晨
  9. dc综合与pt静态时序分析(中文)_新能源汽车小三电系统(PDU/DC/OBC)技术研究详解...
  10. 计算机系统端口445,如何关闭445端口,教您如何关闭系统端口
  11. xp系统下硬盘安装linux,在NTFS格式硬盘XP下安装LINUX系统
  12. URP——后期处理特效——通道混合器Channel Mixer
  13. 微信小程序模板消息测试- formId 的获取
  14. java 多字段分组_在Java 8中按多个字段名称分组
  15. Linux中如何让命令在后台运行
  16. nmap -oG -iL 写入文件和读取文件之[网鼎杯 2020 朱雀组]Nmap
  17. 北大考研复试上机——W's Cipher
  18. Calendar类(日历)
  19. 如何选购计算机硬件,DIY攒机经验之谈:十年老司机教你组装电脑如何选购硬件...
  20. 欧式几何—功能游戏介绍

热门文章

  1. 【原版教材•中英对照】晶体结构间的对称关系——晶体学群论在晶体化学中应用的重要性
  2. 易语言多线程Api封装线程挂起恢复销毁
  3. 易语言多线程大漠多线程初始化COM库
  4. 《深入理解Mybatis原理》 02-Mybatis数据源与连接池
  5. 官网Instagram集成
  6. Paddle平台中搭建CNN模型,在训练模型中采用tensor类型
  7. ipv6格式介绍和地址数量计算
  8. 金九银十:怎么正确跟 HR 谈薪资?
  9. Gox语言中的数组类型及其常用操作 - GX7.1
  10. 毕业论文怎么写?一搏教你拆解论文撰写8大模块