我修改了你的代码,使其可以接受已生成的序列作为输入,而不是计算随机数:
def averager(seqs):
tests = []
for s in seqs:
tests.append(len(set(s)))
return float(sum(tests))/len(tests)
然后我编写了一个函数,用于返回任何给定人数和猜测范围的所有可能选择:
def combos(n, limit):
return itertools.product(*((range(limit),) * n))
(Python 让我着迷的一点是,它非常容易将函数分解成简单的部分。)
然后我开始使用越来越大的数字进行测试:
for n in range(2,100):
x = averager(combos(n, n))
print n, x, x/n
2 1.5 0.75
3 2.11111111111 0.703703703704
4 2.734375 0.68359375
5 3.3616 0.67232
6 3.99061213992 0.66510202332
7 4.62058326038 0.660083322911
8 5.25112867355 0.656391084194
这个算法的复杂度非常高,所以在这一点上我遇到了MemoryError。正如您所看到的,随着人数和猜测范围的增加,唯一结果的百分比不断下降。
使用随机数字重复测试:
def rands(repeats, n, limit):
for i in range(repeats):
yield [random.randint(0, limit) for j in range(n)]
for n in range(10, 101, 10):
x = averager(rands(10000, n, n))
print n, x, x/n
10 6.7752 0.67752
20 13.0751 0.653755
30 19.4131 0.647103333333
40 25.7309 0.6432725
50 32.0471 0.640942
60 38.3333 0.638888333333
70 44.6882 0.638402857143
80 50.948 0.63685
90 57.3525 0.63725
100 63.6322 0.636322
正如您所看到的,结果与我们之前看到的以及您自己的观察一致。我相信一些组合数学可以解释这一切。
set(l)
?不同的人可能会猜到相同的数字。 - SethMMorton