Julia 重新。分区()

Julia 重新。分区(),julia,combinatorics,Julia,Combinatorics,为什么 返回而不是 julia> collect(partitions(1,2)) 0-element Array{Any,1} 我真的必须这么做吗 2-element Array{Any,1}: [0,1] [1,0] 要将结果转换为二维数组,请执行以下操作: 在数论和组合数学中,正整数n的划分,也称为整数划分,是将n写成正整数和的一种方式 对于数组转换,请尝试: x = collect(partitions(n,m)); y = Array(Int64,length(x),le

为什么

返回而不是

julia> collect(partitions(1,2))
0-element Array{Any,1}
我真的必须这么做吗

2-element Array{Any,1}:
 [0,1]
 [1,0]
要将结果转换为二维数组,请执行以下操作:

在数论和组合数学中,正整数n的划分,也称为整数划分,是将n写成正整数和的一种方式

对于数组转换,请尝试:

x = collect(partitions(n,m));
y = Array(Int64,length(x),length(x[1]));
for i in 1:length(x)
    for j in 1:length(x[1])
        y[i,j] = x[i][j];
    end
end

然后

从:

在数论和组合数学中,正整数n的划分,也称为整数划分,是将n写成正整数和的一种方式

对于数组转换,请尝试:

x = collect(partitions(n,m));
y = Array(Int64,length(x),length(x[1]));
for i in 1:length(x)
    for j in 1:length(x[1])
        y[i,j] = x[i][j];
    end
end

然后

中的MATLAB脚本实际上按照我需要的方式运行,我认为partitions()会按照给出的描述执行。朱莉娅的版本是

julia> hcat(x...)
3x2 Array{Int64,2}:
 3  2
 1  2
 1  1
使用daycaster可爱的hcat(x…)小贴士:) 我仍然希望有一种更紧凑的方法来实现这一点

第一次提到这种方法似乎是,据我所知,它是基于“星条旗”方法的

的MATLAB脚本实际上按照我所需要的方式运行的,并且是我认为分区()根据给出的描述所做的。朱莉娅的版本是

julia> hcat(x...)
3x2 Array{Int64,2}:
 3  2
 1  2
 1  1
使用daycaster可爱的hcat(x…)小贴士:) 我仍然希望有一种更紧凑的方法来实现这一点


第一次提到这种方法似乎是,据我所知,它是基于“星条旗”方法的

# k - sum, n - number of non-negative integers
function nsumk(k,n)
  m = binomial(k+n-1,n-1);
  d1 = zeros(Int16,m,1);
  d2 = collect(combinations(collect((1:(k+n-1))),n-1));
  d2 = convert(Array{Int16,2},hcat(d2...)');
  d3 = ones(Int16,m,1)*(k+n);
  dividers = [d1 d2 d3];
  return diff(dividers,2)-1;
end

julia> nsumk(3,2)
4x2 Array{Int16,2}:
 0  3
 1  2
 2  1
 3  0
这会分配大量内存,但我认为您当前的方法也是如此。也许制作一个一流的版本并将其添加到combinationics.jl中会很有用

示例:

multisets(n, k) = map(A -> [sum(A .== i) for i in 1:n],
                      with_replacement_combinations(1:n, k))

参数顺序与您的相反,以符合数学约定。如果您喜欢另一种方式,则可以很容易地改变。

这里有另一种解决问题的方法,我认为更简单,使用Combinatics.jl库:

# k - sum, n - number of non-negative integers
function nsumk(k,n)
  m = binomial(k+n-1,n-1);
  d1 = zeros(Int16,m,1);
  d2 = collect(combinations(collect((1:(k+n-1))),n-1));
  d2 = convert(Array{Int16,2},hcat(d2...)');
  d3 = ones(Int16,m,1)*(k+n);
  dividers = [d1 d2 d3];
  return diff(dividers,2)-1;
end

julia> nsumk(3,2)
4x2 Array{Int16,2}:
 0  3
 1  2
 2  1
 3  0
这会分配大量内存,但我认为您当前的方法也是如此。也许制作一个一流的版本并将其添加到combinationics.jl中会很有用

示例:

multisets(n, k) = map(A -> [sum(A .== i) for i in 1:n],
                      with_replacement_combinations(1:n, k))

参数顺序与您的相反,以符合数学约定。如果您喜欢另一种方式,则很容易改变。

可以使用字典学预设生成算法实现一种稳健的解决方案,该算法最初由Donald Knuth和经典的
分区(n)

这就是词典学的前置变形生成器:

julia> multisets(2, 1)
2-element Array{Array{Int64,1},1}:
 [1,0]
 [0,1]

julia> multisets(3, 5)
21-element Array{Array{Int64,1},1}:
 [5,0,0]
 [4,1,0]
 [4,0,1]
 [3,2,0]
 [3,1,1]
 [3,0,2]
 [2,3,0]
 [2,2,1]
 [2,1,2]
 [2,0,3]
 ⋮      
 [1,2,2]
 [1,1,3]
 [1,0,4]
 [0,5,0]
 [0,4,1]
 [0,3,2]
 [0,2,3]
 [0,1,4]
 [0,0,5]
然后,我们将使用
分区(n)
(忘记所需数组的长度m)生成求和为n的所有整数数组,并使用
resize\将它们调整到长度m

julia> lpremutations([2,2,0])
3-element Array{Array{Int64,1},1}:
 [0,2,2]
 [2,0,2]
 [2,2,0]
主要功能如下所示:

function resize_!(x,m)
  [x;zeros(Int,m-length(x))]
end
检查它

function lpartitions(n,m)
  result=[]
  for i in partitions(n)
    append!(result,lpremutations(resize_!(i, m)))
  end
  result
end 

一个健壮的解决方案可以通过使用字典学前置生成算法来实现,该算法最初由Donald Knuth和经典的
分区(n)

这就是词典学的前置变形生成器:

julia> multisets(2, 1)
2-element Array{Array{Int64,1},1}:
 [1,0]
 [0,1]

julia> multisets(3, 5)
21-element Array{Array{Int64,1},1}:
 [5,0,0]
 [4,1,0]
 [4,0,1]
 [3,2,0]
 [3,1,1]
 [3,0,2]
 [2,3,0]
 [2,2,1]
 [2,1,2]
 [2,0,3]
 ⋮      
 [1,2,2]
 [1,1,3]
 [1,0,4]
 [0,5,0]
 [0,4,1]
 [0,3,2]
 [0,2,3]
 [0,1,4]
 [0,0,5]
然后,我们将使用
分区(n)
(忘记所需数组的长度m)生成求和为n的所有整数数组,并使用
resize\将它们调整到长度m

julia> lpremutations([2,2,0])
3-element Array{Array{Int64,1},1}:
 [0,2,2]
 [2,0,2]
 [2,2,0]
主要功能如下所示:

function resize_!(x,m)
  [x;zeros(Int,m-length(x))]
end
检查它

function lpartitions(n,m)
  result=[]
  for i in partitions(n)
    append!(result,lpremutations(resize_!(i, m)))
  end
  result
end 

我认为它计算非零元素的向量。我认为它计算非零元素的向量。我认为这回答了第二个问题,但不是第一个问题。我建议您在答案中加入@Reza的评论,以获得更完整的解决方案。@niczky12是的,我没有真正理解问题的这一部分-可能它们不包括0,因为它们会出现在每个可能的分区中……这是对“分区”一词含义的不同看法吗?我似乎记得以前有过关于这一点的讨论,不确定是在这里还是在julia-users上。@DavidP.Sanders不知道,我所知道的唯一的分区是那些在隔间中分隔工人的分区…:)谢谢你的回答,hcat(x…)的花边是金色的。我想如果零不是一个正整数,那么实现就有意义了。求和的顺序在许多应用程序(例如我的应用程序)中都很重要,但我想在许多情况下,仅列出唯一的无序解决方案也是有效的。我认为这回答了第二个问题,但不是第一个问题。我建议您在答案中加入@Reza的评论,以获得更完整的解决方案。@niczky12是的,我没有真正理解问题的这一部分-可能它们不包括0,因为它们会出现在每个可能的分区中……这是对“分区”一词含义的不同看法吗?我似乎记得以前有过关于这一点的讨论,不确定是在这里还是在julia-users上。@DavidP.Sanders不知道,我所知道的唯一的分区是那些在隔间中分隔工人的分区…:)谢谢你的回答,hcat(x…)的花边是金色的。我想如果零不是一个正整数,那么实现就有意义了。求和的顺序在许多应用程序(例如我的应用程序)中都很重要,但我想在许多情况下,仅列出唯一的无序解决方案也是有效的。实际上,这是从n个符号中选择大小为S的多个集合。在某些情况下,这可能是一个有用的函数。也许可以考虑将它添加到组合数学中。JL?有效地,这是从N个符号中选择的多个大小的S。在某些情况下,这可能是一个有用的函数。也许可以考虑把它添加到组合数学中。JL?这真的很好,很紧凑。我正在摆弄(at)time宏,看看你的代码是否有什么不同,我从MATLAB移植到Julia的代码。。。(at)时间x=nsumk(k,n)和(at)时间y=hcat(多集(n,k)…)”,分别给出0.007708秒(36.51k分配:2.708MB)和1.065818秒(342.59 k al)