Ruby组合函数的顺序复杂性

时间:2014-05-05 09:34:33

标签: ruby algorithm big-o complexity-theory

在我的一个算法中,我使用了Ruby的combinationpermutation方法。我必须讨论这种算法的复杂性。我在哪里可以找到有关其复杂性/实施的信息?

我尝试过一个简单的手工制作的'功能,但Ruby似乎在接近恒定的时间运行!

非常感谢任何关于去哪儿的信息。

2 个答案:

答案 0 :(得分:1)

实施可以显示在您链接的相同页面上。将鼠标悬停在组合/置换方法的名称上,然后选择click to toggle source

您可以在主仓库中查看最新和不同版本的来源:http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/

您可以阅读array.c的修订历史记录,以查看可能/何时对组合/置换方法进行任何更改的原因。 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/array.c?view=log。这可能会让您了解开发人员的复杂性和设计选择。

您甚至可以向消息来源的某些贡献者询问他们为什么让XYZ改变方法的原因,他们可能/可能没有帮助。

答案 1 :(得分:1)

Ruby语言规范中没有任何内容要求实现者保证某种算法的复杂性,并且肯定没有什么能够强制实现特定的实现。

每个Ruby执行引擎都有自己的实现,它们可能有也可能没有相同的算法复杂性。

例如,Rubiniuskernel/common/array.rb#L360-394实施kernel/common/array.rb#L935-969位于kernel/common/array.rb#L971-994

Array#combination

def combination(num) num = Rubinius::Type.coerce_to num, Fixnum, :to_int return to_enum(:combination, num) unless block_given? if num == 0 yield [] elsif num == 1 each do |i| yield [i] end elsif num == size yield self.dup elsif num >= 0 && num < size stack = Rubinius::Tuple.pattern num + 1, 0 chosen = Rubinius::Tuple.new num lev = 0 done = false stack[0] = -1 until done chosen[lev] = self.at(stack[lev+1]) while lev < num - 1 lev += 1 chosen[lev] = self.at(stack[lev+1] = stack[lev] + 1) end yield chosen.to_a lev += 1 begin done = lev == 0 stack[lev] += 1 lev -= 1 end while stack[lev+1] + num == size + lev + 1 end end self end 位于{{3}}:

Array#permutation

如您所见,它委托给{{3}}中定义的名为def permutation(num=undefined, &block) return to_enum(:permutation, num) unless block_given? if undefined.equal? num num = @total else num = Rubinius::Type.coerce_to num, Fixnum, :to_int end if num < 0 || @total < num # no permutations, yield nothing elsif num == 0 # exactly one permutation: the zero-length array yield [] elsif num == 1 # this is a special, easy case each { |val| yield [val] } else # this is the general case perm = Array.new(num) used = Array.new(@total, false) if block # offensive (both definitions) copy. offensive = dup Rubinius.privately do offensive.__permute__(num, perm, 0, used, &block) end else __permute__(num, perm, 0, used, &block) end end self end 的{​​{1}}辅助方法:

private