Fruchterman-Reingold的吸引力是如何与Boost图库协同工作的
How does the attractive force of Fruchterman Reingold work with Boost Graph Library
我正在学习Boost图库中的Fruchterman-Reingold算法。通过阅读文档,我知道算法是根据图形布局计算所有节点的位置,但我的问题是我无法理解Boost图库中吸引力的计算步骤。
例如,如果拓扑是高度为100、宽度为100的矩形,则每个顶点被标记为字符串,并且每个对顶点之间的关系为:
"0" "5"
"Kevin" "Martin"
"Ryan" "Leo"
"Y" "S"
"Kevin" "S"
"American" "USA"
每一行表示两个标记的顶点已连接。每个顶点的吸引力公式应该是:
f = (d^2) / k
其中CCD_ 1是两个顶点之间的距离,而CCD_。但我不明白如何在Boost图库中获得Fruchterman-Reingold代码中的距离d
。在本例中,它是否将每对顶点之间的ASCII值差计算为距离d
?(ASCII值"0"为48,ASCII值"5"为53。Fruchterman-Reingold在BGL中计算53-48=5为d,这是真的吗?)如果有人能帮我,我真的很感激。
Furchterman-Reingold实现采用IN/OUT拓扑。
它希望拓扑在执行之前被初始化到某种状态。传递到吸引函数的距离将是在该迭代时从拓扑到的距离。
注意注意(除非
progressive
设置为true
)Furterman Reingold将在默认情况下随机初始化拓扑(使用random_graph_layout
)。
以上所有内容均取自文档。
这里有一个使用输入图的小演示,展示了如何实现这样一个吸引人的force函数:
struct AttractionF {
template <typename EdgeDescriptor, typename Graph>
double operator()(EdgeDescriptor /*ed*/, double k, double d, Graph const& /*g*/) const {
//std::cout << "DEBUG af('" << g[source(ed, g)].name << " -> " << g[target(ed, g)].name << "; k:" << k << "; d:" << d << ")n";
return (d*d/k);
}
};
请参阅Coliru直播
#include <memory>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/fruchterman_reingold.hpp>
#include <boost/graph/random_layout.hpp>
#include <libs/graph/src/read_graphviz_new.cpp>
#include <boost/graph/topology.hpp>
#include <boost/random.hpp>
using namespace boost;
struct Vertex {
std::string name;
};
struct AttractionF {
template <typename EdgeDescriptor, typename Graph>
double operator()(EdgeDescriptor /*ed*/, double k, double d, Graph const& /*g*/) const {
//std::cout << "DEBUG af('" << g[source(ed, g)].name << " -> " << g[target(ed, g)].name << "; k:" << k << "; d:" << d << ")n";
return (d*d/k);
}
};
using Graph = adjacency_list<vecS, vecS, undirectedS, Vertex>;
Graph make_sample();
int main() {
auto g = make_sample();
using Topology = square_topology<boost::mt19937>;
using Position = Topology::point_type;
std::vector<Position> positions(num_vertices(g));
square_topology<boost::mt19937> topology;
random_graph_layout(g,
make_iterator_property_map(positions.begin(), boost::identity_property_map{}),
topology);
fruchterman_reingold_force_directed_layout(
g,
make_iterator_property_map(positions.begin(), boost::identity_property_map{}),
topology,
attractive_force(AttractionF())
);
dynamic_properties dp;
dp.property("node_id", get(&Vertex::name, g));
write_graphviz_dp(std::cout, g, dp);
}
Graph make_sample() {
std::string const sample_dot = R"(
graph {
"0" -- "5";
"Kevin" -- "Martin";
"Ryan" -- "Leo";
"Y" -- "S";
"Kevin" -- "S";
"American" -- "USA";
}
)";
Graph g;
dynamic_properties dp;
dp.property("node_id", get(&Vertex::name, g));
read_graphviz(sample_dot, g, dp);
return g;
}
请注意,在c++11中,您同样可以很好地使用lambda:
fruchterman_reingold_force_directed_layout(
g,
make_iterator_property_map(positions.begin(), boost::identity_property_map{}),
topology,
attractive_force([](Graph::edge_descriptor, double k, double d, Graph const&) { return (d*d)/k; })
);
相关文章:
- 我不明白参数和参数如何协同工作
- Qt C++括号匹配和突出显示当前线路功能无法协同工作
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- Emrun 和无头铬 - 如何让这两者协同工作?
- 如何编译Freetype(2)和Harfbuzz(带有Visual studio)使它们协同工作?
- 如果我将作品张贴到线程池,并且线程已经在Boost中工作,会发生什么
- 模板类实例化如何与类继承协同工作
- 如何将RegisterDragDrop,RoInitialize组合在一个线程中协同工作
- 与boost::property_tree XML解析器一起使用时,boost::协同程序库崩溃
- 如何让助推upgrade_to_unique_lock+condition_variable协同工作
- Fruchterman-Reingold的吸引力是如何与Boost图库协同工作的
- 如何使Ws2_32.lib与针对Windows 8.1的VS 2013项目协同工作
- 在linux下使用boost::thread创建一个boost::asio工作线程
- 如何在C++中使一个void函数与另一个void功能协同工作
- std::transform 和 std::p lus 如何协同工作
- 无法让 cgal 和 hdf5 协同工作
- std::ref 和交换功能似乎不能很好地协同工作
- 阻止Boost Asio工作线程
- 类的详细信息:设计一组协同工作的类时出错
- 如何使这两个模板类协同工作?(C++中的属性)