Determine if a node exists in a Boost binomial_heap - c++

I am trying to determine if an element exists in a boost::heap::binomial_heap because I need to know if I should call update() (if the node already exists) or push() (if the node does not exist). Some queues provide a push_or_update() function for exactly this purpose. The only thing I could figure out to do is keep a property map with the same index type as the nodes in the queue and value_type 'handle_t'. Then I can lookup in the map if the item has a valid handle so that I can push if it does not, or update if it does.
Is there a better way to do this?
Here is the doc for reference.

This is not something a binomial heap is supposed to do.
A usual way to solve your problem would be: use a hash map (or other data structure you like) to store a mapping between values and handles. You can then query the hash map for the handle. If it exists, this handle will let you modify the value in the heap. If it doesn't exist, you can just add a new value to the heap (of course, and a new mapping in the hash map)
Another way to solve the problem is to use a tree set/map, which is easier and may be more efficient than the solution I described above, depending on the actual use case.

Related

Can we have a string tree (in c++)? If not, what is the fastest solution?

Consider the following example:
These are the inputs:
ASED
BTY
ASED->CWD
CWD->DTT
EI->FHK
These are just a string. They have no special meaning. But "->" indicates propagate as a clone. And I want to get DTT's father according to these entries. Is there a faster solution?
I did not ask about coding, I only ask about the method.
It all depends if the tokens (ASED, CWD, etc.) are unique or not. Also, do you want to use only standard C++ libraries or you are open to using additional libraries.
Assuming the tokens are unique, and you want to use standard C++. There are no tree data structures in the standard C++, but in this case you don't need them to address your problem.
Assuming also that a token can have only one parent, you can revert the expression parent -> child to child -> parent (in your algorithm, not in the input list). Once done, you can store the child as a key of a map and the parent as a value. You will need to introduce a stop key as a value (ex. NULL) to signify that the particular key has no parent.
To extract the parent, you will need to fetch the value from the map corresponding to the child, which is the intermediate parent (the link). Next you fetch the intermediate parent to get his parent. This will be repeated until you reach the stop key.
As of complexity of this approach, depends on which type of map you select std::map or std::unordered_map
This algorithm can be slightly modified to support for multiple parents, in which case during the traveling you will travel all possible values for the key you are fetching, which can be done with recursion or with a stack, and you will use std::multimap to store the data.

Wrapping synchronize with ConcurrentHashMap

I have one use case that I need to save the data into a Map. I'm trying to use the concurrentMap
I need to update/extract the value of the record later so that I have to use a Map(Queue, List won't work because I can't extract the value when the collection it self is updated).
Now my question is: Since I need to check the size of the Map before executing, how could I do that? Do I have to wrap map with synchronized or try to lock it? Is there any other way I could do that?

A* whats the best data structure for the open set?

Im developing an A* for the first time, and I was using a priority_queue for the open set, until I realize you need to check if nodes are in the open set too, not just the close one.
Thing is, you cant iterate over a priority queue..So why everyone recommend a priority queue for the open set? Is it yet the best option? I think the only way to iterate over it is making a copy so I can pop everything from it (enormous cost).
What the best data structure to use on A*?
A priority queue (PQ) is an abstract data structure (ADS). There are many possibilities to implement them. Unfortunately, the priority_queue supplied with the C++ standard library is rather limited, and other implementations are suited a lot better for implementing A*. Spoilers: you can use std::set/multiset instead of std::priority_queue. But read on:
So what do you need from the priority queue to implement A* is:
Get the node with the lowest cost
Decrease the costs of arbitrary elements
Any priority queue can do 1., but for 2., you need a "mutable" priority queue. The Standard-Lib one cannot do this. Also, you need an easy way to find entries in the priority queue, to find out where to decrease the keys (For when A* finds a better path to an already opened node). There are two basic ways for this: You store a handle to the priority queue element within your graph node (or use a map to store those handles for each graph node) - or you insert the graph nodes themselves.
For the first case, where you store handles for each node, you can use std::multiset for your priority queue. std::multiset::first() will always be your "lowest cost" key, and you can decrease a key by removing it from the set, changing the value and re-inserting, and updating the handle. Alternatively, you can use the mutable priority queues from Boost.Heap, which directly support "decrease-key".
For the second case, you would need some kind of "intrusive" binary tree - since your pathfinding nodes themselves need to be in the priority queue. If you don't want to roll your own, see the ordered associative containers in Boost.Intrusive.
The subject is very large, I suggest you reading this page if you want to know the different possibilities and have a good understanding of which data structure is adapted to your situation :
http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html#set-representation
In my case, the binary heap was a good balance between difficulty to implement and performances, which was totally what I was looking for. But maybe you are looking for something different ?
The rest of the document is a very good reference for A* for game development
http://theory.stanford.edu/~amitp/GameProgramming/index.html
They mean A priority queue not necessarily the std::priority_queue class that comes with the language. If the built in one doesn't do what you need it to write your own, or find another.

C++: insert into std::map without knowing a key

I need to insert values into std::map (or it's equivalent) to any free position and then get it's key (to remove/modify later). Something like:
std::map<int, std::string> myMap;
const int key = myMap.insert("hello");
Is it possibly to do so with std::map or is there some appropriate container for that?
Thank you.
In addition to using a set, you can keep a list of allocated (or free)
keys, and find a new key before inserting. For a map indexed by
int, you can simply take the last element, and increment its key. But
I rather think I'd go with a simple std::vector; if deletion isn't
supported, you can do something simple like:
int key = myVector.size();
myVector.push_back( newEntry );
If you need to support deletions, then using a vector of some sort of
"maybe" type (boost::optional, etc.—you probably already have
one in your toolbox, maybe under the name of Fallible or Maybe) might be
appropriate. Depending on use patterns (number of deletions compared to
total entries, etc.), you may want to search the vector in order to
reuse entries. If your really ambitious, you could keep a bitmap of the
free entries, setting a bit each time you delete and entry, and
resetting it whenever you reuse the space.
You can add object to an std::set, and then later put the whole set into a map. But no, you can't put a value into a map without a key.
The closest thing to what you're trying to do is probably
myMap[myMap.size()] = "some string";
The only advantage this has over std::set is that you can pass the integer indexes around to other modules without them needing to know the type of std::set<Foo>::iterator or similar.
It is impossible. Such an operation would require intricate knowledge of the key type to know which keys are available. For example, std::map would have to increment int values for int maps or append to strings for string maps.
You could use a std::set and drop keying altogether.
If you want to achieve something similar to automatically generated primary keys in SQL databases than you can maintain a counter and use it to generate a unique key. But perhaps std::set is what you really need.

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!