AI-Pathfinding-SMAstar
view release on metacpan or search on metacpan
lib/AI/Pathfinding/SMAstar/PriorityQueue.pm view on Meta::CPAN
while(1){
while($least_depth == 0){
$avltree = $cost_hash_ref->{$highest_cost_key}; #tree with highest cost
# get the deepest queue in the tree
# so we can use it to step backward to the smallest non-zero
# depth in the following loop
my $queue_at_largest_depth = $$avltree->largest();
$least_depth = $queue_at_largest_depth->key();
$depth_keys_iterator = $$avltree->get_keys_iterator();
# get lowest non-zero key of tree (smallest non-zero depth)
while (defined(my $key = $depth_keys_iterator->())){
#########################################################################
#
# Does this need to be a non-zero depth element? yes. (example: test68.lst)
#
#########################################################################
if($key != 0){
$least_depth = $key;
last;
}
}
# if no non-zero depths, find the next highest key and loop back
my $next_highest_cost_key;
if($least_depth == 0){
$next_highest_cost_key = next_largest_element(\@cost_keys, $highest_cost_key);
$highest_cost_key = $next_highest_cost_key;
if(!$highest_cost_key){
print "no highest_cost_key found\n";
exit;
}
}
else{ # least depth is non-zero, so it's good
last;
}
} # Now have a good highest_cost_key, with a tree that has a good non-zero key queue somewhere in it.
my $queue = $$avltree->get_queue($least_depth); # get the queue at least_depth
my $queue_keys_iterator = $queue->get_keys_iterator();
my $queue_key = $queue_keys_iterator->(); # burn the first value from the iterator since we're getting first object on next line.
$obj = $$avltree->oldest_at($least_depth); # get the shallowest one that is not at zero depth
my $i = 1;
while($compare_func->($obj, $best) || $compare_func->($obj, $succ) || $obj->has_descendants_in_memory()){
if($queue_key = $queue_keys_iterator->()){
$obj = $queue->lookup_by_key($queue_key);
}
else{
# need a new least_depth. check if there are any more queues with non-zero depth in this tree.
# if not, need a new highest_cost_key.
$obj = undef;
my $next_smallest = $depth_keys_iterator->();
if(!defined($next_smallest)){
last;
}
else{
$least_depth = $next_smallest;
$queue = $$avltree->get_queue($least_depth); # get the queue at least_depth
$queue_keys_iterator = $queue->get_keys_iterator();
$queue_key = $queue_keys_iterator->(); # burn the first value from the iterator
$obj = $$avltree->oldest_at($least_depth); # get the shallowest one that is not at zero depth
$i = 1;
next;
}
}
$i++;
} # end while($compare_func->($obj, $best) || $compare_func->($obj, $succ) || $obj->has_descendants_in_memory())
# done loop on last highest_cost_key. if obj is not found, get another highest_cost_key, and loop back again.
if(!$obj){
$least_depth = 0;
$highest_cost_key = next_largest_element(\@cost_keys, $highest_cost_key);
}
else{
last;
}
} # end while(1)
my $obj_str = $str_function->($obj);
$$avltree->remove($obj, $cmp_func->($obj_str));
if($obj){
$self->{_size} = $self->{_size} - 1;
my $antecedent = $obj->{_antecedent};
if($antecedent){
$antecedent->{_descendants_on_queue} = $antecedent->{_descendants_on_queue} - 1;
}
$obj->is_on_queue(0);
if($$avltree->is_empty()){
delete $cost_hash_ref->{$highest_cost_key};
$cost_min_max_tree->remove($highest_cost_key);
}
return $obj;
}
else{
return;
}
}
}
sub largest_element
{
my ($array) = @_;
( run in 1.672 second using v1.01-cache-2.11-cpan-d80b1682f3f )