Algorithm 计算julia中置换的最优方法

Algorithm 计算julia中置换的最优方法,algorithm,julia,combinatorics,Algorithm,Julia,Combinatorics,考虑一个列表[1,1,1,…,1,0,0,…,0](一个由0和1组成的任意列表)。我们需要这个数组中所有可能的排列,将有二项式(l,k)排列(l表示列表的长度,k表示列表中的个数) 现在,我已经测试了三种不同的算法来生成整个可能的排列,一种使用递归函数,一种计算 通过计算区间数的排列[1,…,1,0,0,…,0] 到[0,0,…0,1,1,…,1](因为这可以看作是一个二进制数间隔),以及使用字典顺序计算排列的间隔 到目前为止,前两种方法在执行排列时失败 大约32。词典编纂技术仍然非常有效(只需

考虑一个列表
[1,1,1,…,1,0,0,…,0]
(一个由0和1组成的任意列表)。我们需要这个数组中所有可能的排列,将有
二项式(l,k)
排列(
l
表示列表的长度,
k
表示列表中的个数)

现在,我已经测试了三种不同的算法来生成整个可能的排列,一种使用递归函数,一种计算 通过计算区间数的排列
[1,…,1,0,0,…,0]
[0,0,…0,1,1,…,1]
(因为这可以看作是一个二进制数间隔),以及使用字典顺序计算排列的间隔

到目前为止,前两种方法在执行排列时失败 大约32。词典编纂技术仍然非常有效(只需几毫秒即可完成)

我的问题是,特别是对于julia,哪种方法是计算的最佳方法
如我前面所述的排列?我对组合学知道的不多,但我认为下降基准应该是从总的
二项式(l,l/2)

中生成所有排列,正如您在评论中提到的,在这种情况下,
l>>k
是绝对需要的。在这种情况下,我们可以通过不处理长度为
l
的向量(直到我们真正需要它们),而是处理这些向量的索引列表来显著提高性能

在中,以下算法将允许您迭代空间
O(k^2)
和时间
O(k^2*binom(l,k))

但是,请注意,每次从索引组合生成位向量时,都会产生开销
O(l)
,其中也会有下限(对于所有组合)为
Omega(l*binom(l,k))
,并且内存使用量会增加到
Omega(l+k^2)

算法 例子 然后,您可以按如下方式迭代所有组合:

for c in @task(combination_producer(l, k))
    # do something with c
end
请注意此算法的可恢复性:您可以随时停止迭代,然后再次继续:

iter = @task(combination_producer(5, 3))
for c in iter
    println(c)
    if c[1] == 2
        break
    end
end

println("took a short break")

for c in iter
    println(c)
end
这将产生以下输出:

[1,2,3]
[1,2,4]
[1,2,5]
[1,3,4]
[1,3,5]
[1,4,5]
[2,3,4]
took a short break
[2,3,5]
[2,4,5]
[3,4,5]
如果你想从
c
中得到一个位向量,你可以这样做

function combination_to_bitvector(l, c)
    result = zeros(l)
    result[c] = 1
    result
end

<> > <代码> L>代码>是位向量的期望长度。

“最佳方式”将取决于问题的约束(列表的最大大小是什么?代码< > L<代码/代码>和<代码> k>代码>均匀分布)和您认为最好的值。(最简单、最快或最直接?针对使用的总内存或CPU时间进行了优化?)。听起来你已经有了一个很好的解决方案。你为什么不满意呢?实际上,
k
l
的值是任意的。灵感来自于一个由费米子组成的物理系统。恰巧描述它的一个合适的数学基础是(Fock基)[,它具有维度
二项式(l,k)
基础的一个成员是我给出的带有0和1的列表的一些排列。如果我没记错的话,一个好的例子是
l>>k
,这个想法是有足够大的基础来模拟一个合适的物理系统(在fortran中,我或多或少地快速地执行了类似于
~10^4
基本维度的操作).另一方面,我希望算法足够快,可以生成整个基础,如果可能的话,可以节省尽可能多的内存。最后的灵感是学习新的组合算法,并朝着这个方向深入研究,这是我想要真正探索的。这个实现似乎不再有效(在Julia 1.1中测试)。特别是,
product
不久前已被弃用,我不知道它是如何被替换的。您能否将此答案至少更新为Julia 1.0?
function combination_to_bitvector(l, c)
    result = zeros(l)
    result[c] = 1
    result
end