Should I use boost::property_map? - c++

(Apologies for the title, I couldn't come up with a good one shorter than 140 characters...)
I'm writing a graph algorithm for the boost::graph library. Within my algorithm, I need to keep variables, weights and counters, about the nodes. The typical way to do this, as far as I can tell from documentation and looking at other people's code, would be to attach these properties to the graph directly and access them with property maps.
In a library function however, I don't want to require a specific read/write-map to be bundled with the graph, so I create my own external property maps. But these require a std::map (or equivalent), so I end up creating both a std::map and a boost::associative_property_map<std::map>. The good thing about this is that I have a uniform way of getting both my algorithm's properties and the user's properties (boost::get), but on the downside, I seem to have two redundant maps. Is there any meaning in doing this besides mentioned uniformity? Can I somehow let the property map maintain it's own internal map (I realize there would be no gain in memory etc, but there would be one less member variable to keep track of per property)?

In a nutshell, create a map m and an associative property map pm using m and you won't generate a redundancy. More information follows.
boost::associative_property_map does not create a new map. It only references another map and makes it accessible through the boost property_map API (get & put).
See the documented example here.
If you go and have a look at the constructor for associative_property_map, you'll see that it takes a reference to a container and stores its address as a pointer (m_c). Look here and search the file for "associative_property_map".

Related

In BGL, how to efficiently find an adjacent vertex using a property of a vertex

I’m having a bidirectional graph (i.e. a directed graph in which it is possible to iterate both the in-edges and the out-edges).
Each vertex, among other internal properties, has a special ID property which is an integer from a finite set (couple of hundreds) which is known at program's startup, that is – it won’t change during program's life time, but it is unknown at compile time.
This property is not unique at the scope of the graph (i.e. there can be two Vertices with the same ID), and therefore cannot be used with named/labeled_graph. It is however unique in the scope of a given Vertex, that is both the incoming neighbors and the outgoing neighbors of a vertex should all have different IDs.
My question is whether there is a build in mechanism in BGL to efficiently find an adjacent vertex u, of v given u’s descriptor, the graph, and the ID of u.
This can of course be achieve using some external mapping, but it feels like quite a common scenario, and given that the adjacency_list’s first template parameter can be an associative container – it seems only natural to have some kind of find_adjacent(v,g,ID) function, alas, I wasn’t able to find anything like it.
Many thanks,
Andrey
You don't post a sample, but from the description given you could select an ordered set for the OutEdgeList and order it by the target vertex ID (which is unique in that scope).
Now you can use std::lower_bound/std::upper_bound/std::equal_range on the out_edges of any given node.
If you prefer you can easily add free functions like find_adjacent to hide the implementation.

Boost Graph Library dynamic edges weights

I'm wondering if it's possible to make dynamic edges weights in BGL? I'm writing public transport navigator so except time as weight it would be nice if I can promote actualy using line instead of change at every stop event if it would be 3 minutes faster - this is just inconvenient.
Thanks for your help
edit:
Or maybe there is better library than can do that which I should use?
I'm not entirely clear on what you mean by dynamic... the weights are presumably stored in edge properties; there's nothing to stop you updating the properties with new values as required.
If you mean that you want the edge weights to be a function-object (or "functor", if you must) rather than "just a value", then see this thread on the BGL users list; haven't tried it myself. Makes me wonder how well various graph algorithms using edge weights deal with the weights changing while they're in progress (if the functor is called more than once and returns a different value each time)...

Copying a boost::property_map into a boost::vector_property_map

When calling boost::get on a graph, the return type is boost::associative_property_map<Graph, PropertyType>. I'd like to get a copy of this map, and I'd like to store it in a boost::vector_property_map. However, they are not compatible enough to allow simply assigning to the vector map. Looking at the source of property_map, it seems boost::associative_property_map does not have any access methods at all (the vector variety at least exposes "storage iterators").
Is there a way? Or do I have to find the keys somehow and loop over them?
I am sorry, but simply using boost::associative_property_map, you won't be able to retrieve iterators over contained items. You must use an alternate way to iterate over them -- iterate over edges or vertices, i guess, and put them into a boost::vector_property_map.
But if you have to do that, it means you are deconstructing the whole idea of having the common interface that property maps provide. Can't you templatize the algorithm which currently needs vector_property_map to have it accept other property_map types ?

What's the best way to search from several map<key,value>?

I have created a vector which contains several map<>.
vector<map<key,value>*> v;
v.push_back(&map1);
// ...
v.push_back(&map2);
// ...
v.push_back(&map3);
At any point of time, if a value has to be retrieved, I iterate through the vector and find the key in every map element (i.e. v[0], v[1] etc.) until it's found. Is this the best way ? I am open for any suggestion. This is just an idea I have given, I am yet to implement this way (please show if any mistake).
Edit: It's not important, in which map the element is found. In multiple modules different maps are prepared. And they are added one by one as the code progresses. Whenever any key is searched, the result should be searched in all maps combined till that time.
Without more information on the purpose and use, it might be a little difficult to answer. For example, is it necessary to have multiple map objects? If not, then you could store all of the items in a single map and eliminate the vector altogether. This would be more efficient to do the lookups. If there are duplicate entries in the maps, then the key for each value could include the differentiating information that currently defines into which map the values are put.
If you need to know which submap the key was found in, try:
unordered_set<key, pair<mapid, value>>
This has much better complexity for searching.
If the keys do not overlap, i.e., are unique througout all maps, then I'd advice a set or unordered_set with a custom comparision functor, as this will help with the lookup. Or even extend the first map with the new maps, if profiling shows that is fast enough / faster.
If the keys are not unique, go with a multiset or unordered_multiset, again with a custom comparision functor.
You could also sort your vector manually and search it with a binary_search. In any case, I advice using a tree to store all maps.
It depends on how your maps are "independently created", but if it's an option, I'd make just one global map (or multimap) object and pass that to all your creators. If you have lots of small maps all over the place, you can just call insert on the global one to merge your maps into it.
That way you have only a single object in which to perform lookup, which is reasonably efficient (O(log n) for multimap, expected O(1) for unordered_multimap).
This also saves you from having to pass raw pointers to containers around and having to clean up!

How can one create cyclic (and immutable) data structures in Clojure without extra indirection?

I need to represent directed graphs in Clojure. I'd like to represent each node in the graph as an object (probably a record) that includes a field called :edges that is a collection of the nodes that are directly reachable from the current node. Hopefully it goes without saying, but I would like these graphs to be immutable.
I can construct directed acyclic graphs with this approach as long as I do a topological sort and build each graph "from the leaves up".
This approach doesn't work for cyclic graphs, however. The one workaround I can think of is to have a separate collection (probably a map or vector) of all of the edges for an entire graph. The :edges field in each node would then have the key (or index) into the graph's collection of edges. Adding this extra level of indirection works because I can create keys (or indexes) before the things they (will) refer to exist, but it feels like a kludge. Not only do I need to do an extra lookup whenever I want to visit a neighboring node, but I also have to pass around the global edges collection, which feels very clumsy.
I've heard that some Lisps have a way of creating cyclic lists without resorting to mutation functions. Is there a way to create immutable cyclic data structures in Clojure?
You can wrap each node in a ref to give it a stable handle to point at (and allow you to modify the reference which can start as nil). It is then possible to possible to build cyclic graphs that way. This does have "extra" indirection of course.
I don't think this is a very good idea though. Your second idea is a more common implementation. We built something like this to hold an RDF graph and it is possible to build it out of the core data structures and layer indices over the top of it without too much effort.
I've been playing with this the last few days.
I first tried making each node hold a set of refs to edges, and each edge hold a set of refs to the nodes. I set them equal to each other in a (dosync... (ref-set...)) type of operation. I didn't like this because changing one node requires a large amount of updates, and printing out the graph was a bit tricky. I had to override the print-method multimethod so the repl wouldn't stack overflow. Also any time I wanted to add an edge to an existing node, I had to extract the actual node from the graph first, then do all sorts of edge updates and that sort of thing to make sure everyone was holding on to the most recent version of the other thing. Also, because things were in a ref, determining whether something was connected to something else was a linear-time operation, which seemed inelegant. I didn't get very far before determining that actually performing any useful algorithms with this method would be difficult.
Then I tried another approach which is a variation of the matrix referred to elsewhere. The graph is a clojure map, where the keys are the nodes (not refs to nodes), and the values are another map in which the keys are the neighboring nodes and single value of each key is the edge to that node, represented either as a numerical value indicating the strength of the edge, or an edge structure which I defined elsewhere.
It looks like this, sort of, for 1->2, 1->3, 2->5, 5->2
(def graph {node-1 {node-2 edge12, node-3 edge13},
node-2 {node-5 edge25},
node-3 nil ;;no edge leaves from node 3
node-5 {node-2 edge52}) ;; nodes 2 and 5 have an undirected edge
To access the neighbors of node-1 you go (keys (graph node-1)) or call the function defined elsewhere (neighbors graph node-1), or you can say ((graph node-1) node-2) to get the edge from 1->2.
Several advantages:
Constant time lookup of a node in the graph and of a neighboring node, or return nil if it doesn't exist.
Simple and flexible edge definition. A directed edge exists implicitly when you add a neighbor to a node entry in the map, and its value (or a structure for more information) is provided explicitly, or nil.
You don't have to look up the existing node to do anything to it. It's immutable, so you can define it once before adding it to the graph and then you don't have to chase it around getting the latest version when things change. If a connection in the graph changes, you change the graph structure, not the nodes/edges themselves.
This combines the best features of a matrix representation (the graph topology is in the graph map itself not encoded in the nodes and edges, constant time lookup, and non-mutating nodes and edges), and the adjacency-list (each node "has" a list of its neighboring nodes, space efficient since you don't have any "blanks" like a canonical sparse matrix).
You can have multiples edges between nodes, and if you accidentally define an edge which already exists exactly, the map structure takes care of making sure you are not duplicating it.
Node and edge identity is kept by clojure. I don't have to come up with any sort of indexing scheme or common reference point. The keys and values of the maps are the things they represent, not a lookup elsewhere or ref. Your node structure can be all nils, and as long as it's unique, it can be represented in the graph.
The only big-ish disadvantage I see is that for any given operation (add, remove, any algorithm), you can't just pass it a starting node. You have to pass the whole graph map and a starting node, which is probably a fair price to pay for the simplicity of the whole thing. Another minor disadvantage (or maybe not) is that for an undirected edge you have to define the edge in each direction. This is actually okay because sometimes an edge has a different value for each direction and this scheme allows you to do that.
The only other thing I see here is that because an edge is implicit in the existence of a key-value pair in the map, you cannot define a hyperedge (ie one which connects more than 2 nodes). I don't think this is a big deal necessarily since most graph algorithms I've come across (all?) only deal with an edge that connects 2 nodes.
I ran into this challenge before and concluded that it isn't possible using truly immutable data structures in Clojure at present.
However you may find one or more of the following options acceptable:
Use deftype with ":unsynchronized-mutable" to create a mutable :edges field in each node that you change only once during construction. You can treat it as read-only from then on, with no extra indirection overhead. This approach will probably have the best performance but is a bit of a hack.
Use an atom to implement :edges. There is a bit of extra indirection, but I've personally found reading atoms to be extremely efficient.