0

以下问题:有一个基本三元组 (0,1,0)

现在我尝试在给定范围内创建一个已更改三元组的列表。

约束:

  1. Triple[0] 和 Triple[2] 应该有最大值 r,比如 r=0.2
  2. 总和(三倍)= 1
  3. Triple[0] 不必等于 Triple[1] 并且应该增加给定的逐步参数 s,例如 s= 0.02

在上面提到的这个例子中,我们的方法应该创建

lst = [(0.0, 1, 0.0),(0.02, 0.98, 0.), (0.04, 0.96,0), (0.04,0.94, 0.02), (0.06,0.94,0), (0.06, 0.92, 0.02), (0.06, 0.9, 0.04), ...]

有什么漂亮的方法可以做到这一点吗?

也许您有一个想法来创建没有嵌套循环的这些列表(可能使用 numpy?)。

非常感谢!

4

4 回答 4

1

您可以创建一个函数,使您描述的三元组......例如:

def make_triple(r=0.2, s=0.02):
    element_one = round(random.uniform(0, r), 2)
    max_s = r/s
    element_three = random.randint(0, max_s) * s
    element_two = round(1 - element_one - element_three, 2)
    return (element_one, element_two, element_three)

然后只需创建一个调用此函数的循环:

list_of_triples = []
for i in range(5):
    list_of_triples.append(make_triple(0.2, 0.02))

你去吧!不需要嵌套循环。

于 2012-05-23T17:32:40.497 回答
1

这是一个列表理解,它应该提供满足您的约束的所有三元组(据我所知)。由于 range 函数仅接受整数,因此它比我想要的要笨拙一些:

r = 0.2
s = 0.02
steps = int(math.ceil(r/s))
lst = [(a*s, 1-(a+b)*s, b*s) for b in range(steps) for a in range(steps)]

结果:

>>> lst[0:4]
[(0.0, 1.0, 0.0), (0.02, 0.98, 0.0), (0.04, 0.96, 0.0), (0.06, 0.94, 0.0)]
>>> lst[90:94]
[(0.0, 0.8200000000000001, 0.18), (0.02, 0.8, 0.18), (0.04, 0.78, 0.18), (0.06, 0.76, 0.18)]

在这段代码中,第一个和最后一个值仅上升到 0.18,我不确定这是否可取(约束是 < r 还是 <= r?)。如果您希望以另一种方式进行调整,则应该不难调整。

于 2012-05-23T17:52:30.073 回答
1

另一个简单的答案只是为了踢:

import numpy as np
r = .2
s = .02

a, b = np.mgrid[0:r:s, 0:r:s]
lst = np.dstack([a, 1 - (a+b), b]).reshape(-1, 3)
于 2012-05-23T19:07:46.193 回答
0

根据要求,这是一个没有 for 循环的 NumPy 解决方案。它使用 3D 数组和 NumPy 广播规则来按行和按列分配比例。scale是单列的二维数组,因此可以方便地被.T. 最后,将 3D 阵列重塑为 2D。

import numpy as np

r = .2
s = .02

scale = np.arange(r, step=s, dtype=float).reshape(-1,1)
a = np.empty((len(scale),len(scale),3), dtype=float)
a[:,:,0] = scale
a[:,:,2] = scale.T
a[:,:,1] = 1 - a[:,:,0] - a[:,:,2]

print a.reshape(-1,3)
于 2012-05-23T18:04:43.653 回答