boost-graph 相关问题

Boost.Graph是一个包含通用图形组件和算法的C ++库。

读取 Boost Graph Library 中的 GraphML 文件时出现解析错误

我在使用 Boost Graph Library 读取 GraphML 文件时遇到问题。该文件创建时没有问题,但读回它会引发解析错误。以下是我正在做的事情的总结: 我创建我的

回答 1 投票 0

当存在没有边的顶点时如何使用boost::connected_components?

boost中的例子来自文档 https://www.boost.org/doc/libs/1_85_0/libs/graph/example/connected_components.cpp //================================================== ======================= //

回答 1 投票 0

boost 子图给出“形成对 void 的引用”错误

我正在尝试创建 boost::adjacency_list 的 boost::subgraph,但我在创建时遇到了一个我不明白的错误。专门使用 boost::adjacency_list 构建的类似代码和

回答 1 投票 0

Boost 图自定义索引使用 Dijkstra

我正在尝试通过Boost图形库创建一个图形,它具有自定义索引(删除顶点时稳定), 我复制了此处提出的解决方案来创建非常有效的图表

回答 1 投票 0

boost graphs - 优先拓扑排序

我想做一个改变的拓扑排序。在任何给定的级别,我们可以采取多种选择。 例如,该图的拓扑顺序可以是 1 -> 2 -> 3 或 2 -> 1 ...

回答 1 投票 0

C++ Boost kamada_kawai_spring_layout 问题

为了实现某些顶点位置固定的平面嵌入, 我目前正在使用力导向布局方法。这种做法可行吗? 我目前面临编译问题...

回答 1 投票 0

将 EdgeList 作为 unordered_set 存储在 Boost Graph Library 上

我正在重现一个科学实验,我需要将图的边集存储为无序集。我正在尝试使用 BGL adjacency_graph,我认为最后一个参数是 hash_...

回答 3 投票 0

Boost Graphs - 来自 JSON 的确定性图行为

我正在从 JSON 数组文件创建图形,我希望这样当我遍历图形的边和顶点(例如 in_edges()、vertices() 或 topological_sort() )时,它位于准确

回答 1 投票 0

Boost Graphs - 确保确定性的图行为

我正在根据 JSON 文件中的数据创建图形,并且我希望这样当我遍历图形的边和顶点(例如 in_edges()、vertices() 或 topological_sort() )时,它位于该...

回答 1 投票 0

使用自定义比较器和额外参数设置Typedef

我有一个升压有向图的包装器。每个顶点都有一个整数 id 字段,我想在 typedef 中编写一组按 id 排序的顶点描述符。本质上我有: 结构 VertexDat...

回答 1 投票 0

如何使用 add_vertex() 将自定义 vertex_descriptor 设置为自己的值 - Boost Graph Library

我正在学习 Boost Graph Library (BGL) 的工作原理,并使用以下示例来尝试根据文本文件中的某些数据创建图形。数据从文本文件中读入...

回答 1 投票 0

如何使用boost graph遍历平面图(代表一棵树)来模拟沿着图的边缘行走

我在 XY 平面上有以下图形。顶点已编号。我有 结构点{ 双x; 双 y; } std::vector 点; std::向量 e...

回答 1 投票 0

改变Boost拓扑排序

我正在尝试调整此 git 页面,在拓扑排序的同时获取传入顶点的拓扑排序列表。我这样做的原因是为了比较这个实现...

回答 1 投票 0

Boost::graph (c++) 优于 networkx (python)

编辑:正如@sehe所指出的,错误位于介数中心性计算之前的某个地方。向前走! 我实现了一个最小的程序来计算 undir 的介数中心性......

回答 1 投票 0

使用 Boost 的 Dijkstra 最短路径实现查找一对顶点之间的多个(所有)最短路径

我一直在使用 Boost 使用 Dijkstra 最短路径算法 dijkstra_shortest_paths 的实现来查找图中两个节点之间的最短路径 (SP)。该函数返回一个

回答 1 投票 0

如何在 boost 图中对 std::shared_ptr<> 中包装的图属性进行深度复制?

我有一个带有自定义属性的增强图。 我想复印一份。我按照下面的方式尝试了一下。 使用 BGType = boost::adjacency_list 我有一个带有自定义属性的增强图。 我想复印一份。我按照以下方法尝试过。 using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, // Vertex Properties... vertexProps, // Edge Propereties... edgeProps, // Graph Properties graphProps>; vertexProps.h class vertexProps { public: explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr, long refPtr = 0 ) : _refPtr(refPtr), { _moduleName = moduleName ? *moduleName : ""; _name = name ? *name : ""; }; std::string _moduleName; std::string _name; BGType *_subGraph = nullptr; BGType *_graph = nullptr; } struct CustomVertexCopy { BGType const &g1; BGType &g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { schVertexProps const &p1 = g1[v1]; schVertexProps &p2 = g2[v2]; p2._subGraph = p1._subGraph; p2._graph = p1._graph; p2._moduleName = p1._moduleName; p2._name = p1._name; } }; edgeProps.h class edgeProps { public: explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct CustomEdgeCopy { BGType const &g1; BGType &g2; void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const { g2[e2]._name = g1[e1]._name; } }; schGraphProps.h class schGraphProps { public: explicit schGraphProps(std::string *name = nullptr) { _name = name ? *name : ""; }; std::string _name; std::map<std::string, std::vector<std::string>> _altNames; std::map<std::string, schSymbol> _modSymbol; std::shared_ptr<vertexProps> _vertexPtr = nullptr; // ****want to deep copy this property******* } 一些函数.cpp OnClick(BGType* bgNew) { // some code BGType* oldBg = new BGType; boost::copy_graph( *bgNew, *oldBg, boost::vertex_copy(CustomVertexCopy{*bgNew, *oldBg}).edge_copy(CustomEdgeCopy{*bgNew, *oldBg})); boost::get_property(*oldBg) = boost::get_property(*bgNew); // Copying graph properties DeepCopyOfBG(bgNew, oldBg); } DeepCopyOfBG(BGType *bGraph, BGType *oldBg) { boost::copy_graph( *bGraph, *oldBg, boost::vertex_copy(CustomVertexCopy{*bGraph, *oldBg}).edge_copy(CustomEdgeCopy{*bGraph, *oldBg})); boost::get_property(*oldBg) = boost::get_property(*bGraph); // Deep copy _altNames map for (auto entry : (*bGraph)[boost::graph_bundle]._altNames) { std::vector<std::string> deepCopyValues(entry.second.begin(), entry.second.end()); (*oldBg)[boost::graph_bundle]._altNames[entry.first] = deepCopyValues; // Deep copy _modSymbol map for (auto entry : (*bGraph)[boost::graph_bundle]._modSymbol) { (*oldBg)[boost::graph_bundle]._modSymbol[entry.first] = entry.second; } // Want to copy std::shared_ptr<schVertexProps> _vertexPtr = nullptr } 我想深度复制以下属性,但无法做到。 std::shared_ptr<vertexProps> _vertexPtr = nullptr 我因为shared_ptr概念而陷入困境。 如何对shared_ptr概念进行深拷贝? 我的第一反应是:当你想要值语义时,不要使用 shared_ptr。 这正是我在之前的回答中向您展示value_ptr的原因。这样,零规则就适用,并且语言会自动按照您想要的方式运行。 如果您必须拥有共享指针并且仍然对它们进行深度克隆,则可以复制该value_ptr并使其包含一个shared_ptr而不是unique_ptr。 如果您不希望这样,或者有其他“自然之力”原因导致您不能(???),您始终可以......只需手动复制对象即可。一般来说,任何唯一指针在概念上的行为都类似于指针。 { // clone a pointer T* p = new T(); T* clone = new T(*p); } { // clone a unique_ptr unique_ptr<T> p = std::make_unique<T>(); unique_ptr<T> clone = std::make_unique<T>(*p); } { // clone a shared_ptr shared_ptr<T> p = std::make_shared<T>(); shared_ptr<T> clone = std::make_shared<T>(*p); } 我希望你能发现其中的规律?深度复制基本上只是调用 *p 的复制构造函数:无论 p 指向什么。您拥有哪种(智能)指针甚至并不重要。 { // clone a whatever_ptr whatever_ptr<T> p = std::make_whatever<T>(); whatever_ptr<T> clone = std::make_whatever<T>(*p); } 关于代码,您会遇到更多问题,因为您在同一对象上多次运行copy_graph。您还可以运行以下作业两次: boost::get_property(*oldBg) = boost::get_property(*bGraph); 该赋值已复制所有图形属性(schGraphProps对象)。 现在,C++ 允许您通过提供用户定义的复制构造函数来自定义此类副本的行为。在你的情况下,你可以例如做到: schGraphProps(schGraphProps const& other) : _name(other._name) , _altNames(other._altNames) , _modSymbol(other._modSymbol) , _vertexPtr(other._vertexPtr ? std::make_shared<vertexProps>(*other._vertexPtr) : nullptr) {} 记住要修复构造函数中的指针误用,正如我之前多次向您展示的那样,您将获得以下类:Live class schGraphProps { public: explicit schGraphProps(std::string name = {}) : _name(std::move(name)) {} schGraphProps(schGraphProps const& other) : _name(other._name) , _altNames(other._altNames) , _modSymbol(other._modSymbol) , _vertexPtr(other._vertexPtr ? std::make_shared<vertexProps>(*other._vertexPtr) : nullptr) {} std::string _name; std::map<std::string, std::vector<std::string>> _altNames; std::map<std::string, schSymbol> _modSymbol; std::shared_ptr<vertexProps> _vertexPtr = nullptr; }; 现场演示 我没有心情再次创建完整的演示,因为我不断修复您不断重新引入的错误和不必要的复杂性。所以我将只关注图形属性。 ASIDE 事实上,这可能会帮助您更好地理解 C++ 类型系统的行为。即使作为 BGL 的 adjacency_list 等复杂数据结构的一部分,所有部分仍然“只是 C++ 类型”。如果您使用 C++ 编写代码,那么了解 C++ 类型系统是必须。 住在Coliru #include <cassert> #include <map> #include <memory> #include <string> #include <vector> struct vertexProps{}; struct schSymbol{}; class schGraphProps { public: explicit schGraphProps(std::string name = {}) : _name(std::move(name)) {} schGraphProps(schGraphProps const& other) : _name(other._name) , _altNames(other._altNames) , _modSymbol(other._modSymbol) , _vertexPtr(other._vertexPtr ? std::make_shared<vertexProps>(*other._vertexPtr) : nullptr) {} std::string _name; std::map<std::string, std::vector<std::string>> _altNames; std::map<std::string, schSymbol> _modSymbol; std::shared_ptr<vertexProps> _vertexPtr = nullptr; }; #include <iostream> int main() { auto v = std::make_shared<vertexProps>(); schGraphProps graphProps1{"hello"}; graphProps1._vertexPtr = v; // clone it! auto graphProps2 = graphProps1; // uses copy constructor std::cout << "Original v:\t" << v.get() << "\n"; std::cout << "graphProps1._vertexPtr:\t" << graphProps1._vertexPtr.get() << "\n"; std::cout << "graphProps2._vertexPtr:\t" << graphProps2._vertexPtr.get() << "\n"; assert(graphProps1._vertexPtr == v); assert(graphProps2._vertexPtr != v); // deep copied } 打印例如 Original v: 0xbce030 graphProps1._vertexPtr: 0xbce030 graphProps2._vertexPtr: 0xbce050 所有断言都通过,证明了深拷贝。

回答 1 投票 0

如何复制包含图本身的boost图的顶点属性?

我有一个带有自定义属性的增强图。我想复印一份。我按照下面的方式尝试了一下。 使用 BGType = boost::adjacency_list 我有一个带有自定义属性的增强图。我想复印一份。我按照以下方法尝试过。 using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, // Vertex Properties... vertexProps, // Edge Propereties... edgeProps, // Graph Properties graphProps>; vertexProps.h class vertexProps { public: explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr, long refPtr = 0 ) : _refPtr(refPtr), { _moduleName = moduleName ? *moduleName : ""; _name = name ? *name : ""; }; std::string _moduleName; std::string _name; BGType *_subGraph = nullptr; BGType *_graph = nullptr; struct CustomVertexCopy { BGType const &g1; BGType &g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { schVertexProps const &p1 = g1[v1]; schVertexProps &p2 = g2[v2]; p2._subGraph = p1._subGraph; p2._graph = p1._graph; p2._moduleName = p1._moduleName; p2._name = p1._name; } }; edgeProps.h class edgeProps { public: explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct CustomEdgeCopy { BGType const &g1; BGType &g2; void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const { g2[e2]._name = g1[e1]._name; } }; 一些函数.cpp OnClick(BGType* bgNew) { // some code BGType* oldBg = new BGType; boost::copy_graph( *bgNew, *oldBg, boost::vertex_copy(CustomVertexCopy{*bgNew, *oldBg}).edge_copy(CustomEdgeCopy{*bgNew, *oldBg})); boost::get_property(*oldBg) = boost::get_property(*bgNew); // Copying graph properties DeepCopyOfBG(bgNew, oldBg); } void someFunction::DeepCopyOfBG(BGType* bGraph, BGType* oldBg) { // Iterate through the source map and copy its contents for (const auto& entry : (*bGraph)[boost::graph_bundle]._modInfo) { const std::string& key = entry.first; const auto& value = entry.second; // Create a deep copy of value (a tuple containing vectors of schPinInfo) std::tuple<std::vector<schPinInfo*>, std::vector<schPinInfo*>, std::vector<schPinInfo*>> deepCopyValue = value; // Add the deep copy to the target map (*oldBg)[boost::graph_bundle]._modInfo[key] = deepCopyValue; } // some more properties. } 以上方法工作正常。但它有 1 个问题。 Vertex 属性有 1 个字段,它本身就是一个 boost 图。 p2._subGraph = p1._subGraph; 上面的行只是复制指针。因此,在旧的升压图中,我得到了我不想要的新升压图的子图。 那么如何深度复制这个_subGraph字段呢? Vertex 属性有 1 个字段,它本身就是一个 boost 图 确实没有。正如您自己指出的,它包含指向图形的指针。这根本不是一回事。 上面的行只是复制指针。因此,在旧的升压图中,我得到了我不想要的新升压图的子图。那么如何深度复制这个_subGraph字段呢? 我怀疑你确实想要它,因为复制每个顶点的图是昂贵的。因此,除非您使用小图,否则我建议使用 shared_ptr<BGType const> 来接受间接寻址,这也解决了生命周期问题(您的代码几乎不可避免地会像现在一样遭受内存泄漏)。 旁注: p2._graph = p1._graph; 看起来也很可疑。应该是p2._graph = &g2;吗? 解决方案1 如果您想要完整副本,最简单的方法是不使用指针,因此该行 p2._subGraph = p1._subGraph; 实际上复制了对象。 解决方案2 您显然可以将其拼写出来,通过使用原始指针引入新的内存泄漏机会: p2._subGraph = new BTType(*p1._subGraph); 由于您仍在执行复杂的舞蹈来复制其他位置的图表,因此您可能需要在此处重复该操作。我建议创建一个函数来完成它: p2._subGraph = my_graph_copy_function(p1._subGraph); 演示 我将按照惯例提供一个演示,但我将基于我的之前的建议来展示完整的价值语义,从而避免首先复制图表带来的所有不必要的复杂情况。 现在,因为这里存在递归(图的节点包含图,图的节点包含......等),我们必须使用某种动态分配。我选择了一个“value_ptr”,它基本上是一个通过深拷贝复制的unique_ptr: struct BGType; // forward using SubGraph = value_ptr<BGType>; struct vertexProps { std::string _moduleName; std::string _name; long _refPtr; SubGraph _subGraph; }; 现在默认的副本分配将执行您想要的操作,没有内存泄漏的风险,并且无需编写过于复杂的代码。 因为BGType需要在这里向前声明,所以我们必须将其定义为一个结构体 - 我们可以通过继承来做到这一点: struct BGType : BGTypeImpl { using BGTypeImpl::BGTypeImpl; using BGTypeImpl::operator=; }; 现在主要是: int main() { BGType g1 = make_graph(); BGType g2; g2 = g1; // FULL COPY std::cout << "g2:\n" << g2 << "\n"; std::cout << "address of subgraph in g1: " << g1[2]._subGraph.address() << "\n"; std::cout << "address of subgraph in g2: " << g2[2]._subGraph.address() << "\n"; } 我们可以得到输出 g2: digraph G { label=name; 0 [moduleName=Hello, name=world, ref=111, subGraph="(none)"]; 1 [moduleName=Goodbye, name=moon, ref=222, subGraph="(none)"]; 2 [moduleName=Greetings, name=Cosmos, ref=333, subGraph="digraph G { label=sub; 0 [moduleName=Greetings, name=Cosmos, ref=333, subGraph=\"(none)\"]; 1 [moduleName=\"\", name=\"\", ref=0, subGraph=\"(none)\"]; 0->0 [name=nested]; } "]; 0->1 [name=one]; 2->0 [name=two]; } address of subgraph in g1: 0x1025900 address of subgraph in g2: 0x1025ba0 请注意,子图地址是不同的。这里没有内存泄漏。 完整列表 住在Coliru #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> // forward declarations so we can have recursive object structure template <typename T> struct value_ptr { /*explicit*/ value_ptr(std::nullptr_t = {}) {} /*explicit*/ value_ptr(T v) : p_(std::make_unique<T>(std::move(v))) {} value_ptr(value_ptr const& rhs) : p_(rhs.p_ ? std::make_unique<T>(*rhs.p_) : nullptr) {} value_ptr& operator=(value_ptr const& rhs) { p_ = rhs.p_ ? std::make_unique<T>(*rhs.p_) : nullptr; return *this; } value_ptr(value_ptr&& rhs) = default; value_ptr& operator=(value_ptr&& rhs) = default; explicit operator bool() const { return !!p_; } auto& operator*() const { return *p_; } auto& operator->() const { return *p_; } auto address() const { return p_.get(); } private: std::unique_ptr<T> p_; friend std::ostream& operator<<(std::ostream& os, value_ptr const& p) { if (!p) return os << "(none)"; return os << *p; } friend std::istream& operator>>(std::istream& is, value_ptr&) { // dynamic properties cannot be readonly is.setstate(std::ios::failbit); return is; } }; struct BGType; // forward using SubGraph = value_ptr<BGType>; struct vertexProps { std::string _moduleName; std::string _name; long _refPtr = 0; SubGraph _subGraph; }; struct edgeProps { edgeProps(edgeProps const&) = default; edgeProps& operator=(edgeProps const&) = default; explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct schPinInfo { std::string id; }; schPinInfo const wellknownPins[] = { {"i1"}, {"i2"}, {"i3"}, {"o4"}, {"o5"}, {"i6"}, {"i7"}, {"i8"}, {"o9"}, {"o10"}, }; static schPinInfo const* const i1 = wellknownPins + 0; static schPinInfo const* const i2 = wellknownPins + 1; static schPinInfo const* const i3 = wellknownPins + 2; static schPinInfo const* const o4 = wellknownPins + 3; static schPinInfo const* const o5 = wellknownPins + 4; static schPinInfo const* const i6 = wellknownPins + 5; static schPinInfo const* const i7 = wellknownPins + 6; static schPinInfo const* const i8 = wellknownPins + 7; static schPinInfo const* const o9 = wellknownPins + 8; static schPinInfo const* const o10 = wellknownPins + 9; using Pins = std::vector<schPinInfo const*>; struct Layout { Pins input, inout, output; }; struct schSymbol {}; struct graphProps { graphProps& operator=(graphProps const&) = default; explicit graphProps(std::string name = {}) : _name(std::move(name)) {} std::string _name; std::map<std::string, Layout> _modInfo; std::map<std::string, std::vector<std::string>> _altNames; std::map<std::string, schSymbol> _modSymbol; }; using BGTypeImpl = boost::adjacency_list< // boost::vecS, boost::vecS, boost::bidirectionalS, // vertexProps, edgeProps, graphProps>; struct BGType : BGTypeImpl { using BGTypeImpl::BGTypeImpl; using BGTypeImpl::operator=; friend auto& get_property(BGType& g, boost::graph_bundle_t prop) { return boost::get_property(static_cast<BGTypeImpl&>(g), prop); } friend auto& get_property(BGType const& g, boost::graph_bundle_t prop) { return boost::get_property(static_cast<BGTypeImpl const&>(g), prop); } friend std::ostream& operator<<(std::ostream& os, BGType const& g) { boost::dynamic_properties dp; // this is ugly, but see https://stackoverflow.com/a/27238425/85371 auto& ncg = const_cast<BGType&>(g); dp.property("node_id", get (boost::vertex_index, g)); dp.property("moduleName", get (&vertexProps::_moduleName, ncg)); dp.property("name", get (&vertexProps::_name, ncg)); dp.property("subGraph", get (&vertexProps::_subGraph, ncg)); dp.property("ref", get (&vertexProps::_refPtr, ncg)); dp.property("name", get (&edgeProps::_name, ncg)); dp.property("label", boost::make_constant_property<BGType*>(get_property(g)._name)); write_graphviz_dp(os, g, dp); return os; } }; // implement functions now that BGType is complete BGType make_graph() { BGType g{3, graphProps{"name"}}; boost::get_property(g)._modInfo = { {"mod1", Layout{{i1, i2, i3}, {}, {o4, o5}}}, {"mod2", Layout{{i6, i7, i8}, {}, {o9, o10}}}, }; boost::get_property(g)._altNames = { {"mod1", {"MOD1", "MOD_1"}}, {"mod2", {"MOD2", "MOD_2"}}, }; boost::get_property(g)._modSymbol = { {"mod1", schSymbol{}}, {"mod2", schSymbol{}}, }; g[0] = vertexProps{"Hello", "world", 111, {}}; g[1] = vertexProps{"Goodbye", "moon", 222, {}}; g[2] = vertexProps{"Greetings", "Cosmos", 333, {}}; { // add a subgraph to vertex 2 BGType sub(2, graphProps{"sub"}); sub[0] = vertexProps{"Greetings", "Cosmos", 333, {}}; add_edge(0, 0, edgeProps{"nested"}, sub); g[2]._subGraph = sub; } add_edge(0, 1, edgeProps{"one"}, g); add_edge(2, 0, edgeProps{"two"}, g); return g; } int main() { BGType g1 = make_graph(); BGType g2; g2 = g1; // FULL COPY std::cout << "g2:\n" << g2 << "\n"; std::cout << "address of subgraph in g1: " << g1[2]._subGraph.address() << "\n"; std::cout << "address of subgraph in g2: " << g2[2]._subGraph.address() << "\n"; }

回答 1 投票 0

如何将一个Boost图的图形属性复制到另一个Boost图?

我有一个带有顶点、边和图属性的增强图。我想复制一份 boost braph。我将一个 boost 图的顶点和边属性(使用 copy_graph)复制到另一个 boost 图中,但 c...

回答 1 投票 0

如何使用所有自定义属性将一个 boost 图复制到另一个(深层复制)?

我有一个带有自定义属性的增强图。我想复印一份。我按照以下方式尝试过,但出现了很多编译错误。 这是我所做的: 使用 BGType = boost::adjacency_list 我有一个带有自定义属性的增强图。我想复印一份。我按照以下方式尝试了,但出现了很多编译错误。 这就是我所做的: using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, // Vertex Properties... vertexProps, // Edge Propereties... edgeProps, // Graph Properties graphProps>; vertexProps.h class vertexProps { public: explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr, long refPtr = 0 ) : _refPtr(refPtr), { _moduleName = moduleName ? *moduleName : ""; _name = name ? *name : ""; }; struct CustomVertexCopy { void operator()(const vertexProps& source_vertex, vertexProps& target_vertex) const { target_vertex._refPtr = source_vertex._refPtr; target_vertex._moduleName = source_vertex._moduleName; target_vertex._name = source_vertex._name; } edgeProps.h class edgeProps { public: explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct CustomEdgeCopy { void operator()(const edgeProps& source_edge, edgeProps& target_edge) const { target_edge._name = source_edge._name; } }; 一些函数.cpp OnClick(BGType* bGraph) { // some code BGType* oldBg = new BGType; boost::copy_graph(bGraph, oldBg, boost::vertex_copy(CustomVertexCopy())); boost::copy_graph(bGraph, oldBg, boost::edge_copy(CustomEdgeCopy())); // some code } 我哪里错了? 我还有一个疑问。 如果 grpah 很大,这种深度复制会影响性能吗? 如果是的话,有什么办法可以避免吗? 命名参数是链接的,因此您可以在一个地方传递任意数量的参数: boost::copy_graph( // g1, g2, // boost::vertex_copy(CustomVertexCopy{}) // .edge_copy(CustomEdgeCopy{})); 请注意,.edge_copy 链接在 vertex_copy() 命名参数对象上。 然后,仍然无法编译,因为自定义复制器应该采用描述符,而不是捆绑引用: struct CustomVertexCopy { BGType const& g1; BGType& g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { vertexProps const& p1 = g1[v1]; vertexProps& p2 = g2[v2]; p2._refPtr = p1._refPtr; p2._moduleName = p1._moduleName; p2._name = p1._name; } }; 现在一切正常了: 住在Coliru #include <boost/graph/adjacency_list.hpp> #include <boost/graph/copy.hpp> #include <boost/graph/graphviz.hpp> class vertexProps { public: explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0) : _refPtr(refPtr) { _moduleName = mn ? *mn : ""; _name = n ? *n : ""; } std::string _moduleName; std::string _name; long _refPtr; }; class edgeProps { public: explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct graphProps {}; using BGType = boost::adjacency_list< // boost::vecS, boost::vecS, boost::bidirectionalS, // vertexProps, edgeProps, graphProps>; struct CustomVertexCopy { BGType const& g1; BGType& g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { vertexProps const& p1 = g1[v1]; vertexProps& p2 = g2[v2]; p2._refPtr = p1._refPtr; p2._moduleName = p1._moduleName; p2._name = p1._name; } }; struct CustomEdgeCopy { BGType const& g1; BGType& g2; void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const { g2[e2]._name = g1[e1]._name; } }; int main() { BGType g1(3); std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"}; g1[0] = vertexProps{names + 0, names + 1, 111}; g1[1] = vertexProps{names + 2, names + 3, 222}; g1[2] = vertexProps{names + 4, names + 5, 333}; add_edge(0, 1, edgeProps{"one"}, g1); add_edge(2, 0, edgeProps{"two"}, g1); BGType g2; boost::copy_graph( // g1, g2, // boost::vertex_copy(CustomVertexCopy{g1, g2}) // .edge_copy(CustomEdgeCopy{g1, g2})); boost::dynamic_properties dp; dp.property("node_id", get(boost::vertex_index, g2)); dp.property("moduleName", get(&vertexProps::_moduleName, g2)); dp.property("name", get(&vertexProps::_name, g2)); dp.property("ref", get(&vertexProps::_refPtr, g2)); dp.property("name", get(&edgeProps::_name, g2)); write_graphviz_dp(std::cout, g2, dp); } 打印 digraph G { 0 [moduleName=Hello, name=world, ref=111]; 1 [moduleName=Goodbye, name=moon, ref=222]; 2 [moduleName=Greetings, name=Cosmos, ref=333]; 0->1 [name=one]; 2->0 [name=two]; } 奖金 简化!只需使属性可复制,就可以了,代码行数减少了 20 行,大约减少了 30% 的错误/悲观空间: 住在Coliru #include <boost/graph/adjacency_list.hpp> #include <boost/graph/copy.hpp> #include <boost/graph/graphviz.hpp> class vertexProps { public: vertexProps(vertexProps const&) = default; vertexProps& operator=(vertexProps const&) = default; explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0) : _refPtr(refPtr) { _moduleName = mn ? *mn : ""; _name = n ? *n : ""; } std::string _moduleName; std::string _name; long _refPtr; }; class edgeProps { public: edgeProps(edgeProps const&) = default; edgeProps& operator=(edgeProps const&) = default; explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct graphProps {}; using BGType = boost::adjacency_list< // boost::vecS, boost::vecS, boost::bidirectionalS, // vertexProps, edgeProps, graphProps>; int main() { BGType g1(3); std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"}; g1[0] = vertexProps{names + 0, names + 1, 111}; g1[1] = vertexProps{names + 2, names + 3, 222}; g1[2] = vertexProps{names + 4, names + 5, 333}; add_edge(0, 1, edgeProps{"one"}, g1); add_edge(2, 0, edgeProps{"two"}, g1); BGType g2; boost::copy_graph(g1, g2); boost::dynamic_properties dp; dp.property("node_id", get(boost::vertex_index, g2)); dp.property("moduleName", get(&vertexProps::_moduleName, g2)); dp.property("name", get(&vertexProps::_name, g2)); dp.property("ref", get(&vertexProps::_refPtr, g2)); dp.property("name", get(&edgeProps::_name, g2)); write_graphviz_dp(std::cout, g2, dp); } 仍在打印 digraph G { 0 [moduleName=Hello, name=world, ref=111]; 1 [moduleName=Goodbye, name=moon, ref=222]; 2 [moduleName=Greetings, name=Cosmos, ref=333]; 0->1 [name=one]; 2->0 [name=two]; }

回答 1 投票 0

如何使用 boost::dijkstra_shortest_paths 计算具有“顶点权重”的最短路径?

我正在尝试计算具有顶点权重和边权重的图上的最短路径,但是 boost::dijkstra_shortest_paths 不计算通过顶点的权重。 我试过了

回答 2 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.