我正在尝试生成15个数组中某些值的所有可能组合,最多可添加50个。
$a = [3, 4, 1, 2, 5]
print $a.repeated_permutation(15).to_a
在这种情况下,
[2,2,2,2,4,4,4,4,4,4,4,4,4,3,3]
[2,2,2,4,2,4,4,4,4,4,4,4,4,3,3]
[2,2,4,2,2,4,4,4,4,4,4,4,4,3,3]
都是可能的答案。
经过一番调查后,我意识到执行此操作的代码有点过头,但如果有可能对其他人有所帮助,我会提出问题。
关于我正在做什么的参考,项目欧拉,问题114.这是非常困难的,所以我试图只解决一个案例,我的50空间长网格只填充3单元长块。这些块必须至少由一个空格分隔,所以我将这些块计为4.这个(有一些调整,我已经遗漏了,因为这已经足够令人困惑)允许12个块加上3个单个空白,或者最大值十五个元素。
答案 0 :(得分:1)
<强>方法强>
我认为递归是这里的方法,你的递归方法如下所示:
def recurse(n,t)
,其中
n
是所需元素的数量;和t
是必需的总数。如果我们让@arr
成为您给出的整数数组,recurse(n,t)
将返回一个数组,其中包含来自n
的{{1}}个元素的所有排列,其总和为{{1} }}
<强>假设强>
我假设@arr
的元素是非负整数,按大小排序,但如果它包含负整数,则可以很容易地修改该方法(尽管性能会受到影响)。在不失一般性的情况下,我们可以假设t
的元素是唯一的,按增加的幅度排序。
<强>代码强>
@arr
<强>实施例强>
@arr
<强>改进强>
然而,我们可以通过首先计算所有组合,然后计算每种组合的排列来做得更好。
def recurse(n,t)
if n == 1
@arr.include?(t) ? [[t]] : nil
else
@arr.each_with_object([]) do |i,a|
break if i > t # as elements of @arr are non-decreasing
if (ret = recurse(n-1,t-i))
ret.each { |b| a << [i,*b] }
end
end
end
end
然后我们可以从组合中计算排列:
@arr = [3, 4, 1, 2, 5].sort
#=> [1, 2, 3, 4, 5]
recurse(1,4)
#=> [[4]]
recurse(2,6)
#=> [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]
recurse(3,10)
#=> [[1, 4, 5], [1, 5, 4], [2, 3, 5], [2, 4, 4], [2, 5, 3],
# [3, 2, 5], [3, 3, 4], [3, 4, 3], [3, 5, 2], [4, 1, 5],
# [4, 2, 4], [4, 3, 3], [4, 4, 2], [4, 5, 1], [5, 1, 4],
# [5, 2, 3], [5, 3, 2], [5, 4, 1]]
recurse(3,50)
#=> []
我们可以估算def combo_recurse(n,t,last=0)
ndx = @arr.index { |i| i >= last }
return nil if ndx.nil?
arr_above = @arr[ndx..-1]
if n == 1
arr_above.include?(t) ? [[t]] : nil
else
arr_above.each_with_object([]) do |i,a|
break if i > t # as elements of @arr are non-decreasing
if (ret = combo_recurse(n-1,t-i,i))
ret.each { |b| a << [i,*b] }
end
end
end
end
combo_recurse(1,4)
#=> [[4]]
combo_recurse(2,6)
#=> [[1, 5], [2, 4], [3, 3]]
combo_recurse(3,10)
#=> [[1, 4, 5], [2, 3, 5], [2, 4, 4], [3, 3, 4]]
combo_recurse(3,50)
#=> []
combo_recurse(15,50).size
#=> 132
combo_recurse(15,50).first(5)
#=> [[1, 1, 1, 1, 1, 1, 4, 5, 5, 5, 5, 5, 5, 5, 5],
# [1, 1, 1, 1, 1, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5],
# [1, 1, 1, 1, 1, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5],
# [1, 1, 1, 1, 1, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5],
# [1, 1, 1, 1, 1, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5]]
的排列数(由于未应用combo_recurse(2,6).flat_map { |a| a.permutation(a.size).to_a }.uniq
#=> [[1, 5], [5, 1], [2, 4], [4, 2], [3, 3]]
combo_recurse(3,10).flat_map { |a| a.permutation(a.size).to_a }.uniq
#=> [[1, 4, 5], [1, 5, 4], [4, 1, 5], [4, 5, 1], [5, 1, 4],
# [5, 4, 1], [2, 3, 5], [2, 5, 3], [3, 2, 5], [3, 5, 2],
# [5, 2, 3], [5, 3, 2], [2, 4, 4], [4, 2, 4], [4, 4, 2],
# [3, 3, 4], [3, 4, 3], [4, 3, 3]]
,因此会有些高):
(15,50)
即,结果大约有1,600位数。你将在这个平台上运行什么?