具有可移动节点、可访问属性和可靠ID的C++图
C++ graph with removable nodes, accessible properties and reliable IDs
我正试图将从专有图库迁移到开源图库。
编辑:由于似乎很少有人知道Boost Graph的实际工作原理,如果你能使用LEMON Graph Library提供一个解决方案,那也没关系。
目前,我的顶点的类型为Graph_Vertex*
,并且可以有一个相关的void*
指针来存储相关信息。对于类型为Graph_Edge*
的边使用类似的逻辑。我使用void*
指针来存储我自己的结构Node_State
,它类似于这个
struct Node_State {
std::string name;
int id;
// other stuff
};
根据我目前对BGL的了解,我可以使用adjacency_list
结构和绑定的属性来创建一个图,以指向我的Node_State
。然后,我将使用整数顶点索引,而不是使用的顶点指针。
我一直在看教程和这里的一些问题,这似乎是可能的。我在考虑类似的东西
typedef adjacency_list < listS, vecS, bidirectionalS, Node_State> gr;
我会不时地移除顶点的所有边。不太频繁,我可能也会删除一个节点。这就是为什么我会选择listS, vecS
。
我想为无向边创建此结构的第二个版本变得更容易。我不确定bidirectionalS
是否是我的最佳选择。感谢您在这方面的投入。
不过还有一个问题。现在,我可以使用外部映射按其名称或使用唯一整数id来查找每个顶点。
std::map<int, Graph_Vertex*> nodes_by_id;
std::map<std::string, Graph_Vertex*> nodes_by_name();
如果我删除了一个顶点,我只需要删除映射中相应的条目,事情就会继续进行。
据我所知,使用BGL实现这一点并不容易,因为删除一个顶点会触发所有ID较高的顶点的重新编号,还可能导致内部结构的重新分配。再见id和再见指针。
主要问题是否可以创建一个map<name, node>
或map<index, node>
,它可以在节点删除时幸存下来,只需进行最小的调整(例如,只删除无效密钥)?如果没有,将节点映射到某个唯一标识符的最佳方法是什么?
一个选项可能是使用内部属性。此处为教程示例。
struct vertex_index_t { };
struct edge_index_t { };
struct vertex_name_t { };
struct edge_name_t { };
并保留一些外部结构
std::map<vertex_index_t, Graph_Vertex*> nodes_by_id;
std::map<vertex_name_t, Graph_Vertex*> nodes_by_name;
std::map<edge_index_t, Graph_Edge*> edges_by_id;
std::map<edge_name_t, Graph_Edge*> edges_by_name;
这将与我现在所做的更加相似,并且需要对当前代码进行较少的更改。
我还没有真正理解顶点移除对vertex_index_t
的影响,以及如何分配vertex_name_t
。然而,如果这可以工作,则类似的逻辑也可以应用于使用edge_index_t
和edge_name_t
的边。
总结。我需要一段工作代码来展示如何:
- 添加顶点(具有特性)
- 添加圆弧(具有特性)
- 删除顶点
- 删除圆弧
有了这些重要的先决条件:
- 能够通过id(int或string)对顶点进行索引,以便轻松检索它们并访问它们的属性
- 如果删除了顶点,id就不能更改
- 索引和属性的添加不应使"查找连接组件"answers"Dijkstra搜索"等算法的运行变得更加困难
如果我能取得这样的成绩,我会很高兴
Vertex* vertex0 = Graph.get_vertex_by_name("v0");
Vertex_Data* v0_data = vertex0.get_data();
Edge* edge4 = Graph.get_edge_by_id(4);
Edge_Data* e4_data = edge4.get_data();
这看起来可能有很多问题,但实际上只是我启动和运行这个库所需的基础。只要少一点,我就完全没用了。
请击中所有要点。
把这看作一个教程,我希望给予赏金也能帮助其他人。
然后,我将使用整数顶点索引,而不是使用顶点指针。
事实上,我认为你应该使用顶点描述符。在vecS容器选择的情况下,是的
据我所知,使用BGL实现这一点并不容易,因为删除一个顶点会触发所有ID更高的顶点的重新编号,还可能导致内部结构的重新分配。
严格地说,情况并非总是如此。vecS
的情况是,但例如listS
(列表具有稳定的迭代器)则不然。
- 迭代程序无效规则
总之,我建议将listS
视为容器选择,并放弃vertex_descriptor
是积分类型的假设(它将变得不透明)。
作为迭代器稳定性的回报,您需要为某些算法提供顶点索引映射。
- 从函数角度看ID到文件路径的内部与外部映射
- 通过组合不同的类型来创建唯一的id
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- FFMPEG配置文件级别id大小无效
- 方法内部但循环仍得到预期的不合格id错误C++
- 如何获取 GLFW 窗口 ID?
- 当简单捕获中的标识符显示为参数的声明符 ID 时,没有编译器诊断
- 显示数组中的学生 ID 和最高分
- C++:"("令牌"之前有预期的非限定 id 指向类中成员函数的指针
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- Xcode 9.4.1 中的 Apple Mach-O 链接器 (id) 错误
- 错误:令牌 { '{' 之前应存在非限定 ID
- 断言"id < 0"在Qt ActiveX中失败
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- 如何根据两个因素组织向量:id 和数量?(C++)
- 在返回 0 之前应为非限定 ID
- Direct3D 11 - HLSL - 获取顶点索引 ID
- 编译时检查特征专用化是否具有唯一 ID
- DCMTK 了解"DIMSE 没有有效的演示上下文 ID"错误
- 一种有效的数据结构,用于按 ID 访问和查找加权随机项