BGL - changing internal values of a graph
Hi, I'm trying to write a simple graph: // Link and Edge types struct Link { std::string name; }; struct Edge { long count; }; // directed graph typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::directedS, Link, Edge > graph_t; // Vertex and Edge descriptors typedef boost::graph_traits < graph_t >::vertex_descriptor link_d; typedef boost::graph_traits < graph_t >::edge_descriptor edge_d; // Map with all vertexes and links (deduplicate) typedef std::map < std::string, link_d > link_map_t; And my method to add a vertex (which is working well) is: link_d Chain::addVertex (string& name) { link_map_t::iterator pos; link_d descriptor; Link link; bool inserted; // Insert into map boost::tie(pos, inserted) = links.insert(make_pair(name, link_d())); // Insert into graph (or get descriptor) if (inserted) { link.name = name; descriptor = add_vertex(link, graph); pos->second = descriptor; cerr << "Added new vertex: " << graph[descriptor].name << endl; } else { descriptor = pos->second; cerr << "Reused old vertex: " << graph[descriptor].name << endl; } return descriptor; } And my method to connect the edges (which is not working) is: void Chain::addConnection (string subject, string object) { link_d sub, obj; edge_d pred; Edge e; bool inserted, found; // Add vertices sub = addVertex(subject); obj = addVertex(object); // Connect through predicate and increment counter boost::tie(pred, found) = edge (sub, obj, graph); if (found) { e = graph[pred]; cerr << "Old, pred: " << pred << " count: " << e.count << endl; e.count++; } else { e.count = 1; } boost::tie(pred, inserted) = add_edge(sub, obj, e, graph); e = graph[pred]; // Print to see if it was correct cerr << "New, pred: " << pred << " count: " << e.count << "\n" << endl; } By reading a text line "ABABAB." and taking letter by letter and inserting into sub and obj (A,B), (B,A) ... I have the following output: line [ABABAB.] Added new vertex: first Added new vertex: A New, pred: (0,1) count: 1 Reused old vertex: A Added new vertex: B New, pred: (1,2) count: 1 Reused old vertex: B Reused old vertex: A New, pred: (2,1) count: 1 Reused old vertex: A Reused old vertex: B Old, pred: (1,2) count: 1 New, pred: (1,2) count: 2 Reused old vertex: B Reused old vertex: A Old, pred: (2,1) count: 1 New, pred: (2,1) count: 2 Reused old vertex: A Reused old vertex: B Old, pred: (1,2) count: 1 New, pred: (1,2) count: 2 Reused old vertex: B Added new vertex: . New, pred: (2,3) count: 1 Reused old vertex: . Added new vertex: last New, pred: (3,4) count: 1 The creation and reuse of vertices is working pretty well as you can see but the edge, even when reused doesn't have its value updated on a second time. It may be a very stupid problem (not even in BGL) but can you help me find out what's going on? Basically, the following part works while inside the function: if (found) { e = graph[pred]; cerr << "Old, pred: " << pred << " count: " << e.count << endl; e.count++; } I'm getting it again from the graph in order to assure it changed: boost::tie(pred, inserted) = add_edge(sub, obj, e, graph); e = graph[pred]; And even when using a new variable: boost::tie(pred, inserted) = add_edge(sub, obj, e, graph); Edge f; f = graph[pred]; My cerr still produces the correct value. But when I get it a few iterations later the value is 1 again. What's going on? Or better, how to change the value of the structure inside the graph? thanks, --renato
On Jan 30, 2008 3:14 PM, Renato Golin
Hi,
I'm trying to write a simple graph:
// Link and Edge types struct Link { std::string name; };
struct Edge { long count; };
// directed graph typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::directedS, Link, Edge > graph_t; // Vertex and Edge descriptors typedef boost::graph_traits < graph_t >::vertex_descriptor link_d; typedef boost::graph_traits < graph_t >::edge_descriptor edge_d; // Map with all vertexes and links (deduplicate) typedef std::map < std::string, link_d > link_map_t;
And my method to add a vertex (which is working well) is:
link_d Chain::addVertex (string& name) { link_map_t::iterator pos; link_d descriptor; Link link; bool inserted;
// Insert into map boost::tie(pos, inserted) = links.insert(make_pair(name, link_d()));
// Insert into graph (or get descriptor) if (inserted) { link.name = name; descriptor = add_vertex(link, graph); pos->second = descriptor; cerr << "Added new vertex: " << graph[descriptor].name << endl; } else { descriptor = pos->second; cerr << "Reused old vertex: " << graph[descriptor].name << endl; }
return descriptor; }
And my method to connect the edges (which is not working) is:
void Chain::addConnection (string subject, string object) { link_d sub, obj; edge_d pred; Edge e; bool inserted, found;
// Add vertices sub = addVertex(subject); obj = addVertex(object);
// Connect through predicate and increment counter boost::tie(pred, found) = edge (sub, obj, graph); if (found) { e = graph[pred]; cerr << "Old, pred: " << pred << " count: " << e.count << endl; e.count++; } else { e.count = 1; } boost::tie(pred, inserted) = add_edge(sub, obj, e, graph); e = graph[pred];
// Print to see if it was correct cerr << "New, pred: " << pred << " count: " << e.count << "\n" << endl; }
By reading a text line "ABABAB." and taking letter by letter and inserting into sub and obj (A,B), (B,A) ... I have the following output:
line [ABABAB.] Added new vertex: first Added new vertex: A New, pred: (0,1) count: 1
Reused old vertex: A Added new vertex: B New, pred: (1,2) count: 1
Reused old vertex: B Reused old vertex: A New, pred: (2,1) count: 1
Reused old vertex: A Reused old vertex: B Old, pred: (1,2) count: 1 New, pred: (1,2) count: 2
<snip>
The creation and reuse of vertices is working pretty well as you can see but the edge, even when reused doesn't have its value updated on a second time.
It may be a very stupid problem (not even in BGL) but can you help me find out what's going on?
Hi Renato, The sequence of statements: Edge e; e = graph[pred]; e.count++; copies the Edge structure from graph[pred] to e by value, then makes a modification to the copy in e, which is then thrown away when e goes out of scope. Instead, try: graph[pred].count++; Regards, Aaron
Aaron Windsor wrote:
Hi Renato,
The sequence of statements:
Edge e; e = graph[pred]; e.count++;
copies the Edge structure from graph[pred] to e by value, then makes a modification to the copy in e, which is then thrown away when e goes out of scope. Instead, try:
graph[pred].count++;
Oh my, that obviously worked! Thanks! It's the kind of silly things that you need someone else to show you... ;) Thank you! --renato
participants (2)
-
Aaron Windsor
-
Renato Golin