gpt4 book ai didi

c++ - Boost.Graph:使用名称保存和加载 boost::adjacency_list

转载 作者:太空宇宙 更新时间:2023-11-04 13:22:36 24 4
gpt4 key购买 nike

在 boost::adjaceny_list 中,我能够获取并设置图表的名称。可悲的是,我无法将其保存并加载到文件中或从文件中加载。我可以保存和加载顶点和边,但图形属性的工作方式不同。

在下面的完整测试编译代码中,我显示:

  • 如何创建一个带有名称的空有向图
  • 设置并获取图表名称
  • 加载并保存图表
  • main: 设置一个图的名字,保存,加载,检查结果是否仍然是那个名字

首先是基础工作:

  • 如何创建一个带有名称的空有向图
  • 设置并获取图表名称

这些函数非常短:

#include <boost/graph/adjacency_list.hpp>
#include <string>

boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t,std::string>
>
create_empty_directed_graph_with_graph_name() noexcept
{
return {};
}

template <typename graph>
void set_graph_name(const std::string& name, graph& g) noexcept
{
get_property(g, boost::graph_name) = name;
}

template <typename graph>
std::string get_graph_name(const graph& g) noexcept
{
return get_property(g, boost::graph_name
);
}

我想要开始的测试:

int main()
{
const std::string dot_filename{"test.dot"};
auto g = create_empty_directed_graph_with_graph_name();
set_graph_name("TestGraph", g);
save_graph_with_graph_name_to_dot(g, dot_filename);
const auto h = load_directed_graph_with_graph_name_from_dot(dot_filename);
assert(get_graph_name(g) == get_graph_name(h));
}

步骤是:(1)设置一个图的名称(2)保存它(3)加载一个图(4)检查它是否具有相同的名称

我质疑的代码是保存。我用这样的名称保存图表:

template <typename graph>
void save_graph_with_graph_name_to_dot(
const graph& g, const std::string& filename
)
{
std::ofstream f(filename);
boost::write_graphviz(
f,
g,
boost::default_writer(),
boost::default_writer(),
[g](std::ostream& os) {
os << "name=\""
<< get_graph_name(g)
<< "\";\n";
}
);
}

我不确定这是不是要走的路。它生成以下 .dot 文件:

digraph G {
name="TestGraph";
}

我想知道它是否不应该改为“digraph TestGraph”,但它被接受为有效的 .dot 文件。

加载这个文件是我卡住的地方。我什至不知道如何让它编译。我确实知道如何(保存和)加载任何类型的边和顶点(请参阅 a Boost.Graph tutorial ),但在这里我迷路了。这是我的尝试:

boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t, std::string>
>
load_directed_graph_with_graph_name_from_dot(
const std::string& dot_filename
)
{
std::ifstream f(dot_filename.c_str());
auto g = create_empty_directed_graph_with_graph_name();

//#define TODO_KNOW_HOW_TO_LOAD_A_GRAPH_ITS_NAME
#ifdef TODO_KNOW_HOW_TO_LOAD_A_GRAPH_ITS_NAME
boost::dynamic_properties p;
p.property("name",get_property(g,boost::graph_name)); //Something like this?
#else
boost::dynamic_properties p(
boost::ignore_other_properties
);
#endif
boost::read_graphviz(f,g,p);
return g;
}

我希望有人知道如何使用名称保存和加载图表。应该不会太难吧?

这是完整的 list :

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/properties.hpp>
#include <cassert>
#include <fstream>
#include <string>

boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t,std::string>
>
create_empty_directed_graph_with_graph_name() noexcept
{
return {};
}

template <typename graph>
void set_graph_name(const std::string& name, graph& g) noexcept
{
get_property(g, boost::graph_name) = name;
}

template <typename graph>
std::string get_graph_name(const graph& g) noexcept
{
return get_property(g, boost::graph_name
);
}

template <typename graph>
void save_graph_with_graph_name_to_dot(
const graph& g, const std::string& filename
)
{
std::ofstream f(filename);
boost::write_graphviz(
f,
g,
boost::default_writer(),
boost::default_writer(),
//Unsure if this results in a graph that can be loaded correctly from a .dot file
[g](std::ostream& os) {
os << "name=\""
<< get_graph_name(g)
<< "\";\n";
}
);
}

boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t, std::string>
>
load_directed_graph_with_graph_name_from_dot(
const std::string& dot_filename
)
{
std::ifstream f(dot_filename.c_str());
auto g = create_empty_directed_graph_with_graph_name();

//#define TODO_KNOW_HOW_TO_LOAD_A_GRAPH_ITS_NAME
#ifdef TODO_KNOW_HOW_TO_LOAD_A_GRAPH_ITS_NAME
boost::dynamic_properties p;
p.property("name",get_property(g,boost::graph_name)); //Something like this?
#else
boost::dynamic_properties p(
boost::ignore_other_properties
);
#endif
boost::read_graphviz(f,g,p);
return g;
}

int main()
{
const std::string dot_filename{"test.dot"};
auto g = create_empty_directed_graph_with_graph_name();
set_graph_name("TestGraph", g);
save_graph_with_graph_name_to_dot(g, dot_filename);
const auto h = load_directed_graph_with_graph_name_from_dot(dot_filename);
assert(get_graph_name(g) == get_graph_name(h));
}

最佳答案

cv_and_he:谢谢!我确实看到了那个页面,但很难阅读它!

答:加载部分的代码需要改成这样:

boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t, std::string>
>
load_directed_graph_with_graph_name_from_dot(
const std::string& dot_filename
)
{
using graph = boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
boost::no_property,
boost::property<boost::graph_name_t, std::string>
>;


std::ifstream f(dot_filename.c_str());
auto g = create_empty_directed_graph_with_graph_name();

boost::ref_property_map<graph*,std::string>
graph_name(get_property(g,boost::graph_name)
);

boost::dynamic_properties dp;
dp.property("name",graph_name);

boost::read_graphviz(f,g,dp);
return g;
}

关于c++ - Boost.Graph:使用名称保存和加载 boost::adjacency_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34544567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com