我使用长度为N和条目总和S的自然数向量,例如,使用(N,S)=(4,7)一个示例向量 E=[1,2,1,3] ,其中所有条目在向量中假设> 0。
我想列出具有相同配置(N,S)=(4,7)的所有向量,但应该过滤掉旋转。
问题:最好的算法是什么?
(我的实际实现是在 Pari/GP 中,它提供了一个嵌套的 for 循环,使用一个边界向量来表示上下索引值)
我首先尝试了一个“蛮力”解决方案,因为我使用嵌套的 for 循环生成一个列表,但将向量连接的双重concat(E,E)存储在列表EE[]中,然后,对于每个新向量E=[e_1,e_2,e_3,e_4]检查该向量是否出现在已检查列表EE[]的串联向量中,如果没有,则将其附加为新的有效条目
EE[k]=E||E = [e_1,e_2,e_3,e_4,e_1,e_2,e_3,e_4]。此处的比较类似于字符串比较 - 如果匹配从位置1或最多N开始,则始终找到匹配。
这种方法有效,但在我看来有点像蛮力,并且由于其组合结构随着N和S的增加而爆炸。
是否存在更好的方法?
注意:目标语言是Pari/GP
注意:伪算法就足够了 - 但也许 Pari/GP 中的工具允许一些更紧凑的解决方案/符号。
例子,(N,S)=(4,7)
下面是一个非常简单的例子。
假设通过嵌套循环,我通过以下方式获得向量E :
[1,1,1,4] --- first vector: store as [1,1,1,4;1,1,1,4] in EE
[1,1,2,3] --- 2nd vector: not in EE so far, append as [1,1,2,3;1,1,2,3] to EE
[1,2,1,3] ...
[2,1,1,3] ...
[1,1,3,2] --- ignore!! This is a rotation of an earlier entry (is in EE)
[1,2,2,2]
...
这将依次构建向量列表EE:
[1,1,1,4;1,1,1,4]
[1,1,2,3;1,1,2,3]
[1,2,1,3;1,2,1,3]
[2,1,1,3;2,1,1,3]
[1,2,2,2;1,2,2,2]
这个列表,只有前N列,是我以后要使用的向量列表。
额外的完整性检查:对于(N,S)=(4,16)我得到未过滤列表length_unfiltered = 455,并且在删除旋转后length_filtered=116 。