是否有任何众所周知的算法可以生成具有相同常数和的加权随机数阵列?
这个问题可以用另一种方式说明:比方说,我的总值是20.应该分成3个部分,每个部分的权重分别为2,4,3。 因此,我需要3个随机数,其总和为20,但分布将遵循权重。
我试过了:
Range=20
W=[2,4,3]
Prob=[i/float(sum(W)) for i in W]
Weighted_array=np.random.multinomial(Range, Prob)
还有更好的选择吗?
答案 0 :(得分:0)
<强>符号:强>
这是n=3
变量的线性丢番图方程。要在python中解析它,你可以sympy
使用from random import randint
from sympy.solvers.diophantine import diop_linear
from sympy.abc import x, y, z
# Our original equation is 2 * x + 4 * y + 3 * z = 20
# Re-arrange to 2 * x + 4 * y + 3 * z - 20 = 0, and input the left side to sympy
general_solution = diop_linear(2 * x + 4 * y + 3 * z - 20)
def get_random_valid_triple():
t0,t1 = general_solution[2].free_symbols
# You can pick whatever bounds you want here
a = randint(-100, 100)
b = randint(-100, 100)
solution = [s.subs({t0: a, t1:b}) for s in general_solution]
print(solution)
# Get a random solution
get_random_valid_triple()
:
n
蛮力:
或者,至少对于每个变量的小random.choice
和紧密边界,您可以预先计算所有可能的解决方案,并使用[0, 20 / coefficient]
每次选择一个。例如,我们将所有变量限制为正数,然后它们被强制放在import random
import itertools
n = 20
coefficients = [2, 4, 3]
valid_solutions = []
ranges = [range(0, n // k + 1) for k in coefficients]
for value in itertools.product(*ranges):
if sum(value[j] * i for j, i in enumerate(coefficients)) == n:
valid_solutions.append(value)
print("All solutions:")
print("\n".join(str(i) for i in valid_solutions))
print("Random solution:")
print(random.choice(valid_solutions))
中,并且只有14个解。我们可以在python中生成如下:
All solutions:
(0, 2, 4)
(0, 5, 0)
(1, 0, 6)
(1, 3, 2)
(2, 1, 4)
(2, 4, 0)
(3, 2, 2)
(4, 0, 4)
(4, 3, 0)
(5, 1, 2)
(6, 2, 0)
(7, 0, 2)
(8, 1, 0)
(10, 0, 0)
Random solution:
(10, 0, 0)
这会产生:
list1 = [5,1,5,5,5,1,5,5,1,5,5,5,5]
list2 = []
templist = []
for idx,val in enumerate(list1):
if (idx+1) <= (len(list1)-1):
if list1[idx+1] == 5 and list1[idx] == 5:
templist.append(val)
templist.append(1)
list2.append(val)
list2.append(42)
else:
templist.append(val)
list2.append(val)