When reading a graph with read_graphviz()
of the boost graph Library, the internal index used to store the nodes changes compared with the one used to display the same graph. This is problematic when dealing with big graphs as it becomes difficult to compare them as text files.
I wrote a small example (see below the source code), where I start reading a small graph with
INPUT
digraph G {
0[index=0];
1[index=1];
2[index=2];
10[index=10];
}
But then, when printing it with write_graphviz() the output ordering changes:
OUTPUT
digraph G {
0[index=0];
1[index=1];
2[index=10]; /* <= mismatch here ! */
3[index=2]; /* <= and here ! */
}
Although I understand why the node index 10 is reaffected to a smaller value such as all indexes follow each others in ascending order, I don't get why it gets affected index 2 and not 3 as it comes after the index 2 (in input).
I guess that it is because the order used must be somehow a lexicographic order on the index property interpreted as a string, but is this really the case ? In my own program, nodes indexes go above 150 and I get the following reordering:
0[index=0000];
1[index=0001];
2[index=0010];
3[index=0100];
4[index=0101];
5[index=0102];
6[index=0103];
7[index=0104];
8[index=0105];
9[index=0106];
10[index=0107];
11[index=0108];
12[index=0109];
13[index=0011];
14[index=0110];
15[index=0111];
My Question: how can I avoid this behavior such that internal node index always match my own index ?
Here is the code of this simple example:
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
using namespace std;
struct Node { std::size_t index; };
/*! \brief DAG: Directed Acyclic Graph */
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Node> DAG;
template<class IndexMap> class node_writer {
public:
node_writer(IndexMap n) : inm(n) {}
template<class Vertex> void operator()(std::ostream & out, const Vertex & v) {
out << "[index=" << inm[v] << "]";
}
private:
IndexMap inm;
};
template<class IndexMap>
inline node_writer<IndexMap> make_node_writer(IndexMap inm) {
return node_writer<IndexMap>(inm);
}
std::ostream & operator<<(std::ostream & o, const DAG & g) {
boost::write_graphviz(o, g, make_node_writer(boost::get(&Node::index, g)));
return o;
}
std::istream & operator>>(std::istream & i, DAG & g)
{
boost::dynamic_properties dp(boost::ignore_other_properties);
dp.property("index", get(&Node::index, g));
read_graphviz(i, g, dp);
return i;
}
int main(int argc, char * argv[])
{
DAG * pTree = new DAG(0);
std::stringstream dag_file;
dag_file << "digraph G {\n";
dag_file << "0[index=0];\n";
dag_file << "1[index=1];\n";
dag_file << "2[index=2];\n";
dag_file << "10[index=10];\n";
dag_file << "}";
std::cout << dag_file.str() << "\n";
dag_file >> *pTree;
std::cout << *pTree;
return 0;
}