2015-09-27 69 views
2

对于我的C++程序,我需要使用Boost Graph读取DOT文件,并稍后输出另一个DOT文件。不过,我在读入阶段遇到了一个奇怪的错误,这真的搞砸了我的程序。奇数错误导入DOT文件

我的读入的代码(图形类型是双向升压曲线图的一个typedef)

void readGraph(Graph& graph, string filename) { 

    boost::dynamic_properties dp(boost::ignore_other_properties); 

    ifstream fin(filename.c_str()); 
    boost::read_graphviz(fin, graph, dp); 

} 

好了,所以问题是,在.DOT文件中的节点都在在读错误的订单!我用一个简单的例子.DOT文件试过:

digraph G { 
0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 
0->1; 1->0; 
1->2; 2->1; 
2->3; 3->2; 
3->4; 4->3; 
4->5; 5->4; 
5->6; 6->5; 
6->7; 7->6; 
7->8; 8->7; 
8->9; 9->8; 
9->10; 10->9; 
} 

这是从节点0到节点10的双向链然而,如果我读取使用升压图形,并将其输出该文件没有立即改变,变得:

digraph G { 
0; 
1; 
2; 
3; 
4; 
5; 
6; 
7; 
8; 
9; 
10; 
0->1 ; 
1->3 ; 
3->4 ; 
4->5 ; 
5->6 ; 
6->7 ; 
7->8 ; 
8->9 ; 
9->10 ; 
10->2 ; 
1->0 ; 
3->1 ; 
4->3 ; 
5->4 ; 
6->5 ; 
7->6 ; 
8->7 ; 
9->8 ; 
10->9 ; 
2->10 ; 
} 

请注意,节点2现在无法解释地连接到节点10,并且在链的末端。我已经完成了没有什么在读取和输出图之间。

注:

  • 当我尝试这种更复杂的.DOT文件,图的拓扑结构是一样的,它只是节点已经被交换一些奇怪的原因。

  • 我知道这是一个读,而不是写错误,因为当我在程序期间输出顶点和边时,它们已经搞砸了。

任何人都可以帮助我理解和解决这个问题吗?谢谢。

回答

2

如果你读了图形和打印(在graphviz的格式)再次产生,你会发现图是等价(或同构):

Live On Coliru

#include <boost/graph/graphviz.hpp> 
#include "/Archive2/45/a4410ef1bd3024/main.cpp" // alias <libs/graph/src/read_graphviz_new. 

using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>; 

void readGraph(Graph &graph, std::string filename) { 
    boost::dynamic_properties dp(boost::ignore_other_properties); 

    std::ifstream fin(filename.c_str()); 
    boost::read_graphviz(fin, graph, dp); 
} 

int main() { 
    Graph g; 
    readGraph(g, "input.dot"); 

    boost::write_graphviz(std::cout, g); 
} 

随你输入:

enter image description here

输出显然是异的Morphic:

enter image description here

注意在你自己的问题显示的输出很简单,太!

你真正想要的是顶点ID的保留。

为了做到这一点,您必须显式地将顶点ID(从点文件中读取)存储到属性中。这里有一个例子:

Live On Coliru

#include <boost/graph/graphviz.hpp> 
#include "/Archive2/45/a4410ef1bd3024/main.cpp" // alias <libs/graph/src/read_graphviz_new. 

using namespace boost; 

struct MyVertex { 
    int id; 
}; 

using Graph = adjacency_list< 
    vecS, vecS, directedS, 
    MyVertex 
>; 

void readGraph(Graph &graph, std::string filename) { 
    boost::dynamic_properties dp(boost::ignore_other_properties); 
    dp.property("node_id", boost::get(&MyVertex::id, graph)); 

    std::ifstream fin(filename.c_str()); 
    boost::read_graphviz(fin, graph, dp); 
} 

int main() { 
    Graph g; 
    readGraph(g, "input.dot"); 

    boost::dynamic_properties dp(boost::ignore_other_properties); 
    dp.property("node_id", boost::get(&MyVertex::id, g)); 
    boost::write_graphviz_dp(std::cout, g, dp); 
} 

生成:

enter image description here

1

好吧,所以我做了更多的调查。我修改了读取到的功能是:

void readGraph(Graph& graph, string filename) { 

    boost::dynamic_properties dp(boost::ignore_other_properties); 

    ifstream fin(filename.c_str()); 

    dp.property("node_id", boost::get(&vert::id, graph)); 
    boost::read_graphviz(fin, graph, dp, "node_id"); 

} 

在那里我有我的图表创建的结构

vert { 
    int id; 
} 

为捆绑的属性我的顶点:

typedef boost::adjacency_list<boost::listS, boost::vecS, boost::bidirectionalS, vert, edge> Graph; 

如果我现在使用.id包打印出读入图的所有顶点和边缘:

Graph h; 
readGraph(h, "InputGraph.dot"); 
for(pair<vertexIt, vertexIt> it = boost::vertices(h); it.first != it.second; ++it.first) { 
    cout << h[*it.first].id << endl; 
} 
for(pair<edgeIt, edgeIt> it = boost::edges(h); it.first != it.second; ++it.first) { 
    cout << h[source(*it.first,h)].id << " -> " << h[target(*it.first,h)].id << endl; 
} 

我得到:

0 
1 
10 
2 
3 
4 
5 
6 
7 
8 
9 
0 -> 1 
1 -> 0 
1 -> 2 
2 -> 1 
2 -> 3 
3 -> 2 
3 -> 4 
4 -> 3 
4 -> 5 
5 -> 4 
5 -> 6 
6 -> 5 
6 -> 7 
7 -> 6 
7 -> 8 
8 -> 7 
8 -> 9 
9 -> 8 
9 -> 10 
10 -> 9 

于是我们看到了一个潜在的问题 - 节点已经按字母顺序被读取。我不知道这是如何解释我之前看到的奇怪的2-> 10连接。谢天谢地,.id包存储了节点的真实信息,所以我们只是用它来访问图形。 我仍然认为这是真正愚蠢和不直观的read_graphviz如何解析点文件。

+0

请稍候带自受理这里。我会在稍后时间找到完整的问题。我可能会发现潜在的问题。同时,你可以[搜索我现有的答案](http://stackoverflow.com/search?tab=relevance&q=user%3a85371%20read_graphviz)万一你发现你在做什么不同的事情 – sehe

+0

有没有什么可怕的事情发生毕竟(“虚假的”连接(_node 2现在无法解释地连接到节点10_)在我的答案 – sehe

+0

+ 1-ed中解释,因为我看到你几乎拥有了所有的组件,我只是不同意“这真的很愚蠢,不直观“ - 在阅读的时候,解析器无法知道节点id的类型顺便说一下,如果你有能力改变节点id的格式(例如'02'和'03'),那么就有另一种选择:https://vimeo.com/channels/761265 – sehe