<p>我修改了您的代码,以便它将一个已经生成的序列作为输入,而不是计算随机数:</p>
<pre><code>def averager(seqs):
tests = []
for s in seqs:
tests.append(len(set(s)))
return float(sum(tests))/len(tests)
</code></pre>
<p>然后我做了一个函数,返回<em>所有</em>任何给定人数和猜测范围的可能选择:</p>
<pre><code>def combos(n, limit):
return itertools.product(*((range(limit),) * n))
</code></pre>
<p>(关于Python,我喜欢的一件事是,很容易将一个函数分解成琐碎的部分。)</p>
<p>然后我开始用越来越多的数字进行测试:</p>
<pre><code>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
</code></pre>
<p>这个算法有一个可怕的复杂度,所以在这一点上我得到了一个内存错误。如您所见,随着人数和猜测范围的不断增加,唯一结果的百分比不断下降。你知道吗</p>
<p>用随机数重复测试:</p>
<pre><code>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
</code></pre>
<p>正如你所看到的,结果与我们之前看到的以及你自己的观察是一致的。我相信一点组合数学可以解释这一切。你知道吗</p>