如何按百分比分布从值集合中生成符合比例的随机值
Randomly Assign Values with Specified Percentage Distributions
Great question! When you need to pick values from an array while sticking to specific percentage probabilities, the core trick is to map those percentages into a cumulative range that you can pair with a random number generator. Here's a straightforward, practical approach with code examples to implement it:
Core Concept
First, we convert individual percentages into a cumulative distribution range. For your example:
catcovers 0–30 (30% chance)dogcovers 31–80 (50% chance, since 30+50=80)mousecovers 81–100 (20% chance, 80+20=100)
Then, generate a random number between 0–99 (or 1–100) and check which range it falls into to select the corresponding value.
JavaScript Implementation
function getWeightedRandomValue(values, weights) { // Build cumulative weight array const cumulativeWeights = []; let total = 0; for (const weight of weights) { total += weight; cumulativeWeights.push(total); } // Generate random number (0 to 99 inclusive) const randomNum = Math.floor(Math.random() * 100); // Find which value matches the random number for (let i = 0; i < cumulativeWeights.length; i++) { if (randomNum < cumulativeWeights[i]) { return values[i]; } } // Fallback (only triggers if weights don't sum to 100) return values[values.length - 1]; } // Example usage const animalValues = ["cat", "dog", "mouse"]; const animalPercentages = [30, 50, 20]; // Generate 10 random values const randomAnimals = Array.from({ length: 10 }, () => getWeightedRandomValue(animalValues, animalPercentages) ); // Print results like your example randomAnimals.forEach((animal, index) => { console.log(`${index + 1}. ${animal}`); });
Python Implementation
If you're working in Python, here's an equivalent version:
import random def get_weighted_random_value(values, weights): cumulative_weights = [] total = 0 for weight in weights: total += weight cumulative_weights.append(total) # Generate random number between 1 and 100 random_num = random.randint(1, 100) # Match to the corresponding value for idx, val in enumerate(values): if random_num <= cumulative_weights[idx]: return val return values[-1] # Example usage animal_values = ["cat", "dog", "mouse"] animal_percentages = [30, 50, 20] random_animals = [get_weighted_random_value(animal_values, animal_percentages) for _ in range(10)] for idx, animal in enumerate(random_animals, 1): print(f"{idx}. {animal}")
Key Notes
- Check Total Percentage: Make sure your percentages add up to 100 for accurate distribution. If they don't, normalize them first (divide each by the total sum, multiply by 100).
- Sample Size Expectations: For small samples (like 10 items), you might not see an exact 3/5/2 split, but as you generate more values, the distribution will get closer to your target percentages.
- Efficiency: For very large arrays, precomputing a lookup array (e.g., 100 elements where each index maps to the corresponding value) can speed up repeated lookups, but for small arrays like your example, the loop approach works perfectly.
内容的提问来源于stack exchange,提问作者Prodip0609
相关产品推荐
相关产品推荐

