AI-Pathfinding-OptimizeMultiple

 view release on metacpan or  search on metacpan

lib/AI/Pathfinding/OptimizeMultiple.pm  view on Meta::CPAN

    }
    else
    {
        return $self->_quotas()->($iter);
    }
}

sub _calc_get_iter_state_param_method
{
    my $self = shift;

    my $optimize_for = $self->_optimize_for();

    my %resolve = (
        len        => "_get_iter_state_params_len",
        minmax_len => "_get_iter_state_params_minmax_len",
        speed      => "_get_iter_state_params_speed",
    );

    return $resolve{$optimize_for};
}

sub _get_iter_state_params
{
    my $self = shift;

    my $method = $self->_calc_get_iter_state_param_method();

    return $self->$method();
}

sub _my_sum_over
{
    my $pdl = shift;

    return $pdl->sumover()->slice(":,(0)");
}

sub _my_xchg_sum_over
{
    my $pdl = shift;

    return _my_sum_over( $pdl->xchg( 0, 1 ) );
}

sub _get_iter_state_params_len
{
    my $self = shift;

    my $iters_quota        = 0;
    my $num_solved_in_iter = 0;
    my $selected_scan_idx;

    # If no boards were solved, then try with a larger quota
    while ( $num_solved_in_iter == 0 )
    {
        my $q_more = $self->_get_next_quota();
        if ( !defined($q_more) )
        {
            AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
                error => "No q_more", );
        }

        $iters_quota += $q_more;

        my $iters        = $self->_scans_data()->slice(":,:,0");
        my $solved       = ( ( $iters <= $iters_quota ) & ( $iters > 0 ) );
        my $num_moves    = $self->_scans_data->slice(":,:,2");
        my $solved_moves = $solved * $num_moves;

        my $solved_moves_sums   = _my_sum_over($solved_moves);
        my $solved_moves_counts = _my_sum_over($solved);
        my $solved_moves_avgs   = $solved_moves_sums / $solved_moves_counts;

        ( undef, undef, $selected_scan_idx, undef ) =
            $solved_moves_avgs->minmaximum();

        $num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
    }

    return {
        quota      => $iters_quota,
        num_solved => $num_solved_in_iter,
        scan_idx   => $selected_scan_idx,
    };
}

sub _get_iter_state_params_minmax_len
{
    my $self = shift;

    my $iters_quota        = 0;
    my $num_solved_in_iter = 0;
    my $selected_scan_idx;

    # If no boards were solved, then try with a larger quota
    while ( $num_solved_in_iter == 0 )
    {
        my $q_more = $self->_get_next_quota();
        if ( !defined($q_more) )
        {
            AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
                error => "No q_more", );
        }

        $iters_quota += $q_more;

        my $iters        = $self->_scans_data()->slice(":,:,0");
        my $solved       = ( ( $iters <= $iters_quota ) & ( $iters > 0 ) );
        my $num_moves    = $self->_scans_data->slice(":,:,2");
        my $solved_moves = $solved * $num_moves;

        my $solved_moves_maxima = $solved_moves->maximum()->slice(":,(0),(0)");
        my $solved_moves_counts = _my_sum_over($solved);

        ( undef, undef, $selected_scan_idx, undef ) =
            $solved_moves_maxima->minmaximum();

        $num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
    }

    return {
        quota      => $iters_quota,
        num_solved => $num_solved_in_iter,
        scan_idx   => $selected_scan_idx,
    };
}

sub _get_iter_state_params_speed
{
    my $self = shift;

    my $iters_quota        = 0;
    my $num_solved_in_iter = 0;
    my $selected_scan_idx;

    # If no boards were solved, then try with a larger quota
    while ( $num_solved_in_iter == 0 )
    {
        my $q_more = $self->_get_next_quota();
        if ( !defined($q_more) )
        {
            AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
                error => "No q_more" );
        }

        $iters_quota += $q_more;

        ( undef, $num_solved_in_iter, undef, $selected_scan_idx ) =
            PDL::minmaximum(
            PDL::sumover(
                ( $self->_scans_data() <= $iters_quota ) &
                    ( $self->_scans_data() > 0 )
            )
            );
    }

    return {
        quota      => $iters_quota,
        num_solved => $num_solved_in_iter->at(0),
        scan_idx   => $selected_scan_idx->at(0),
    };
}

sub _get_selected_scan
{
    my $self = shift;

    my $iter_state =
        AI::Pathfinding::OptimizeMultiple::IterState->new(
        $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( [] );



( run in 0.853 second using v1.01-cache-2.11-cpan-f6376fbd888 )