【发布时间】:2019-02-20 10:22:03
【问题描述】:
我有以下问题,可以总结如下:
假设你有两个大于 0 的整数 N(它定义了 数组
n=np.array(range(N)) 和 M。我们想生成所有 可能的元素组合 ofn有长度 M,条件是没有相等的元素是连续的。
例如,对于 N=3 (n=[0,1,2]) 和 M=3,我们应该得到:
(0,1,0), (0,1,2) (0,2,0), (0,2,1), (1,0,1), (1,0,2), (1,2,0), (1,2,1), (2,0,1), (2,0,2), (2,1,0), (2,1,2)
即(0,0,1), (1,1,1), (2,1,1)...等组合不必出现。
请注意,所有有效组合的数量仅由N*(N-1)**(M-1) 给出。
到目前为止,对于这样的例子,我正在使用这个简单的脚本(它还计算从 m=1 到 m=M 的所有不同长度的组合):
import numpy as np
N = 3
M = 3
p = np.array(range(N))
ic = [0]*M
c2 = np.zeros((int(N*(N-1)**(M-1)),M))
c1 = np.zeros((int(N*(N-1)**(M-2)),M-1))
c0 = np.zeros((int(N*(N-1)**(M-3)),M-2))
for i in p:
c0[ic[0],:] = [i]
ic[0] += 1
for j in p[p!=i]:
c1[ic[1],:] = [i,j]
ic[1] += 1
for k in p[p!=j]:
c2[ic[2],:] = [i,j,k]
ic[2] += 1
问题在于,这只适用于 M=3 的特定情况,并且 M 可以是任何大于 0 的整数。所以对于某些 M,前面的代码应该有 M 个必须手动引入的嵌套循环。
我尝试定义一个可变循环数的递归函数,例如计算组合的 number 的函数(上面的等式给出的数字):
def rec_f(c,N,M):
if n>=1:
for x in range(N):
c=rec_f(c,N,M-1)
else:
c += 1
return c
我什至不知道为什么它适用于那个简单的问题。现在,问题是我需要知道先前循环的索引才能复制生成所有可能组合的脚本,但我不知道该怎么做。
我还尝试制作一个独特的for 循环(将迭代 N*(N-1)^(M-1) 次),记住这些组合可以表示为以 N 为底的数字,但玩了一段时间后,我没有任何用处。
如果有任何帮助,我将不胜感激,在此先感谢(很抱歉发了这么长的帖子)!
【问题讨论】:
标签: python numpy for-loop recursion combinatorics