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 ?
Related
I'm writing simple class for undirected graph's representation. Within my class I use adjacency list for graph representation. I would like to add API method, which returns link to some iterable substance, containing vertexes, adjacent to given vertex.
I have the following idea about this method. First - create dynamically allocated std::vector and handle it with shared_ptr. Second - fill vector with proper vertexes numbers and return the link to this vector. So it's prototype looks like:
const std::vector<int>& adjacent(int vertex);
Is it a good idea? Can I do better?
Regards,
Anton
The idea may work, but i strongly recommend you against it. It will be very error prone, and this function definition will look buggy to many other programmers who look at it.
I'd recommend you return vector by value, and do not think about this kind of optimizations until you come to the point where you really need them ( ie - your app is slow, and you are perfectly sure this is the bottleneck ).
If you want to avoid vector copying you can pass vector to this function by reference, so that it will be filled inside.
I need a container to store a value (int) according to two attributes, source (int) and destination (int) i.e. when a source sends something to a destination, I need to store it as an element in a container. The source is identified by a unique int ID (an integer from 0-M), where M is in the tens to hundreds, and so is the destination (0-N). The container will be updated by iterations of another function.
I have been using a vector(vector(int)) which means goes in the order of source(destination(value)). A subsequent process needs to check this container, to see if an element exists in for a particular source, and a particular destination - it will need to differentiate between an empty 'space' and a filled one. The container has the possibility of being very sparse.
The value to be stored CAN be 0 so I haven't had success trying to find out if the space is empty, since I can't seem to do something like container[M][N].empty().
I have no experience with maps, but I have seen another post that suggests a map might be useful, and an std::map<int, int> seems to be similar to a vector<vector<int>>.
To summarise:
Is there a way to check if a specific vector of vector 'space' is empty (since I can't compare it to 0)
Is a std::map<int, int> better for this purpose, and how do I use one?
I need a container to store a value (int) according to two attributes,
source (int) and destination (int)
std::map<std::pair<int, int>, int>
A subsequent process needs to check this container, to see if an
element exists in for a particular source, and a particular
destination - it will need to differentiate between an empty 'space'
and a filled one.
std::map::find
http://www.cplusplus.com/reference/map/map/find/
The container has the possibility of being very sparse.
Use a std::map. The "correct" choice of a container is based on how you need to find things and how you need to insert/delete things. If you want to find things fast, use a map.
First of all, assuming you want an equivalent structure of
vector<vector<int>>
you would want
std::map<int,std::vector<int>>
because for each key in a map, there is one unique value only.
If your sources are indexed very closely sequentially as 0...N, will be doing a lot of look-ups, and few deletions, you should use a vector of vectors.
If your sources have arbitrary IDs that do not closely follow a sequential order or if you are going to do a lot of insertions/deletions, you should use a map<int,vector<int>> - usually implemented by a binary tree.
To check the size of a vector, you use
myvec.size()
To check whether a key exists in a map, you use
mymap.count(ID) //this will return 0 or 1 (we cannot have more than 1 value to a key)
I have used maps for a while and even though I'm nowhere close to an expert, they've been very convenient for me to use for storing and modifying connections between data.
P.S. If there's only up to one destination matching a source, you can proceed with
map<int,int>
Just use the count() method to see whether a key exists before reading it
If you want to keep using a vector but want to add a check for whether the item contains a valid value, look at boost::optional. The type would now be std::vector<std::vector<boost::optional<int>>>.
You can also use a map, but the key into the map needs to be both IDs not just one.
std::map<std::pair<int,int>,int>
Edit: std::pair implements a comparison operator operator< that should be sufficient for use in a map, see http://en.cppreference.com/w/cpp/utility/pair/operator_cmp.
(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".
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!
I'm trying to dynamically add elements to a vector that is contained within a map, to store multiple arrays of "Particle" objects that are mapped to different ids. I'm new to the language and so I'm having trouble understanding if this can only be done with iterators? In this case it feels like overkill. Is it possible to directly access a vector inside a map? Since I can access the map elements by key, and because there is only one vector per key, it seems like it should be possible. I don't really have exact code as an example but it would look something like this:
int currentId = 1;
map <int, vector<Particle> > particleMap;
Particle p;
particleMap[currentId] <access to vector somehow here?> push_back(p);
I'm sure I'm missing some larger concept here, but I find myself needing this type of data structure a lot, so it would be great to know the proper way to access these kinds of "tables."
particleMap[currentId].push_back(p);
will work just fine.
There is only one vector per id; this is what you are referring to with particleMap[currentId]. Then you just continue with the expression as if you were writing myVector.push_back(p).