Home > Back-end >  Generate two lists of random numbers to obtain a fixed sum
Generate two lists of random numbers to obtain a fixed sum

Time:11-18

I need to generate two lists (let's call them X and Y) that sum to a specific number.

The function I need to create will take as inputs length of X and Y and the sum.

Then it creates random positive numbers for X and negative numbers for Y and normalizes them to sum to the number I want.

I've tried doing it like this:

def extractAmount(ina, outa, balance):
    # ina: length of X, outa: length of Y, balance: the number I want
    valin = random.random((1, ina))  # X
    valout = -random.random((1, outa))  # Y
    val = np.concatenate([valin[0], valout[0]])
    valf = (np.round(val / abs(np.sum(val)) * abs(balance))).tolist() 
    return valf

The code works both for positive and negative numbers as balance, how could I improve it to work also if balance == 0?

If I do extractAmount(2, 3, 100), the output is [49.0, 350.0, -44.0, -68.0, -186.0], my problem is that if I do extractAmount(2, 3, 0), it returns [0.0, 0.0, 0.0, 0.0, 0.0] while I need it to be random values, not all zeros.

CodePudding user response:

I think you need one more constraint for the problem to be well-defined. For example, you could require that the x values have a certain mean, say 200. Then you can first scale the random x values to meet that requirement, and then scale the random y values to meet the balance requirement in conjunction with x:

import numpy as np

def extract_amount(length_x, length_y, mean_x, balance):
    x = np.random.random(length_x)
    x *= mean_x / np.mean(x)
    y = np.random.random(length_y)
    mean_y = (np.sum(x) - balance) / length_y
    y *= - mean_y / np.mean(y)
    return x, y

# Example 1
extract_amount(2, 3, 200, 100)
(array([224.47381339, 175.52618661]),
 array([-101.83346151, -181.49633185,  -16.67020665]))
# Example 2
extract_amount(2, 3, 200, 0)
(array([268.78299914, 131.21700086]),
 array([ -80.71742313, -125.50531378, -193.77726309]))
  • Related