frank-houweling/weighted-random

生成加权随机样本的库

1.0.1 2019-07-27 18:59 UTC

This package is auto-updated.

Last update: 2024-09-28 07:21:32 UTC


README

Build Status codecov

此库用于从一组已注册的值中随机选择值,其中权重较高的值有更大的概率被选中。

安装

使用composer安装此库。

composer require frank-houweling/weighted-random

入门

使用此库很简单。初始化WeightedRandomGenerator,注册可能的值,然后开始生成随机值!

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

// Initiate the generator
$generator = new WeightedRandomGenerator();

// Register some value
$generator->registerValue('foobar', 5);

// And get a random value
echo $generator->generate() . PHP_EOL;

注册值

您可以使用以下方法设置一个值及其权重。较高的权重意味着随机生成器生成该值的概率更高。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

// Initiate the generator
$generator = new WeightedRandomGenerator();

// Register a new value
$generator->registerValue('foobar', 5);

// Override the added value with a weight of 1
$generator->registerValue('foobar', 1);

// The weight should be above 0, this call will result in an \InvalidArgumentException
$generator->registerValue('foobar', 0);

您可以使用registerValues()方法一次性注册多个值。此方法仅接受字符串和整数作为值。

registerValues()方法期望值作为键,权重作为传入数组的值。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

$generator = new WeightedRandomGenerator();

// Register multiple values
$generator->registerValues([
    'foo' => 1,
    'bar' => 2,
]);

// Override the bar, foo will stay the same.
$generator->registerValues([
    'bar' => 1,
]);

// This will result in an InvalidArgumentException, 0 is not a correct weight.
$generator->registerValues([
    'bar' => 0,
]);

您可以使用removeValue方法从生成器中删除一个值。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

$generator = new WeightedRandomGenerator();
$generator->registerValue('foobar', 2);

$generator->removeValue('foobar');

如果您愿意,您还可以使用WeightedValue值对象。您应该使用registerWeightedValue和removeWeightedValue方法注册和删除这些值对象。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;
use FrankHouweling\WeightedRandom\WeightedValue;

$generator = new WeightedRandomGenerator();

$weightedValue = new WeightedValue('foobar', 2);
$generator->registerWeightedValue($weightedValue);
$generator->removeWeightedValue($weightedValue);

检索已注册的值

您可以从生成器检索已注册的值及其权重。这些值总是以WeightedValue值对象的形式返回。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

$generator = new WeightedRandomGenerator();
$generator->registerValues([
    'foo' => 2,
    'bar' => 3,
]);

// Retrieve all registered values
foreach ($generator->getWeightedValues() as $weightedValue) {
    echo sprintf(
        '%s => %s',
        $weightedValue->getValue(),
        $weightedValue->getWeight()
    ) . PHP_EOL;
}

// Or only one, by the given value.
$weightedValue = $generator->getWeightedValue('foo');
echo $weightedValue->getWeight() . PHP_EOL;

生成随机样本

要从已注册的值生成随机样本,我们使用generate方法。

生成的值不总是唯一的。调用generate方法两次可能会返回相同的值。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

$generator = new WeightedRandomGenerator();
$generator->registerValue('foo', 2);

// Because we only registered one value, this now always returns `foobar`
echo $generator->generate() . PHP_EOL;

$generator->registerValue('bar', 2);

// Because we have registered two values, both with a weight of 2, the chance of foo and bar is both 50%.
echo $generator->generate() . PHP_EOL;

您还可以使用generateMultiple方法生成多个值的样本,使用generateMultipleWithoutDuplicates生成一组可能不重复的多个值。

<?php
use FrankHouweling\WeightedRandom\WeightedRandomGenerator;

$generator = new WeightedRandomGenerator();
$generator->registerValues([
    'foo' => 2,
    'bar' => 2,
]);

// Can return foo + bar, bar + foo, foo + foo or bar + bar.
foreach ($generator->generateMultiple(2) as $value) {
    echo $value . PHP_EOL;
}

// Can return foo + bar or bar + foo
foreach ($generator->generateMultipleWithoutDuplicates(2) as $value) {
    echo $value . PHP_EOL;
}

// This will return three values, of which 2 or 3 are duplicate.
$generator->generateMultiple(3);

// This will throw an \InvalidArgumentException, because it is not possible to generate three unique values.
$generator->generateMultipleWithoutDuplicates(3);