view release on metacpan or search on metacpan
lib/AI/Pathfinding/SMAstar.pm view on Meta::CPAN
# get the best candidate for expansion from the queue
$best = $$priority_queue->deepest_lowest_cost_leaf_dont_remove();
#------------------------------------------------------
if(!$DEBUG){
my $str = $log_function->($best);
$show_prog_func->($iteration, $num_states_in_queue, $str);
}
else{
my $str = $log_function->($best);
print "best is: " . $str_function->($best) . ", cost: " . $best->{_f_cost} . "\n";
}
#------------------------------------------------------
if($best->$goal_p()) {
# goal achieved! iteration: $iteration, number of
# states in queue: $num_states_in_queue.
return $best;
}
elsif($best->{_f_cost} >= $max_cost){
lib/AI/Pathfinding/SMAstar.pm view on Meta::CPAN
}
else{
croak "Error: no successor to insert\n";
}
}
}
continue {
$iteration++;
}
print "\n\nreturning unsuccessfully. iteration: $iteration\n";
return;
}
}
sub max
{
my ($n1, $n2) = @_;
return ($n1 > $n2 ? $n1 : $n2);
}
sub fp_compare {
my ($a, $b, $dp) = @_;
my $a_seq = sprintf("%.${dp}g", $a);
my $b_seq = sprintf("%.${dp}g", $b);
if($a_seq eq $b_seq){
return 0;
}
elsif($a_seq lt $b_seq){
return -1;
}
else{
lib/AI/Pathfinding/SMAstar/AVLQueue.pm view on Meta::CPAN
sub get_size{
my ($self) = @_;
my $avltree = $self->{_avltree};
my $size = $avltree->get_size();
return $size;
}
sub print{
my ($self, $delim) = @_;
my @tree_elts = $self->{_avltree}->get_list();
foreach my $obj (@tree_elts){
print $obj->{_start_word} . ", " . $obj->{_phrase} . ", " . $obj->{_queue_counter} . "\n";
}
print "\n\nobj_counts_tree:\n";
$self->{_obj_counts_tree}->print("*");
my $iterator = $self->{_obj_counts_tree}->get_keys_iterator();
print "\n\niterator keys:\n";
while(defined(my $key = $iterator->())){
print "iterator key: $key\n";
}
}
1;
lib/AI/Pathfinding/SMAstar/Examples/PalUtils.pm view on Meta::CPAN
{ my %memo_cache;
sub word_collision_memo
{
my ($word,
$sorted_letters_seen) = @_;
my $sorted_letters_seen_str = join('', @$sorted_letters_seen);
my $memo_key = $word . $sorted_letters_seen_str;
#print "sorted_letters_seen_str: $sorted_letters_seen_str\n";
if($memo_cache{$memo_key}){
return @{$memo_cache{$memo_key}};
}
else{
my @letters = split('', $word);
my @difference = ();
my %letters_hash = ();
my %letters_seen_hash = ();
lib/AI/Pathfinding/SMAstar/Examples/PalUtils.pm view on Meta::CPAN
{
my ($word, $dictionary_rev) = @_;
my $cand = AI::Pathfinding::SMAstar::Examples::WordObj->new(
_word => $word
);
my $cache_key = $word . $dictionary_rev;
my $cached_vals = $memo_hash_ref->{$cache_key};
if($cached_vals){
#print $spaces . "DING DING DING. cache hit!\n";
return @$cached_vals;
}
else{
my @substr_cands = get_substrs_memo($word, $dictionary_rev);
my @superstr_cands = $dictionary_rev->acc_lookup_memo($cand,
\&AI::Pathfinding::SMAstar::Examples::WordObj::compare_up_to,
\&AI::Pathfinding::SMAstar::Examples::WordObj::compare);
my @cands = (@substr_cands, @superstr_cands);
lib/AI/Pathfinding/SMAstar/Examples/PalUtils.pm view on Meta::CPAN
{
my ($word, $dictionary) = @_;
my @words;
my @matches;
my $cache_key = $word . $dictionary;
my $cached_vals = $memo_hash_ref->{$cache_key};
if($cached_vals1){
#print $spaces . "DING DING DING. cache hit!\n";
return @$cached_vals;
}
else{
for(my $i = 1; $i < length($word); $i++){
push(@words, substr($word, 0, $i));
}
foreach my $substring (@words){
#print "looking for matches on: \"$substring\"\n";
my $cand = AI::Pathfinding::SMAstar::Examples::WordObj->new(
_word => $substring
);
my $match_word = $dictionary->lookup($cand, \&AI::Pathfinding::SMAstar::Examples::WordObj::compare);
if($match_word){
# print "FOUND A MATCH: $match_word\n";
push(@matches, $match_word);
}
}
#print "no hashed value yet, creating one.\n";
$memo_hash_ref->{$cache_key} = \@matches;
return @matches;
}
}
}
sub get_substrs
{
my ($word, $dictionary) = @_;
my @words;
my @matches;
for(my $i = 1; $i < length($word); $i++){
push(@words, substr($word, 0, $i));
}
foreach my $substring (@words){
#print "looking for matches on: \"$substring\"\n";
my $cand = AI::Pathfinding::SMAstar::Examples::WordObj->new(
_word => $substring
);
my $match_word = $dictionary->lookup($cand, \&AI::Pathfinding::SMAstar::Examples::WordObj::compare);
if($match_word){
# print "FOUND A MATCH: $match_word\n";
push(@matches, $match_word);
}
}
return @matches;
}
# randomize an array. Accepts a reference to an array.
lib/AI/Pathfinding/SMAstar/Examples/PalUtils.pm view on Meta::CPAN
}
elsif($state == 2){
$spinny_thing = "|";
}
elsif($state == 3){
$spinny_thing = "/";
}
my ($progress) = @_;
my $stars = '*' x int($progress*10);
my $percent = sprintf("%.2f", $progress*100);
$percent = $percent >= 100 ? '100.00%' : $percent.'%';
print("\r$stars $spinny_thing $percent.");
flush(STDOUT);
}
}
sub show_search_depth_and_percentage {
my ($depth, $so_far, $total) = @_;
my $stars = '*' x int($depth);
my $amount_completed = $so_far/$total;
my $percentage = sprintf("%0.2f", $amount_completed*100);
print("\r$stars depth: $depth. completed: $percentage %");
flush(STDOUT);
}
sub show_search_depth_and_num_states {
my ($depth, $states) = @_;
my $stars = '*' x int($depth);
my $num_states = @$states;
print("\rdepth: $depth. num_states: $num_states");
flush(STDOUT);
}
{my $LINES=`tput lines`; # number of rows in current terminal window
my $COLUMNS=`tput cols`; # number of columns in current terminal window
sub show_progress_so_far {
my ($iteration, $num_states, $str, $opt_datum, $opt_datum2) = @_;
my $stars = '*' x int($iteration);
# print "\e[H"; # Put the cursor on the first line
# print "\e[J"; # Clear from cursor to end of screen
# print "\e[H\e[J"; # Clear entire screen (just a combination of the above)
# print "\e[K"; # Clear to end of current line (as stated previously)
# print "\e[m"; # Turn off character attributes (eg. colors)
# printf "\e[%dm", $N; # Set color to $N (for values of 30-37, or 100-107)
# printf "\e[%d;%dH", $R, $C; # Put cursor at row $R, column $C (good for "drawing")
#print "\e[H\e[J"; #clears the entire screen
printf "\e[%d;%dH", $LINES-1, 1; # Put cursor at row $R, column $C (good for "drawing")
print "\e[J"; #clears to end of screen
if($num_states > $max_nodes_in_mem){
$max_nodes_in_mem = $num_states;
}
print "\riteration: $iteration, num_states_in_memory: $num_states, max_states_in_mem: $max_nodes_in_mem\n";
printf "\e[%d;%dH", $LINES, 1; # Put cursor at row $R, column $C (good for "drawing")
print "\e[J"; #clears to end of screen
print "string: $str\e[J";
flush(STDOUT);
}
}
sub show_search_depth_and_num_states_debug {
}
{my $LINES=`tput lines`; # number of rows in current terminal window
my $COLUMNS=`tput cols`; # number of columns in current terminal window
sub show_progress_so_far_debug {
my ($depth, $prog, $num_states, $str, $num_successors) = @_;
my $stars = '*' x int($depth);
print "depth: $depth, string: $str, num_successors: $num_successors\n";
flush(STDOUT);
}
}
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
_repeated_pal_hash_ref => $repeated_pal_hash_ref,
_letters_seen => \@sorted_letters_seen,
_cost => $newcost,
_cost_so_far => $new_cost_so_far,
_num_chars_so_far => $new_num_chars_so_far,
_num_new_chars => $num_new_chars,
_no_match_remainder => 1,
_depth => $depth+1,
);
#print "returning new phrase from first cond.\n";
$new_phrase->{_phrase} = $new_phrase->roll_up_phrase();
return $new_phrase;
}
else{
my $c = shift(@cands);
if(!$c){
return;
}
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
# ------------- filter for repeated palcands for a particular word------
# ----------------------------------------------------------------------
# This will avoid many repeated patterns among palindromes to trim down the
# number redundant palindromes generated.
#
my $letters_seen_str = join("", @{$phrase_obj->{_letters_seen}});
if($letters_seen_str){
my $repeated_pal_hash_key;
$repeated_pal_hash_key = $word . "^" . $c . "^" . $letters_seen_str;
#print "\n\nrepeated_pal_hash_key: $repeated_pal_hash_key\n";
if(my $hash_val = $repeated_pal_hash_ref->{$repeated_pal_hash_key}){
# skip because '$word' <--> '$p' pattern has already appeared in a previous palindrome.
if($hash_val != $depth){
goto LABEL1;
# next; # skip
}
}
else{
#flag this candidate as already having been tested (below).
$repeated_pal_hash_ref->{$repeated_pal_hash_key} = $depth;
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
_predecessor => $phrase_obj,
_dir => $new_direction,
_repeated_pal_hash_ref => $repeated_pal_hash_ref,
_letters_seen => \@sorted_letters_seen,
_cost => $newcost,
_cost_so_far => $new_cost_so_far,
_num_chars_so_far => $new_num_chars_so_far,
_num_new_chars => $num_new_chars,
_depth => $depth+1,
);
#print "returning new phrase from second cond.\n";
$new_phrase->{_phrase} = $new_phrase->roll_up_phrase();
return $new_phrase;
}
else{
#
# There is no match_remainder, so this candidate is the reverse
# of $word, or the phrase built so far is an "even" palindrome,
# i.e. it has a word boundary (space) in the middle.
#
#
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
_repeated_pal_hash_ref => $repeated_pal_hash_ref,
_letters_seen => \@sorted_letters_seen,
_cost => $newcost,
_cost_so_far => $new_cost_so_far,
_num_chars_so_far => $new_num_chars_so_far,
_num_new_chars => $num_new_chars,
_no_match_remainder => 1,
_depth => $depth+1,
);
#print "returning new phrase from third cond.\n";
$new_phrase->{_phrase} = $new_phrase->roll_up_phrase();
return $new_phrase;
}
}
}
}
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
# ------------- filter for repeated palcands for a particular word------
# ----------------------------------------------------------------------
# This will avoid many repeated patterns among palindromes to trim down the
# number redundant palindromes generated.
#
my $letters_seen_str = join("", @{$phrase_obj->{_letters_seen}});
if($letters_seen_str){
my $repeated_pal_hash_key;
$repeated_pal_hash_key = $word . "^" . $c . "^" . $letters_seen_str;
#print "\n\nrepeated_pal_hash_key: $repeated_pal_hash_key\n";
if(my $hash_val = $repeated_pal_hash_ref->{$repeated_pal_hash_key}){
# skip because '$word' <--> '$p' pattern has already appeared in a previous palindrome.
if($hash_val != $depth){
next; #skip
}
}
else{
#flag this candidate as already having been tested (below).
$repeated_pal_hash_ref->{$repeated_pal_hash_key} = $depth;
}
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
# ------------- filter for repeated palcands for a particular word------
# ----------------------------------------------------------------------
# This will avoid many repeated patterns among palindromes to trim down the
# number redundant palindromes generated.
#
my $letters_seen_str = join("", @{$phrase_obj->{_letters_seen}});
if($letters_seen_str){
my $repeated_pal_hash_key;
$repeated_pal_hash_key = $word . "^" . $c . "^" . $letters_seen_str;
#print "\n\nrepeated_pal_hash_key: $repeated_pal_hash_key\n";
if(my $hash_val = $repeated_pal_hash_ref->{$repeated_pal_hash_key}){
# skip because '$word' <--> '$p' pattern has already appeared in a previous palindrome.
if($hash_val != $depth){
goto LABEL;
# next; #skip
}
}
else{
#flag this candidate as already having been tested (below).
$repeated_pal_hash_ref->{$repeated_pal_hash_key} = $depth;
lib/AI/Pathfinding/SMAstar/Examples/Phrase.pm view on Meta::CPAN
my ($pkg, $filename, $line_num) = caller();
if($self->{_predecessor}){
$antecedent = $self->{_predecessor};
$ant_phrase = $antecedent->{_phrase} ? $antecedent->{_phrase} : $antecedent->{_start_word};
}
else{
$antecedent->{_phrase} = "none";
}
# print " $line_num, destroying phrase object $self, '" . $self->{_start_word} . ", " . $self->{_phrase} .
# "', parent is $antecedent: '" . $ant_phrase . "' \n";
# if($line_num != 0){ # if not final sweep at program exit
# print " caller is: $pkg, $filename, $line_num\n";
# }
if($line_num == 0){ # line_num is zero
$d++;
# print "\$d : $d\n";
}
#${$self->{_predecessor}} = 0;
#${$self->{_descendants_list}} = 0;
delete $self->{_predecessor};
}
lib/AI/Pathfinding/SMAstar/PairObj.pm view on Meta::CPAN
}
return 1;
}
sub fp_equal {
my ($self, $A, $B, $dp) = @_;
return sprintf("%.${dp}g", $A) eq sprintf("%.${dp}g", $B);
}
1; # so the require or use succeeds
lib/AI/Pathfinding/SMAstar/PriorityQueue.pm view on Meta::CPAN
}
$self->{_size} = $self->{_size} + 1;
my $antecedent = $pobj->{_antecedent};
if($antecedent){
$antecedent->{_descendants_on_queue} = $antecedent->{_descendants_on_queue} + 1;
}
$pobj->is_on_queue(1);
}
sub print_trees_in_order
{
my ($self) = @_;
my $cost_hash_ref = $self->{_hash_of_trees_ref};
for my $cost_key (keys %$cost_hash_ref){
if(!$cost_hash_ref->{$cost_key}){
# no tree for this depth.
#print "no tree at key $depth_key\n";
}
else{
#print "contents of tree with depth $depth_key\n";
my $avltree = $cost_hash_ref->{$cost_key};
$$avltree->print();
}
}
}
#-----------------------------------
# get_list
#
# return a list of all objects in queue
#
lib/AI/Pathfinding/SMAstar/PriorityQueue.pm view on Meta::CPAN
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.
lib/AI/Pathfinding/SMAstar/PriorityQueue.pm view on Meta::CPAN
}
if($obj1 < $obj2){
return -1;
}
return 1;
}
sub fp_equal {
my ($A, $B, $dp) = @_;
return sprintf("%.${dp}g", $A) eq sprintf("%.${dp}g", $B);
}
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
my $fget_key = $self->{f_obj_get_key};
my $avl_compare = $self->{f_avl_compare};
my $key = $obj->$fget_key();
my $queue = AI::Pathfinding::SMAstar::AVLQueue->new(_key => $key);
my $avltree = \$self->{_avl_tree};
my $found_queue = $self->{_avl_tree}->lookup_obj($queue);
if(!$found_queue){
# print "TreeOfQueues::remove: did not find queue with key $key\n";
# $self->{_avl_tree}->print();
}
else { # found a queue here. remove obj
#print "TreeOfQueues::remove: found queue, removing obj using $cmp_func\n";
$found_queue->remove($obj, $cmp_func);
if($found_queue->is_empty()){
#print "TreeOfQueues::remove: found queue is now empty, removing queue from tree\n";
$$avltree->remove($found_queue);
}
}
}
sub largest_oldest{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
# $$avltree->print("-");
# get the avl tree with the largest key
my $queue = $$avltree->largest();
if($queue){
my $key = $queue->key();
my $obj = $queue->top();
return $obj;
}
else{
return;
}
}
sub pop_largest_oldest{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
# $$avltree->print("*");
# get the avl tree with the largest key
my $queue = $$avltree->largest();
if($queue){
my $key = $queue->key();
my $obj = $queue->pop_top();
if($queue->is_empty()){
$$avltree->remove($queue);
}
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
}
else{
return;
}
}
sub smallest_oldest{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
# $$avltree->print("-");
# get the avl tree with the largest key
my $queue = $$avltree->smallest();
if($queue){
my $key = $queue->key();
my $obj = $queue->top();
return $obj;
}
else{
return;
}
}
sub pop_smallest_oldest{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
# $$avltree->print("*");
# get the avl tree with the largest key
my $queue = $$avltree->smallest();
if($queue){
my $key = $queue->key();
my $obj = $queue->pop_top();
if($queue->is_empty()){
$$avltree->remove($queue);
}
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
sub pop_oldest_at{
my ($self, $key) = @_;
my $avltree = \$self->{_avl_tree};
my $queue_to_find = AI::Pathfinding::SMAstar::AVLQueue->new(_key => $key);
my $queue = $$avltree->lookup_obj($queue_to_find);
if($queue){
# print "TreeOfQueues::pop_oldest_at: found queue with key: $key\n";
my $obj = $queue->pop_top();
if($queue->is_empty()){
$$avltree->remove($queue);
}
return $obj;
}
else{
# print "TreeOfQueues::pop_oldest_at: did not find queue with key: $key\n";
return;
}
}
sub oldest_at{
my ($self, $key) = @_;
my $avltree = \$self->{_avl_tree};
my $queue_to_find = AI::Pathfinding::SMAstar::AVLQueue->new(_key => $key);
my $queue = $$avltree->lookup_obj($queue_to_find);
if($queue){
# print "TreeOfQueues::oldest_at: found queue with key: $key\n";
my $obj = $queue->top();
return $obj;
}
else{
# print "TreeOfQueues::oldest_at: did not find queue with key: $key\n";
return;
}
}
sub largest{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
return $$avltree->largest();
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
sub get_queue{
my ($self, $key) = @_;
my $avltree = \$self->{_avl_tree};
my $queue_to_find = AI::Pathfinding::SMAstar::AVLQueue->new(_key => $key);
my $queue = $$avltree->lookup_obj($queue_to_find);
if($queue){
# print "TreeOfQueues::get_queue: found queue with key: $key\n";
return $queue;
}
else{
# print "TreeOfQueues::get_queue: did not find queue with key: $key\n";
return;
}
}
sub get_keys_iterator
{
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
sub get_keys
{
my ($self) = @_;
my $avltree = \$self->{_avl_tree};
return $$avltree->get_keys();
}
sub print{
my ($self) = @_;
if($self->{_avl_tree}->is_empty()){
print "tree is empty\n";
}
my $get_key_func = $self->{f_obj_get_key};
my $get_data_func = $self->{f_obj_get_data};
my @queue_list = $self->{_avl_tree}->get_list();
foreach my $queue (@queue_list){
#print "queue is $queue\n";
my $queue_key = $queue->key();
#print "queue key: $queue_key\n";
my @objlist = $queue->get_list();
if(!@objlist){
print "queue at key $queue_key is empty\n";
}
print "queue at key $queue_key:\n";
foreach my $obj (@objlist){
my $key = $obj->$get_key_func;
my $word = $obj->$get_data_func;
print " key: $key, data: $word\n";
}
}
}
sub is_empty{
my ($self) = @_;
if($self->{_avl_tree}->is_empty()){
return 1;
lib/AI/Pathfinding/SMAstar/TreeOfQueues.pm view on Meta::CPAN
sub get_list{
my ($self) = @_;
my @objs;
if($self->{_avl_tree}->is_empty()){
return;
}
#$self->{_avl_tree}->print(">>>");
my @queue_list = $self->{_avl_tree}->get_list();
foreach my $queue (@queue_list){
my $queue_key = $queue->key();
my @objlist = $queue->get_list();
#print "get_list: size of queue at key: $queue_key is: " . @objlist . "\n";
push(@objs, @objlist);
}
return @objs;
}
1;
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
#!/usr/bin/perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl AI-Pathfinding-SMAstar.t'
#########################
# change 'tests => 1' to 'tests => last_test_to_print';
use Test::More tests => 9;
BEGIN { use_ok('AI::Pathfinding::SMAstar');
use_ok('Tree::AVL');
use_ok('AI::Pathfinding::SMAstar::Examples::PalUtils');
use_ok('AI::Pathfinding::SMAstar::Examples::WordObj');
use_ok('AI::Pathfinding::SMAstar::Examples::Phrase');
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
my @rev_word_objs;
my $num_words;
my $sparsity;
my $max_states_in_queue;
my %letter_freq;
my $max_word_length = 0;
my $MAX_COST = 99;
#my $collisions_per_length = PalUtils::collisions_per_length("ocid", "abo gad abalones rot abdicators enol aba dagoba");
#print "collisions: $collisions_per_length\n";
#exit;
$dictionary_file = 't/test8.lst';
$min_letters = 4;
$sparsity = 2;
$max_states_in_queue = 4;
diag("\ncreating AVL trees");
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
fget_data => \&AI::Pathfinding::SMAstar::Examples::WordObj::word,
);
my $avltree_rev = Tree::AVL->new(
fcompare => \&AI::Pathfinding::SMAstar::Examples::WordObj::compare,
fget_key => \&AI::Pathfinding::SMAstar::Examples::WordObj::word,
fget_data => \&AI::Pathfinding::SMAstar::Examples::WordObj::word,
);
print STDERR "-" x 80 . "\n";
print STDERR "-" x 80 . "\n";
diag("reading dictionary '$dictionary_file'");
eval{
($num_words, @words) = AI::Pathfinding::SMAstar::Examples::PalUtils::read_dictionary_filter_by_density($dictionary_file, $sparsity);
};
is( $@, '', '$@ is not set after object insert' );
diag("loaded words: '$num_words'");
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
$max_word_length = $length;
}
}
$num_words_filtered = @words;
diag("$num_words words in the currently loaded dictionary. Minimum letters specified = $min_letters");
diag("$num_words_filtered words that meet the initial sparsity constraint max_sparsity = $sparsity.");
if(!@words){
print STDERR "no words to process. exiting\n";
exit;
}
@word_objs = AI::Pathfinding::SMAstar::Examples::PalUtils::process_words_by_density(\@words, $sparsity);
@rev_word_objs = AI::Pathfinding::SMAstar::Examples::PalUtils::process_rev_words_by_density(\@words, $sparsity);
if(!@word_objs){
print STDERR "no words achieve density specified by max sparsity $sparsity\n";
exit;
}
$num_word_objs = @word_objs;
diag("loading avl trees.");
for (my $i = 0; $i < @word_objs; $i++) {
show_progress($i/$num_words);
my $word = $word_objs[$i]->{_word};
my $rev_word = $rev_word_objs[$i]->{_word};
$avltree->insert($word_objs[$i]);
$avltree_rev->insert($rev_word_objs[$i]);
}
show_progress(1);
print STDERR "\n";
#
# Build the words-with-candidates list. This will be used for phrases that are
# palindromes with a space in the middle position. The descendants of these
# types of palindromes are found by sort-of starting all over again... any word becomes
# a candidate for the extension of the palindrome- any word that has candidates,
# that is. By building a list of only the words that have candidates,
# the search time is greatly reduced.
#
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
diag("building words_w_cands_list.");
foreach my $w (@words){
show_progress($i/$num_words);
my @candidates = AI::Pathfinding::SMAstar::Examples::PalUtils::get_cands_from_left($w, $avltree, $avltree_rev);
if(@candidates){
push(@words_w_cands, $w);
}
$i++;
}
show_progress(1);
print STDERR "\n";
my $num_words_w_cands = @words_w_cands;
diag("number of word/candidate pairs is: $num_words_w_cands.");
$avltree_height = $avltree->get_height();
$avltree_rev_height = $avltree_rev->get_height();
diag("AVL trees loaded. Heights are $avltree_height, $avltree_rev_height\n\n");
my @phrase_obj_list;
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
#----------------------------------------------------------------------------
sub log_function
{
my ($path_obj) = @_;
if(!$path_obj){
my ($pkg, $filename, $line) = caller();
print "$pkg, $filename, $line\n";
}
my $str = "";
# $cand is the parent's word (the candidate that generated this phrase)
my $cand = "";
my $cost = "";
my $cost_so_far = "";
my $num_new_chars = "";
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
$cost_so_far = $path_obj->{_state}->{_cost_so_far};
$num_new_chars = $path_obj->{_state}->{_num_new_chars};
$num_chars_so_far = $path_obj->{_state}->{_num_chars_so_far};
$letters_seen = $path_obj->{_state}->{_letters_seen};
$letters_seen_str = join("", @$letters_seen);
$phrase = defined($path_obj->{_state}->{_phrase}) ? $path_obj->{_state}->{_phrase} : "";
$evaluation = AI::Pathfinding::SMAstar::Path::fcost($path_obj);
$depth = $path_obj->{_depth};
$num_chars_so_far = sprintf("%02d", $num_chars_so_far);
$num_new_chars = sprintf("%02d", $num_new_chars);
$cost = sprintf("%02d", $cost);
$cost_so_far = sprintf("%02d", $cost_so_far);
$depth = sprintf("%02d", $depth);
my $specifier = "%" . $max_word_length . "s";
$str = sprintf($specifier, $str);
$evaluation = sprintf("%04f", $evaluation);
$letters_seen_str = sprintf("%26s", $letters_seen_str);
my $log_str = "";
$log_str = $log_str . "depth: $depth, ";
$log_str = $log_str . "eval: $evaluation, ";
$log_str = $log_str . "letters: '$letters_seen_str', ";
$log_str = $log_str . "'$str', ";
$log_str = $log_str . "'$phrase', ";
$log_str = $log_str . "cand: $cand";
t/AI-Pathfinding-SMAstar.t view on Meta::CPAN
}
elsif($state == 2){
$spinny_thing = "|";
}
elsif($state == 3){
$spinny_thing = "/";
}
my ($progress) = @_;
my $stars = '*' x int($progress*10);
my $percent = sprintf("%.2f", $progress*100);
$percent = $percent >= 100 ? '100.00%' : $percent.'%';
print STDERR "\r$stars $spinny_thing $percent.";
flush(STDERR);
}
}