target = 100_000
factor = 2.2 # the exact value depends on the target
# there is always a risk that we miss a few points
size = int(target*factor)
X = np.random.uniform(0.71, 0.72, size=size)
Y = np.random.uniform(0.23, 0.24, size=size)
Z = 1-(X+Y)
idx = np.arange(size)[(Z>=0.05) & (Z<=0.06)][:target]
X = X[idx]
Y = Y[idx]
Z = Z[idx]
assert np.allclose(X+Y+Z, 1)
import random
def find_xyz():
while True:
x = random.uniform(0.71, 0.72)
y = random.uniform(0.23, 0.24)
z = 1 - x - y
if 0.05 < z < 0.06:
return x, y, z
if __name__ == "__main__":
x, y, z = find_xyz()
print(x, y, z)
print(X,Y,Z,"=",X+Y+Z)
print("X is valid: ", xMin <= X <= xMax)
print("Y is valid: ", yMin <= Y <= yMax)
print("Y is valid: ", zMin <= Z <= zMax)
0.7170555223349833 0.23168125318306362 0.05126322448195306 = 1.0
X is valid: True
Y is valid: True
Y is valid: True
import random
X = random.uniform(0.71, 0.72)
Y = random.uniform(0.23, 0.24)
Z = 1 - X - Y
# Adjust Z if it is outside the range [0.05, 0.06]
if Z < 0.05:
Z = 0.05
elif Z > 0.06:
Z = 0.06
# Print the values of X, Y, and Z
print(f"X = {X:.8f}, Y = {Y:.8f}, Z = {Z:.8f}")
import random
X, Y, Z = 0.0, 0.0, 0.0
epsilon = 0.01
target = 1
while True:
X = random.uniform(0.71, 0.72)
Y = random.uniform(0.23, 0.24)
Z = random.uniform(0.05, 0.06)
if target - epsilon <= (X + Y + Z) <= target + epsilon:
print(X, Y, Z)
upd:
import random
epsilon = 1000
x_d, x_u = 71 * epsilon, 72 * epsilon
y_d, y_u = 23 * epsilon, 24 * epsilon
z_d, z_u = 5 * epsilon, 6 * epsilon
target = 1
while True:
X = random.randint(x_d, x_u)
Y = random.randint(y_d, y_u)
Z = random.randint(z_d, z_u)
if (X + Y + Z) == target*epsilon:
print(X / epsilon, Y / epsilon, Z / epsilon)
6条答案
按热度按时间9q78igpj1#
问题是
我们希望在特定范围内选择3个坐标。然而,一旦我们选择
X
和Y
,Z
就固定了。我们不能有完全的自由度,例如,如果我们选择
X = 0.72
和Y = 0.24
,那么Z
不能存在于期望的范围内。如果我们随机选择
X
和Y
并计算Z
,在许多情况下Z
将是错误的:问题是:如何解决这个问题?
过采样
这通常不是推荐的方法,但我们可以使用试错法,这里我们需要采样两次以上,以希望有足够的有效点(在正方形上采样,保留一半的点):
使用数学
我们所寻找的等价于在三角形上生成均匀点。
可以使用this formula:
最后一步使用
einsum
:(The黑点是三角形的角)
Xmax+Ymin+Zmin == Xmin+Ymax+Zmin == Xmin+Ymin+Zmax == 1
)。如果不是这样,忽略MAX并使用corners = (1-np.identity(3))*MIN ; np.fill_diagonal(corners, 1-corners.sum(axis=1))
。eqqqjvef2#
这是生成真正随机变量的简单方法。
3zwjbxry3#
您可以将每个范围转换为从最小值(自由范围)开始的可能增量的基于零的跨度。您知道每个最小值,因此可以从计算中排除这些值,并在从其基础(最小值)随机选择偏移量后将其添加回去。这使得问题变得更简单,因为所有最小值都设置为零,只有x,y,z偏移量需要加起来才能达到剩余的范围。
结果:
第一个随机值(
xDelta
)受到其他两个值对总增量的最大贡献的约束。第二随机值(yDelta
)受(现在已知的)第一值和剩余值的隐式范围的约束。最后一个值在该点没有自由度,必须是总增量的余数。最后一个值将在它指定的范围内,因为前两个值受到了约束。不幸的是,这种方法并不能给予一个规则的分布(根据mozway的测量)。
在所有3个范围具有相同的间隔大小并且对应于与总最小值的差的特殊情况下(即,完全重叠在你的例子0.01),我能够找到一种方法来产生一个规则的分布,随机挑选两个点在0. 0.01间隔,并使用分割的3个部分作为delta值:
产出:
niknxzdl4#
np.random.dirichlet
能用吗?kxkpmulp5#
以下是节目单-
每一次,所有3个变量的值都发生变化,但总和为1。
希望这对你有帮助。
pxyaymoc6#
upd: