<p>以下是正确的方法。正确的意思是每一个合法的结合都是同样可能的。缺点是它比@BradSolomon的贵一点:</p>
<pre><code>>>> def deviant_sep(N_D, N_N):
... Didx = np.random.choice(N_N-N_D, N_D, replace=False)
... out = np.zeros((N_N + N_D,), bool)
... out[Didx] = True
... Didx = np.flatnonzero(out[:N_N-N_D])
... out[Didx] = False
... out[Didx + np.arange(2, 2*N_D+2, 2)] = True
... return np.array(['N', 'D'])[out.view(np.int8)]
...
>>> deviant_sep(3, 8)
array(['N', 'N', 'D', 'N', 'N', 'N', 'N', 'D', 'N', 'N', 'D'],
dtype='<U1')
>>> deviant_sep(3, 8)
array(['N', 'N', 'D', 'N', 'N', 'N', 'N', 'D', 'N', 'N', 'D'],
dtype='<U1')
>>> deviant_sep(3, 8)
array(['N', 'N', 'D', 'N', 'N', 'N', 'D', 'N', 'N', 'D', 'N'],
dtype='<U1')
>>>
>>> from timeit import repeat
>>> repeat('deviant_sep(1000, 8000)', globals=globals(), number=1000)
[0.2079479000531137, 0.20392047404311597, 0.20519483496900648]
</code></pre>
<p>解释:我怀疑是numpy的<code>choice</code>没有替换函数导致了这种速度变慢,我认为它会生成一个完整的置换,然后将其截断。你知道吗</p>
<p>该方法的工作原理如下:我们可以通过在每个<code>D</code>之前移除2 <code>N</code>来将<code>nD</code><code>D</code>s和<code>nN - 2 nD</code><code>N</code>s的合法模式映射到<code>nD</code>s和<code>nN - 2 nD</code><code>N</code>s的模式,反之,通过在每个<code>D</code>之前插入2 <code>N</code>s的合法模式。这张地图是1比1。以及我们知道如何以等概率绘制的无约束模式。所以我们这样做,然后映射到合法模式,在每个<code>D</code>之前插入2<code>N</code>。你知道吗</p>