这是执行此操作的“正确”方法.在每种法律组合均具有同等可能性的意义上说正确.缺点是它比@BradSolomon的贵一点:
>>> 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='
>>> deviant_sep(3, 8)
array(['N', 'N', 'D', 'N', 'N', 'N', 'N', 'D', 'N', 'N', 'D'],
dtype='
>>> deviant_sep(3, 8)
array(['N', 'N', 'D', 'N', 'N', 'N', 'D', 'N', 'N', 'D', 'N'],
dtype='
>>>
>>> from timeit import repeat
>>> repeat('deviant_sep(1000, 8000)', globals=globals(), number=1000)
[0.2079479000531137, 0.20392047404311597, 0.20519483496900648]
说明:我怀疑使这种变慢的原因是numpy的选择没有替换功能,我认为它会生成完整的排列,然后将其截断.
该方法的工作原理如下:我们可以通过在每个D之前删除2个Ns,将具有nD Ds和nN Ns的合法模式映射到具有nD Ds和nN-2 nD Ns的模式,然后通过插入2来将后者的任何模式转换为合法模式每个D之前的Ns.此映射为1比1.无约束的模式我们知道如何以相等的概率绘制.因此,我们这样做,然后通过在每个D之前插入2 N来映射到合法模式.