I'm creating graphs from a JSON array file and I'd like it so that when I traverse through both edges and vertices (e.g. in_edges(), vertices() or topological_sort() ) of the graph, it's in the exact same order regardless of the insertion order. In other words, to produce the same graph even if I shuffle the order of the JSON.
The JSON could look like this:
[
{
"ID": 10,
"PARENTS": [2, 1, 85]
},
{
"ID": 1,
"PARENTS": []
},
{
"ID": 99,
"PARENTS": [2]
},
{
"ID": 2,
"PARENTS": []
},
{
"ID": 85,
"PARENTS": [99]
},
]
As an example, if the insertion order was as the example JSON, 10 -> 1 -> 99 -> 2 -> 85, then the parents of 10 would come up as 1 2 85. However, if the insertion order was instead 85 -> 2 -> 1 -> 99 -> 10, then the parents of 10 would come up as 85 2 1. This is what I'd like to avoid.
Right now I'm considering adding a wrapper around a boost graph and sorting the vertices with a set when you call getParent() for example but I wanted to know if there was an easier way to do achieve this with boost natively.
Another possibility is to sort the JSON beforehand but I'd like to avoid that time complexity.
Given the laws of thermodynamics, this cannot be avoided. You explicitly state that you want normalized/canonical results, which means you have to expend the energy to ... normalize the data, regardless of whether it's done in pre- or post-processing.
Prefer to do it early, so the effort is not repeated.
Remember Boost Graph is already deterministic. What you want is to treat the input in normalized fashion. Let's reproduce the issue first, given two JSON documents
doc1anddoc2from the question:If we 1:1 translate these to
boost::adjacency_list<>:We indeed see the different graphs as expected: Live On Coliru
Printing
Preprocessing Nodes
In this case we can very simply cause the nodes to be inserted in a canonical ordering of our choosing by replacing:
with
For simplicity let's go with the default ordering based on each node properties:
Now we get Live On Coliru
BONUS: What About The Adjacencies
You didn't ask, but how about the order of the parents?
Now gives
Live On Coliru
In pre-processing again coercing the adjacencies into an ordered container (Live):