ksk88/weighted-lottery-php

weighted-lottery-php提供了一个不等于随机洗牌函数。确定是根据每个选择的总权重比例。

dev-master 2015-02-11 17:47 UTC

This package is not auto-updated.

Last update: 2024-09-28 17:12:33 UTC


README

weighted-lottery-php提供了一个不等于随机洗牌函数。确定是根据每个选择的总权重比例。

安装

要使用Composer安装weighted-lottery-php,只需将以下内容添加到您的composer.json文件中

// composer.json
{
    "require-dev": {
        "ksk88/weighted-lottery-php": "dev-master"
    }
}

然后,您可以从存放composer.json文件的目录运行Composer的update命令来安装新的依赖项

# install
$ php composer.phar install --dev
# update
$ php composer.phar update ksk88/weighted-lottery-php --dev

# or you can simply execute composer command if you set it to
# your PATH environment variable
$ composer install --dev
$ composer update ksk88/weighted-lottery-php --dev

您可以在Packagist上看到这个库。

Composer在./vendor/autoloader.php安装自动加载器。如果您在php脚本中使用weighted-lottery-php,请添加

require_once 'vendor/autoload.php';

如果使用Symfony2,自动加载器需要自动检测。

或者您可以使用git clone命令

# HTTP
$ git clone https://github.com/ksk88/weighted-lottery-php.git
# SSH
$ git clone git@github.com:ksk88/weighted-lottery-php.git

示例

<?php
require_once './vendor/autoload.php';
use ksk88\WeightedLotteryPhp\Lot;

$tickets = array(
    array('weight' => 1,  'label' => 'super_rare'),
    array('weight' => 5,  'label' => 'rare'),
    array('weight' => 94, 'label' => 'normal'),
);

$lot = new Lot();
$winners = $lot->pickFromWeightedLottery($tickets);
$winner = reset($winners);

echo $winner['label'];
# super_rare (1%)
# rare       (5%)
# normal     (94%)

运行10000次的结果计数

[1] 创建测试函数。 (test.php)

<?php
require_once './vendor/autoload.php';
use ksk88\WeightedLotteryPhp\Lot;

class Draw
{
    public function exec()
    {
        $results = array();

        for ($i = 0; $i < 10000; $i++) {

            // Lottery
            $winner = $this->pick();

            // Count
            $count = 0;
            $label = $winner['label'];
            if (array_key_exists($label, $results)) {
                $count = $results[$label];
            }
            $results[$label] = $count + 1;

        }

        var_export($results);
    }

    private function pick()
    {
        $tickets = array(
            array('weight' => 1,  'label' => 'super_rare'),
            array('weight' => 5,  'label' => 'rare'),
            array('weight' => 50, 'label' => 'normal_1'),
            array('weight' => 50, 'label' => 'normal_2'),
            array('weight' => 50, 'label' => 'normal_3'),
            array('weight' => 50, 'label' => 'normal_4'),
            array('weight' => 50, 'label' => 'normal_5'),
        );

        $lot = new Lot();
        $num_picked = 1;
        $winners = $lot->pickFromWeightedLottery($tickets, $num_picked);

        $winner = reset($winners);

        return $winner;
    }
}

$draw = new Draw();
$draw->exec();

[2] 执行test.php

# execute
$ php test.php
array (
  'super_rare' => 46,
  'rare'       => 200,
  'normal_1'   => 1962,
  'normal_2'   => 1986,
  'normal_3'   => 1990,
  'normal_4'   => 1915,
  'normal_5'   => 1901,
)

[3] 汇总计数

结果是随机的,但基于每个选择的总权重比例。

选项

库有几个选项。您可以使用选项轻松操作您的数组。

  • weight_gradient

  • 发生频率的差异频率,介于顶部和底部之间。

  • 因此,当设置为'1'时,函数将按正常方式洗牌。

  • 默认为null。

  • use_order_as_weight

  • 使用顺序作为彩票的权重。

  • 默认为false。

  • name_weight_source

  • 以这个名称作为键取权重。

  • 默认为'weight'。

  • threshold_conditions

  • 根据任何条件削减票数。

  • 默认为null。

  • name_id

  • 当排除票时使用。

  • 默认为'ticket_id'。

  • excluded_tickets

  • 通过ID排除票。

  • ID基于'name_id'作为键。

  • 默认为array().

用法

  • option_usage.php
<?php
require_once './vendor/autoload.php';
use ksk88\WeightedLotteryPhp\Lot;

$results = summary();
ksort($results);
var_dump($results);

function draw() {
    $tickets = array(
        array('rank' => 1),
        array('rank' => 2),
        array('rank' => 3),
        array('rank' => 4),
        array('rank' => 5),
        array('rank' => 6),
        array('rank' => 7),
        array('rank' => 8),
        array('rank' => 9),
        array('rank' => 10),    // Removed by option
    );

    $setting = array(
        'weight_gradient' => 2,
        'use_order_as_weight' => true,
        'threshold_conditions' => array(
            array('name' => 'rank', 'val' => 9,  'sign' => 'lesser_or_equal'),
        ),
    );

    $lot = new Lot();
    $num_picked = 1;
    $winners = $lot->pickFromWeightedLottery($tickets, $num_picked, $setting);

    $winner = reset($winners);
    return $winner;
}

function summary() {
    $results = array();
    for ($i = 0; $i < 10000; $i++) {

        // Lottery
        $winner = draw();

        // Count
        $count = 0;
        $label = $winner['rank'];
        if (array_key_exists($label, $results)) {
            $count = $results[$label];
        }
        $results[$label] = $count + 1;
    }
    return $results;
}
  • 结果

通过选项,顶部和底部发生频率的差异大约翻倍。