Create constrained random numbers?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Creating constrained random numbers is not one single technique. The right method depends on the constraint: a bounded range, uniqueness, a fixed total sum, weighted probabilities, or more complex rules such as parity or ordering.
Start By Classifying The Constraint
Before choosing code, decide which kind of constraint you have.
Common cases are:
- one random number in a range
- several unique random numbers
- numbers that must add up to a target
- numbers drawn with non-uniform weights
- values that must satisfy a predicate
Different constraints imply different algorithms. A mistake many people make is trying to solve all of them with random.randint and repeated retries.
Simple Range Constraints
If the only rule is "pick a value between a and b", use the standard random API directly.
For floating-point values in a closed-open interval style, use uniform.
This is the easy case because the generator already matches the constraint.
Unique Integers Without Replacement
If you need several distinct integers, use sampling without replacement instead of repeatedly generating values and checking for duplicates.
This guarantees uniqueness and is clearer than looping until a set reaches the required size.
Values That Must Sum To A Target
A common constrained-random problem is generating n non-negative integers that add up to a fixed total.
One clean approach is to generate random cut points and convert the gaps into parts.
This returns four non-negative integers whose sum is always 10.
If you need strictly positive integers, allocate one unit to each part first and partition the remainder.
Weighted Random Choices
Sometimes the constraint is probabilistic rather than structural. For example, you may want small numbers to be more likely than large ones.
Use weighted choice instead of manual hacks.
This does not guarantee exact frequencies in small samples, but it respects the weight distribution over repeated draws.
Rejection Sampling For Predicate Constraints
If the rule is something like "generate a random point inside a circle" or "pick a value that passes condition X", rejection sampling is often the simplest method.
Generate candidates from a broader easy distribution, and reject the ones that fail.
This is fine when the acceptance rate is reasonably high. It becomes inefficient when valid outputs are rare.
Generate In The Constrained Space When You Can
The best constrained-random algorithm is usually the one that samples directly from valid states rather than sampling invalid states and rejecting them.
For example, for even numbers in a range, do not use rejection sampling if you can map the problem directly:
This is cleaner and has predictable performance.
Think About Distribution, Not Only Validity
A subtle but important issue is whether all valid outputs should be equally likely. Some improvised algorithms satisfy the constraint but bias the distribution.
For example, repeatedly picking random values and clipping them into range is not the same as uniform sampling in range. Likewise, building partitions incrementally can bias certain compositions unless the algorithm was designed carefully.
So the real question is often:
- do I only need valid values?
- or do I need valid values with a specific distribution?
That distinction matters a lot in simulations and tests.
Common Pitfalls
- Using rejection sampling when valid outputs are extremely rare.
- Forgetting to ask whether the valid outputs should be uniformly distributed.
- Reimplementing unique sampling with loops when
random.samplealready solves it. - Generating floats and rounding them, which often distorts the intended distribution.
- Solving a structured constraint with ad hoc retries instead of generating directly in the valid space.
Summary
- Constrained random generation depends on the exact constraint you need to satisfy.
- Use direct APIs for simple ranges and
random.samplefor uniqueness. - For fixed-sum problems, partition the total instead of guessing and retrying.
- Rejection sampling is fine for simple predicates with good acceptance rates.
- Always think about distribution as well as validity.

