Reputation: 1181
I am trying to modify a specific vertex in my undirected graph. Essentially, I want to be able to start at index 1 of 18, and run an algorithm to change the string of each node from that vertex. I read in a graph from a dot file. I was looking at Bundled Properties at boost's website and it seem straight forward. However, when I try to implement this I get Attempt to put a value into a const property map: Aborted (core dumped)
error. So I find this solution and it looks the exact same as mine.
Here is a minimal example of what is throwing the error:
The File I am reading from test.dot:
graph G {
0 [isLeaf=1];
1 [isLeaf=0];
2 [isLeaf=1];
3 [isLeaf=1];
4 [isLeaf=0];
5 [isLeaf=1];
6 [isLeaf=0];
7 [isLeaf=1];
8 [isLeaf=0];
9 [isLeaf=1];
1--3 [time=3.41843];
1--4 [time=1.01826];
4--5 [time=4.2496];
2--6 [time=5.59155];
1--6 [time=9.48199];
6--7 [time=7.72868];
0--8 [time=7.38977];
4--8 [time=6.55225];
8--9 [time=0.0406912];
}
The code that I am running:
#include <iostream>
#include <string>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/graph_utility.hpp>
struct Vertex
{
bool isLeaf;
std::string taxon;
};
typedef boost::property<boost::edge_weight_t, double> Edge;
typedef boost::adjacency_list<boost::vecS,boost::vecS, boost::undirectedS, Vertex, Edge> Graph;
int main()
{
Graph g;
boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g);
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, g));
dp.property("isLeaf", get(&Vertex::isLeaf, g));
dp.property("time", weight);
std::string blah = "Hello";
std::ifstream dot("test.dot");
boost::read_graphviz(dot,g,dp);
g[1].taxon = blah;
}
What is the reason for this error?
Upvotes: 2
Views: 619
Reputation: 392893
Using vecS
for VertexContainerSelector means you have an implicit vertex index descriptors. They are implicitly the integral index vertex descriptor¹, which happens to be the integral index into the container of vertices.
As such, the standard vertex_index
property is read-only
Thought Experiment: what would writing to it mean?
If you changed the
vertex_index
property of a vertex, should it move around, physically, in memory? What if it overwrites an existing Vertex? What about the old location? Should the container be compacted? But that means that assigning a vertex index to a single vertex potentially changes all other vertex indices etc.)
You can get around that in various ways. Easiest would seem to add a field to the Vertex
bundle to contain the node-id property as read from the input:
#include <iostream>
#include <string>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/graph_utility.hpp>
struct Vertex {
int id;
bool isLeaf;
std::string taxon;
};
typedef boost::property<boost::edge_weight_t, double> Edge;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge> Graph;
int main()
{
Graph g;
boost::property_map<Graph, boost::edge_weight_t>::type weight = get(boost::edge_weight,g);
boost::dynamic_properties dp;
dp.property("node_id", get(&Vertex::id, g));
dp.property("isLeaf", get(&Vertex::isLeaf, g));
dp.property("time", weight);
std::string blah = "Hello";
std::ifstream dot("test.dot");
boost::read_graphviz(dot,g,dp);
g[1].taxon = blah;
}
Upvotes: 1