AI-Pathfinding-OptimizeMultiple
view release on metacpan or search on metacpan
lib/AI/Pathfinding/OptimizeMultiple.pm view on Meta::CPAN
package AI::Pathfinding::OptimizeMultiple;
$AI::Pathfinding::OptimizeMultiple::VERSION = '0.0.17';
use strict;
use warnings;
use 5.012;
use AI::Pathfinding::OptimizeMultiple::IterState ();
use AI::Pathfinding::OptimizeMultiple::Scan ();
use AI::Pathfinding::OptimizeMultiple::ScanRun ();
use AI::Pathfinding::OptimizeMultiple::SimulationResults ();
use MooX qw/late/;
use PDL;
use Scalar::Util qw/ blessed /;
has chosen_scans => ( isa => 'ArrayRef', is => 'rw' );
has _iter_idx => ( isa => 'Int', is => 'rw', default => sub { 0; }, );
has _num_boards => ( isa => 'Int', is => 'ro', init_arg => 'num_boards', );
has _orig_scans_data => ( isa => 'PDL', is => 'rw' );
has _optimize_for => ( isa => 'Str', is => 'ro', init_arg => 'optimize_for', );
has _scans_data => ( isa => 'PDL', is => 'rw' );
has _selected_scans =>
( isa => 'ArrayRef', is => 'ro', init_arg => 'selected_scans', );
has _status => ( isa => 'Str', is => 'rw' );
has _quotas => ( isa => 'ArrayRef[Int]', is => 'ro', init_arg => 'quotas' );
has _total_boards_solved => ( isa => 'Int', is => 'rw' );
has _total_iters => ( is => 'rw' );
has _trace_cb =>
( isa => 'Maybe[CodeRef]', is => 'ro', init_arg => 'trace_cb' );
has _scans_meta_data => ( isa => 'ArrayRef', is => 'ro', init_arg => 'scans' );
has _scans_iters_pdls =>
( isa => 'HashRef', is => 'rw', init_arg => 'scans_iters_pdls' );
has _stats_factors => (
isa => 'HashRef',
is => 'ro',
init_arg => 'stats_factors',
default => sub { return +{}; },
);
sub BUILD
{
my $self = shift;
my $args = shift;
my $scans_data = PDL::cat(
map {
my $id = $_->id();
my $pdl = $self->_scans_iters_pdls()->{$id};
my $factor = $self->_stats_factors->{$id};
(
defined($factor)
? ( ( $pdl >= 0 ) * ( ( $pdl / $factor )->ceil() ) +
( $pdl < 0 ) * $pdl )
: $pdl
);
} @{ $self->_selected_scans() }
);
$self->_orig_scans_data($scans_data);
$self->_scans_data( $self->_orig_scans_data()->copy() );
return 0;
}
my $BOARDS_DIM = 0;
my $SCANS_DIM = 1;
my $STATISTICS_DIM = 2;
sub _next_iter_idx
{
my $self = shift;
my $ret = $self->_iter_idx();
lib/AI/Pathfinding/OptimizeMultiple.pm view on Meta::CPAN
$self->_get_iter_state_params(), );
$iter_state->attach_to($self);
return $iter_state;
}
sub _inspect_quota
{
my $self = shift;
my $state = $self->_get_selected_scan();
$state->register_params();
$state->update_total_iters();
if ( $self->_total_boards_solved() == $self->_num_boards() )
{
$self->_status("solved_all");
}
else
{
$state->update_idx_slice();
}
$state->detach();
}
sub calc_meta_scan
{
my $self = shift;
$self->chosen_scans( [] );
$self->_total_boards_solved(0);
$self->_total_iters(0);
$self->_status("iterating");
# $self->_inspect_quota() throws ::Error::OutOfQuotas if
# it does not have any available quotas.
eval {
while ( $self->_status() eq "iterating" )
{
$self->_inspect_quota();
}
};
if (
my $err = Exception::Class->caught(
'AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas')
)
{
$self->_status("out_of_quotas");
}
else
{
$err = Exception::Class->caught();
if ($err)
{
if ( not( blessed $err && $err->can('rethrow') ) )
{
die $err;
}
$err->rethrow;
}
}
return;
}
sub _get_num_scans
{
my $self = shift;
return ( ( $self->_scans_data()->dims() )[$SCANS_DIM] );
}
sub _calc_chosen_scan
{
my ( $self, $selected_scan_idx, $iters_quota ) = @_;
return AI::Pathfinding::OptimizeMultiple::ScanRun->new(
{
iters => (
$iters_quota * (
$self->_stats_factors->{
( $self->_selected_scans->[$selected_scan_idx]->id() ),
} // 1
)
),
scan_idx => $selected_scan_idx,
}
);
}
sub calc_flares_meta_scan
{
my $self = shift;
$self->chosen_scans( [] );
$self->_total_boards_solved(0);
$self->_total_iters(0);
$self->_status("iterating");
my $iters_quota = 0;
my $flares_num_iters = PDL::Core::pdl( [ (0) x $self->_get_num_scans() ] );
my $ones_constant =
PDL::Core::pdl( [ map { [1] } ( 1 .. $self->_get_num_scans() ) ] );
my $next_num_iters_for_each_scan_x_scan =
( ( $ones_constant x $flares_num_iters ) );
my $num_moves = $self->_scans_data->slice(":,:,1");
# The number of moves for dimension 0,1,2 above.
my $num_moves_repeat = $num_moves->clump( 1 .. 2 )->xchg( 0, 1 )
->dummy( 0, $self->_get_num_scans() );
( run in 1.762 second using v1.01-cache-2.11-cpan-e1769b4cff6 )