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.2 || ^8.3 || ^8.4
- webmozart/assert: ^1.11
Requires (Dev)
- ergebnis/composer-normalize: ^2.48
- friendsofphp/php-cs-fixer: ^3.87
- phpstan/phpstan: ^2.1
- phpunit/phpcov: ^11.0
- phpunit/phpunit: ^12.3
This package is auto-updated.
Last update: 2025-12-27 03:07:36 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
π Documentation
- API Reference - Complete API documentation for all classes and methods
- CHANGELOG - Version history and migration guides
- Contributing Guide - Guidelines for contributing to the project
π Usage
Basic Usage
use mschandr\WeightedRandom\WeightedRandom; // Create a generator $gen = WeightedRandom::createFloat(); // Register values with weights $gen->registerValue('common', 7.0) ->registerValue('uncommon', 2.5) ->registerValue('rare', 0.5); // Generate a random value $result = $gen->generate(); // Generate multiple values $results = $gen->generateMultiple(10); // Generate unique values (no duplicates) $unique = $gen->generateMultipleWithoutDuplicates(3);
Batch Registration
$gen->registerValues([ 'apple' => 3.0, 'banana' => 2.0, 'cherry' => 1.0, ]);
Groups (Multiple Values, Single Weight)
// Register a group of values that share a single weight $gen->registerGroup(['bronze', 'silver', 'gold'], 5.0); // When the group is selected, one member is chosen uniformly at random
Fair Distribution (Bag System)
$bag = WeightedRandom::createBag(); $bag->registerValues(['rare' => 1, 'common' => 9]); // Over 10 draws: exactly 1 rare, 9 common (then bag reshuffles) $results = $bag->generateMultiple(10);
Distribution Introspection
// Get probability distribution $distribution = $gen->getDistribution(); // Returns: ['apple' => 0.5, 'banana' => 0.333, 'cherry' => 0.167] // Get probability of specific value $prob = $gen->getProbability('apple'); // 0.5 // Calculate Shannon entropy (distribution randomness) $entropy = $gen->getEntropy(); // For numeric values - statistical analysis $gen->registerValues([1 => 1.0, 2 => 2.0, 3 => 1.0]); $mean = $gen->getExpectedValue(); // Weighted mean $variance = $gen->getVariance(); // Weighted variance $stdDev = $gen->getStandardDeviation(); // Standard deviation
Decay/Boost (Dynamic Weight Adjustment)
// Manual weight adjustment $gen->decayWeight('common', 0.8); // Reduce weight to 80% $gen->boostWeight('rare', 1.5); // Increase weight by 50% // Adjust all weights $gen->decayAllWeights(0.9); // Reduce all weights to 90% $gen->boostAllWeights(1.2); // Increase all weights by 20% // Automatic adjustment based on selection frequency $gen->enableSelectionTracking(); // Generate some values... $gen->generateMultiple(100); // Auto-adjust: frequently selected values get decayed, rare ones get boosted $gen->autoAdjustWeights(0.5); // 0.5 = adjustment strength // View selection counts $counts = $gen->getSelectionCounts(); // Reset tracking $gen->resetSelectionCounts();
Composite Generators (Nested/Hierarchical)
// Create a hierarchy of generators $rareLoot = WeightedRandom::createFloat(); $rareLoot->registerValues(['legendary_sword' => 1.0, 'magic_ring' => 1.0]); $commonLoot = WeightedRandom::createFloat(); $commonLoot->registerValues(['wooden_sword' => 3.0, 'bread' => 2.0]); $lootBox = WeightedRandom::createFloat(); $lootBox->registerValue($rareLoot, 0.1); // 10% chance of rare loot table $lootBox->registerValue($commonLoot, 0.9); // 90% chance of common loot table $item = $lootBox->generate(); // Draws from nested generator
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 (2.x β 3.x)
WeightedRandom 2.x introduces new features and stricter validation. If youβre upgrading from 1.x, hereβs what you need to know:
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.
Roadmap
Floats + NormalizationValidation EnhancementsChaining APIGroupsSeeded RNGDistribution IntrospectionBag SystemDecay/BoostComposite GeneratorsCode coverage and proper testing