mschandr / weighted-random
Library for generating a weighted random sample
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 5
pkg:composer/mschandr/weighted-random
Requires
- php: ^8.1 || ^8.2 || ^8.3 || ^8.4
- beberlei/assert: ^3.2
Requires (Dev)
- phpunit/phpunit: ^8
- squizlabs/php_codesniffer: ^3.3
- vimeo/psalm: ^3.4
This package is auto-updated.
Last update: 2025-10-02 21:02:05 UTC
README
This library is used to pick random values from a set of registered values, where values with a higher weight have a larger probability to be picked.
Installation
To install this library using Composer:
composer require mschandr/weighted-random
🚀 Usage
Registering values
use mschandr\WeightedRandom\WeightedRandomGenerator; $gen = new WeightedRandomGenerator(); // Register values with integer or float weights $gen->registerValue('common', 0.7) ->registerValue('rare', 0.3); // Draw a value echo $gen->generate(); // "common" or "rare"
Multiple values at once
$gen = new WeightedRandomGenerator(); $gen->registerValues([ 'apple' => 70, 'banana' => 30, ]); foreach ($gen->generateMultiple(5) as $value) { echo $value, PHP_EOL; }
No duplicates
foreach ($gen->generateMultipleWithoutDuplicates(2) as $value) { echo $value, PHP_EOL; }
Probability helpers
$gen = new WeightedRandomGenerator(); $gen->registerValues([ 'apple' => 70, 'banana' => 30, ]); print_r($gen->normalizeWeights()); // ['apple' => 0.7, 'banana' => 0.3] echo $gen->getProbability('banana'); // 0.3
Seeded RNG (PHP ≥ 8.2)
use mschandr\WeightedRandom\WeightedRandom; $weights = ['a' => 10, 'b' => 5, 'c' => 1]; echo WeightedRandom::pickKeySeeded($weights, 1234, 'stream.alpha'); echo WeightedRandom::pickKeySeeded($weights, 1234, 'stream.beta');
- Same seed + namespace = reproducible results.
- Different namespaces = independent streams.
Requirements
- PHP 8.1 – 8.4
- Composer Seeded RNG requires PHP 8.2+. On PHP 8.1, those tests are automatically skipped.
🛠 Development
vendor/bin/phpunit -c phpunit.xml --color
GitHub Actions CI runs tests against PHP 8.1, 8.2, 8.3, 8.4.
License
MIT License.
Migration Guide (1.x → 2.x)
WeightedRandom 2.x introduces new features and stricter validation. If you’re upgrading from 1.x, here’s what you need to know:
⚠️ Breaking Changes
- Zero or negative weights are no longer allowed.
// ❌ This will now throw an exception $gen->registerValue('foo', 0);
- Empty sets are not permitted.
// ❌ This will now throw $gen->generate();
- Tests that assumed specific ordering may fail. Random draws are inherently order-independent — update assertions to check for membership, not sequence.
What’s New
- Float weight support → Use 0.7 vs 0.3 without scaling up to integers.
- Seeded RNG with namespace isolation (PHP ≥ 8.2) → Deterministic, reproducible draws.
- Chaining API for cleaner code.
- Probability helpers:
normalizeWeights()
→ normalized distribution.getProbability($value)
→ single-value probability.
- Bag System (v2.2+) → fairness via without-replacement draws.
- Stricter validation → safer, more predictable behavior.
🛠️ Upgrade Checklist
- Review your code and remove any weights ≤ 0.
- If you used floats before by scaling (e.g., 70 vs 30), you can now write them as 0.7 vs 0.3.
- If you want reproducible randomness, upgrade to PHP 8.2+ and switch to pickKeySeeded().
- Update tests to allow for order-independent results.
Roadmap
Floats + NormalizationValidation EnhancementsChaining APIGroupsSeeded RNG- Distribution Introspection
Bag System- Decay/Boost
- Composite Generators