AI-Pathfinding-SMAstar

 view release on metacpan or  search on metacpan

lib/AI/Pathfinding/SMAstar/PriorityQueue.pm  view on Meta::CPAN

    }

    my $compare_func = sub{
	my ($obj1, $obj2) = @_;
	my $obj1_str = $str_function->($obj1);
	my $obj2_str = $str_function->($obj2);	
	if($obj1_str eq $obj2_str){
	    return 1;
	}
	return 0;
    };
    
    my $cmp_func = sub {
	my ($phrase) = @_;			
	return sub{
	    my ($obj) = @_;
	    my $obj_phrase = $str_function->($obj);
	    if($obj_phrase eq $phrase){
		return 1;
	    }
	    else{ 
		return 0; 
	    }	    
	}
    };	

    # get the highest cost from @cost_keys
  
    my $highest_cost_key = $cost_min_max_tree->largest();
    if(!$highest_cost_key){
	croak "shallowest_highest_cost_leaf_dont_remove: object not found in min-max heap\n";
    }

    if(!$cost_hash_ref->{$highest_cost_key}){
	# no tree for this cost.	     
	croak "shallowest_highest_cost_leaf: no tree at key $highest_cost_key\n";
	return;
    }
    else{
	my $least_depth = 0;
	my $avltree;
	my $depth_keys_iterator;

	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++;



( run in 0.483 second using v1.01-cache-2.11-cpan-39bf76dae61 )