Сгенерируйте два списка случайных чисел, чтобы получить фиксированную сумму

#python #numpy #random

Вопрос:

Мне нужно сгенерировать два списка (назовем их X и Y), сумма которых равна определенному числу.

Функция, которую мне нужно создать, будет принимать в качестве входных данных длину X и Y и сумму.

Затем он создает случайные положительные числа для X и отрицательные числа для Y и нормализует их, чтобы сложить в число, которое я хочу.

Я пробовал делать это вот так:

 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  

Код работает как для положительных , так и для отрицательных чисел, поскольку balance , как я мог бы улучшить его, чтобы он также работал, если balance == 0 бы ?

Если я это сделаю extractAmount(2, 3, 100) , то на выходе получится [49.0, 350.0, -44.0, -68.0, -186.0] , что моя проблема в том , что если я это сделаю extractAmount(2, 3, 0) , он вернется [0.0, 0.0, 0.0, 0.0, 0.0] , в то время как мне нужно, чтобы это были случайные значения, а не все нули.

Комментарии:

1. Меня смущает, чего ты на самом деле хочешь. Вы сказали, что функция принимает длины каждого списка, но, исходя из вашего кода, ina-это максимальное значение положительных чисел, а outa-максимальное значение отрицательных чисел.

2. Вы должны предоставить примеры ввода/вывода

3. ina и outa-это длина, которую я хочу для X и Y (в коде valin и valout). Используя random.random((1,3)) (как в ina=3), я получаю 3 случайных числа в массиве, я ошибаюсь?

4. @DuccioBorchi вы используете Python 2 или 3? Модуль random для меня так не работает. передача кортежа в random.random приводит к исключению аргумента

5. Python 3, и это работает для меня

Ответ №1:

Я думаю, что вам нужно еще одно ограничение, чтобы проблема была четко определена. Например, вы можете потребовать, чтобы значения x имели определенное среднее значение, скажем, 200. Затем вы можете сначала масштабировать случайные значения x, чтобы удовлетворить этому требованию, а затем масштабировать случайные значения y, чтобы удовлетворить требованию баланса в сочетании с 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]))  

Комментарии:

1. Это может быть решением, единственная проблема в том, что у меня нет среднего значения для x или y, я думаю, что, возможно, я мог бы сгенерировать число, а затем сгенерировать остальные, начиная с первого

2. Но вам все равно нужно будет ввести ограничение на то, как вы создадите это первое число. Если у вас нет среднего значения, может быть, вы могли бы обосновать какое-то максимальное значение для элементов x и использовать np.random.randint для генерации x без масштабирования?

3. Да, мне это понравилось, и это работает, я использовал a (random.random()*b_mean)/ina , где ina-длина x, а b_mean-среднее значение всего баланса (раньше они хранились в словаре). Поэтому я думаю, что это хорошее решение, если вы знаете возможное среднее значение одного из векторов