关于在系统中表示路径的数据结构的建议
Posted
技术标签:
【中文标题】关于在系统中表示路径的数据结构的建议【英文标题】:Advice on data-structure for represeting a Path in system 【发布时间】:2014-07-12 23:16:16 【问题描述】:我有一个系统,我需要表示类似于路径的东西,路径只是提供到达特定节点的路线。可以有多个路径可用于到达同一节点。
我目前正在使用节点向量表示路径,我需要执行诸如 replaceSubpath、containsNode、containsSubPath、appendNode、getRootNode、getLeafNode 之类的操作(与对字符串所做的操作非常相似)。所有这些操作都可以在向量上完成,但大路径的性能可能会很糟糕。
我正在考虑使用 boost::graph 但没有经验,我想知道对于这些和类似操作,使用 boost::graph 是否是正确/良好的数据结构?
任何关于使用其他数据结构的建议也会有所帮助,我知道我可以通过将节点的(多)映射保持到迭代器等来优化我的向量解决方案。
【问题讨论】:
boost::graph
去吧。
你能给我一些关于如何使用提升图来执行 findSubPath、replaceSubPath 之类的建议吗??
您不想将其表示为单个字符串的原因是?
或者,你知道,boost::path
?
@MooingDuck 我没听说过 boost::path。可以链接到它。我找到的唯一路径是 boost::filesytem::path 我认为这里不太适合。
【参考方案1】:
本质上,Boost.Graph 中的adjacency_list<>
类是一个顶点向量。顶点描述符是这个向量中的一个整数索引。
通常,一棵树或一条路径(路径是一棵树的特例,对吗?)表示为前驱图(如从叶子到根或从目标到源的倒退)。在整数顶点描述符的情况下,这样的前置映射只是vector<int>
。我认为您不能以更紧凑的方式表示路径或树。
当然,这样的前辈向量可以代入字符串操作,尤其是。来自 Boost.String_Algo,http://www.boost.org/doc/libs/1_55_0/doc/html/string_algo.html
【讨论】:
你能指出一些在 adjacency_list 上使用这些字符串算法的例子吗?? 例如,您从一些生成前驱图的图算法开始,例如Dijkstra 最短路径 (boost.org/doc/libs/1_55_0/libs/graph/example/…) 或 Kruskal MST。然后,您通常会使用此前任地图构建感兴趣的路径。这条路径本质上与前驱图的形式相同,但它没有不相关的顶点。我假设你也有一个潜在的子路径 sp 形式相同(作为前身映射写为 vector根据您的描述,听起来您正在生成和编辑图表中的路径,可能是为了优化路线等。
我认为一种数据结构无法满足您的需求。我会将图形结构与您生成的路径分开。
replaceSubpath:对我来说,这建议使用doubly linked list 实现。当你有了路径的开始和结束时,只需将其粘贴并替换子路径。
containsNode:考虑添加地图或集合以进行快速收容检查。
containsSubPath:这可能很困难,具体取决于您的其他顾虑和速度需求。如果这是一项非常重要的操作,请考虑使用Suffix Tree 来快速测试子路径。请记住,如果路径没有太大变化,因为构建它们是 O(N)
appendNode:链表在这里很容易
getRootNode:持有指向当前根节点的指针。
getLeafNode:持有指向当前叶节点的指针。
我会根据您的目标创建一个自定义数据结构来解决这些问题。查找子路径并快速替换它们可能是相互竞争的性能目标。通常更多的搜索优化 = 更多的构建开销使它们的动态性降低。
【讨论】:
【参考方案3】:看看您欣赏的其他一些代码如何实现管理路径的需求。例如,您可能会查看 Dijkstra 的多个实现,然后选择看起来最好、最方便或符合您口味的一个。
恕我直言,将“路径”建模为对象并不是一个好主意,而是将其视为图中节点的属性。
一般来说,我会考虑“标记”路径上的节点。例如,用于包含节点属性的类可能有一个标志,如果该节点在路径上,则该标志指示为真,以及一个带有路径上下一个节点索引的属性。
【讨论】:
我明白你所说的关于标记路径的内容。这将如何解决 OP 查找和替换子路径的需求?此外,如果需要许多路径,则向顶点属性添加标志将无法缩放。也许我错过了什么。以上是关于关于在系统中表示路径的数据结构的建议的主要内容,如果未能解决你的问题,请参考以下文章
如果它们来自数据源,如何在 graphql 模式中表示枚举?