random numbers
constant sum
number generation
mathematical algorithms
programming techniques

Generate N random numbers within a range with a constant sum

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

To generate N random numbers inside a range while forcing their total to equal a fixed sum, you have to satisfy both local bounds and a global constraint at the same time. The most important first step is checking whether the request is even feasible, because no algorithm can produce a solution when the sum lies outside the total allowed range.

Feasibility Comes First

For integer values in the interval [low, high], a solution exists only if:

N * low <= target_sum <= N * high

Example:

  • 'N = 5'
  • 'low = 2'
  • 'high = 7'
  • 'target_sum = 18'

This is feasible because 5 * 2 = 10 and 5 * 7 = 35, and 18 lies between them.

If the target sum is outside that interval, stop immediately and report failure.

A Simple Constructive Algorithm

For integers, a practical approach is to build the numbers one by one. At each step:

  1. choose a random value for the current slot
  2. keep enough sum available for the remaining slots
  3. keep the remaining slots within their own bounds

That means the choice for each number is constrained by what must still be possible afterward.

python
1import random
2
3def random_ints_with_sum(n, low, high, target_sum):
4    if target_sum < n * low or target_sum > n * high:
5        raise ValueError("No solution exists for these parameters")
6
7    result = []
8    remaining_sum = target_sum
9
10    for remaining_slots in range(n, 0, -1):
11        min_value = max(low, remaining_sum - (remaining_slots - 1) * high)
12        max_value = min(high, remaining_sum - (remaining_slots - 1) * low)
13
14        value = random.randint(min_value, max_value)
15        result.append(value)
16        remaining_sum -= value
17
18    return result
19
20nums = random_ints_with_sum(5, 2, 7, 18)
21print(nums, sum(nums))

This guarantees:

  • each value stays in range
  • the final sum is exact

Why Those Bounds Work

Suppose you are filling one position and still have remaining_slots - 1 positions left afterward. If you choose too small a value now, the remaining slots may be unable to reach the target sum even if all of them take the maximum allowed value. If you choose too large a value now, the remaining slots may be forced below the minimum allowed value.

That is why the current slot is limited to:

  • at least remaining_sum - (remaining_slots - 1) * high
  • at most remaining_sum - (remaining_slots - 1) * low

The algorithm is random, but every random choice is filtered through feasibility for the rest of the sequence.

Integer Solutions Are Not Automatically Uniform

The algorithm above produces valid random solutions, but it does not sample every valid vector with equal probability. For many applications that is completely fine. If you need a truly uniform distribution over all valid integer solutions, the problem becomes more specialized and often requires dynamic programming or combinatorial counting.

So be clear about the requirement:

  • valid random solution
  • uniformly random valid solution

Those are different tasks.

Floating-Point Variant

For real numbers rather than integers, a common trick is:

  1. shift the problem so the lower bound becomes zero
  2. generate random proportions
  3. scale them to the remaining sum
  4. add the lower bound back

That works when the target is feasible. A simple example:

python
1import random
2
3def random_floats_with_sum(n, low, high, target_sum):
4    if target_sum < n * low or target_sum > n * high:
5        raise ValueError("No solution exists for these parameters")
6
7    remaining = target_sum - n * low
8    capacity = high - low
9
10    weights = [random.random() for _ in range(n)]
11    total_weight = sum(weights)
12    values = [low + remaining * w / total_weight for w in weights]
13
14    if any(v > high for v in values):
15        return random_floats_with_sum(n, low, high, target_sum)
16
17    return values

This version may need retries because scaling random weights can overshoot the upper bound on some coordinates.

Practical Uses

This pattern appears in:

  • budget allocation simulations
  • randomized test-data generation
  • load-distribution experiments
  • game-stat generation under caps

The important thing is to define whether the numbers are integers or real values before choosing the algorithm.

Common Pitfalls

  • Forgetting the feasibility check and debugging an impossible request as if the generator were broken.
  • Using a naïve "generate random values, then normalize" approach for integers, which usually breaks the range constraints after rounding.
  • Assuming the sequential constructive algorithm is uniform over all valid solutions when it is only guaranteed to produce valid random solutions.
  • Mixing integer and floating-point requirements without noticing that the algorithms and edge cases are different.
  • Ignoring the final remaining-sum logic and choosing early values that make the rest of the sequence impossible to complete.

Summary

  • A valid generator must satisfy both per-value bounds and the total-sum constraint.
  • Always check feasibility first with N * low <= target_sum <= N * high.
  • For integers, a sequential constrained-random algorithm is simple and reliable.
  • For floating-point values, scaling random weights can work, but upper-bound handling needs care.
  • "Random valid" and "uniform over all valid solutions" are different requirements and should not be confused.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.