I'm getting an unrelated error with Boost's Fibonacci Heap when I use the erase()
method:
astar: /usr/include/boost/intrusive/list.hpp:1266: static boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::iterator boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::s_iterator_to(boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::reference) [with ValueTraits = boost::intrusive::bhtraits<boost::heap::detail::heap_node_base<false>, boost::intrusive::list_node_traits<void*>, (boost::intrusive::link_mode_type)1, boost::intrusive::dft_tag, 1>; SizeType = long unsigned int; bool ConstantTimeSize = true; HeaderHolder = void; boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::iterator = boost::intrusive::list_iterator<boost::intrusive::bhtraits<boost::heap::detail::heap_node_base<false>, boost::intrusive::list_node_traits<void*>, (boost::intrusive::link_mode_type)1, boost::intrusive::dft_tag, 1>, false>; boost::intrusive::list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder>::reference = boost::heap::detail::heap_node_base<false>&]: Assertion `!node_algorithms::inited(value_traits::to_node_ptr(value))' failed.
This is the part of the code that triggers the error:
void prune(Node_h* last_sol){
Node_h* elem;
int count = 0;
for(auto it=open.begin(),end=open.end(); it != end; ++it){
elem = *it;
if (handlers.find(elem) == handlers.end()){
printf("KEEEEY NOT FOUND");
} else {
printf("elem->f: %f >= last_sol->f: %f \n",elem->g.second+elem->h.second, last_sol->g.second+last_sol->h.second);
if(elem->g.second+elem->h.second >= last_sol->g.second+last_sol->h.second){
open.erase(handlers[elem]);
count++;
}
}
}
printf("New Open size: %ld ", open.size());
printf("Nodes prune: %d\n", count);
}
I'm saving the handlers in a hash map at the moment of pushing the nodes:
open_handle handler = open.push(succ);
handlers[succ] = handler;
Everything worked fine with the heap until this point (pop and push methods) so I'm puzzled on what could trigger this error, implementation looks accord to the documentation.
Other information:
struct compare_states {
bool operator()(const Node_h* s1, const Node_h* s2) const {
//return n1.id > n2.id;
return s1->f > s2->f ;
}
};
typedef fibonacci_heap<Node_h*,compare<compare_states> >::handle_type open_handle;
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
This loop looks suspect:
Quoting the docs:
That means the
erase
invalidates the loop iterator(s).From context I'm assuming that
handler
/handlers
in your code actually refers to nodehandle
s. If so, you might want to collect handles to be erased in a temporary container before doing the deletion:Live On Compiler Explorer
Prints
For classic node-based containers, the following loop style would be applicable:
However,
fibonacci_heap::erase
returns void.