我是新手来推广图表,正在研究最适合我需求的图表。我需要创建一个依赖图并给出一个顶点,我需要访问进出边。我正在考虑使用Directed = bidirectionalS的adjacency_list。
但是我需要确保当我调用add_edge并导致循环引用时它必须输出错误。我似乎无法找到如何做到这一点。
答案 0 :(得分:2)
一般来说,只有一种方法可以发现图形是否是一个循环:遍历所有节点。
因此,您只需要在添加每条边后检查图形是否仍然是循环的。
但是,根据您添加节点的方式,您可以进行优化。如果,例如通过遍历DFS顺序的源节点来添加边缘,您可以只跟踪节点"看到"在当前路径中并拒绝为这些路径添加边缘。
基于topological_sort
Live On Coliru 的简单示例:
#include <iostream> // for std::cout
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/function_output_iterator.hpp>
using namespace boost;
int main()
{
srand(time(0));
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
const int num_vertices = 10;
Graph g(num_vertices);
// add random edges to the graph object
for (size_t i = 0; i < 10; ++i)
{
auto f = rand()%num_vertices,
s = rand()%num_vertices;
add_edge(f, s, g);
try {
topological_sort(g, boost::make_function_output_iterator([](int){}));
} catch(not_a_dag const& e)
{
remove_edge(f, s, g);
std::cerr << "dropped edge: " << e.what() << "\n";
}
}
write_graphviz(std::cout, g);
}
创建像
这样的随机DAG
答案 1 :(得分:0)
在增强图中,双向表示边将具有源顶点和目标顶点。 以下是它的例子:
#include <QtCore/QCoreApplication>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/subgraph.hpp>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
using namespace std;
using namespace boost;
typedef boost::subgraph<boost::adjacency_list< boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_index_t, int , property<boost::vertex_color_t, boost::default_color_type > > ,
boost::property<boost::edge_index_t,int, property<boost::edge_color_t , default_color_type> > > >
Graph;
const int num_vertices = 5;
Graph g(num_vertices);
add_edge(0, 1, g);
add_edge(1, 2, g);
add_edge(1, 3, g);
add_edge(2, 4, g);
add_edge(3, 4, g);
boost::graph_traits<Graph>::vertex_iterator VertexItr, VertexItr_end;
boost::graph_traits<Graph>::in_edge_iterator in, in_end;
boost::graph_traits<Graph>::out_edge_iterator out,out_end;
typedef boost::graph_traits < Graph >::adjacency_iterator adjacency_iterator;
// This loop is for getting in edges at vertex
cout<<"In Edge :- "<<endl;
for(boost::tie(VertexItr,VertexItr_end) = vertices(g); VertexItr != VertexItr_end; ++VertexItr) {
cout << *VertexItr << " <-- ";
for (boost::tie(in,in_end) = in_edges(*VertexItr, g); in != in_end; ++in)
cout << source(*in, g) << " ";
cout << endl;
}
// This loop is for getting out edges from vertex
cout<<endl<<"Out Edge :- "<<endl;
for(boost::tie(VertexItr,VertexItr_end) = vertices(g); VertexItr != VertexItr_end; ++VertexItr) {
cout<<*VertexItr<<"--->";
for (boost::tie(out,out_end) = out_edges(*VertexItr, g); out != out_end; ++out)
cout << target(*out, g) << " ";
cout << endl;
}
// This loop is for getting the neighbour vertices of vertex
typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexMap;
IndexMap index = get(boost::vertex_index, g);
cout<<"Adjacent vertices"<<endl;
for(boost::tie(VertexItr,VertexItr_end) = vertices(g); VertexItr != VertexItr_end; ++VertexItr) {
cout<<*VertexItr<<"--->";
std::pair<adjacency_iterator, adjacency_iterator> neighbors =
boost::adjacent_vertices(vertex(*VertexItr,g), g);
for(; neighbors.first != neighbors.second; ++neighbors.first)
{
std::cout << index[*neighbors.first] << " ";
}
cout<<endl;
}
return a.exec();
}
答案 2 :(得分:0)
我在boost文档中找到了讨论如何检测依赖关系的这一部分:
http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/file_dependency_example.html#sec:cycles
但是对于adjacency_list,VertexList和EdgeList必须是vecS类型。这里有关于此的讨论: How to print a boost graph in graphviz with one of the properties displayed?