HEX
Server: Apache/2.4.57 (Ubuntu) mod_fcgid/2.3.9 OpenSSL/3.0.2
System: Linux vmi267337.contaboserver.net 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:54:22 UTC 2022 x86_64
User: ohirex (1008)
PHP: 8.2.8
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,exec,system,passthru,shell_exec
Upload Files
File: /home/ohirex/web/ohirex.com/public_html/join/abtests/Strategies/EpsilonFirst.php
<?php
declare(strict_types=1);

namespace Offdev\Bandit\Strategies;

use Offdev\Bandit\Exceptions\RuntimeException;
use Offdev\Bandit\Lever;
use Offdev\Bandit\Machine;
use Offdev\Bandit\StrategyInterface;

/**
 * Represents the epsilon-first strategy to solve the multi armed bandit problem.
 *
 * From wikipedia (2016-08-13):
 * A pure exploration phase is followed by a pure exploitation phase. For N trials
 * in total, the exploration phase occupies eN trials and the exploitation phase
 * 1-eN trials. During the exploration phase, a lever is randomly selected (with
 * uniform probability); during the exploitation phase, the best lever is always
 * selected.
 *
 * @url https://en.wikipedia.org/wiki/Multi-armed_bandit#Bandit_strategies
 */
class EpsilonFirst implements StrategyInterface
{
    private float $e;

    private int $maxTries;

    public function __construct(int $maxTries, float $proportion = 0.1)
    {
        if ($maxTries <= 0) {
            throw new RuntimeException('Amount of total maximum tries must be greater than 0!');
        }

        if ($proportion < 0.0) {
            throw new RuntimeException('Proportion must be greater than or equal to 0!');
        }

        if ($proportion > 1.0) {
            throw new RuntimeException('Proportion must be less than or equal to 1!');
        }

        $this->e = $proportion;
        $this->maxTries = $maxTries;
    }

    public function solve(Machine $machine): Lever
    {
        $tries = 0;
        $leverList = $machine->getLeverList();
        foreach ($leverList as $lever) {
            $tries += $lever->getTries();
        }

        $r = $tries / $this->maxTries;
        if ($r <= $this->e) {
            return $machine->getRandomLever();
        }

        return $machine->getBestLever();
    }
}