生成排列的算法的复杂性
Posted
技术标签:
【中文标题】生成排列的算法的复杂性【英文标题】:Complexity of the algorithm that generates permutations 【发布时间】:2015-04-07 16:57:55 【问题描述】:我很难理解如何确定该算法的时间复杂度(用 Python 编写,但适用于任何语言):
def permutazioni(list):
n = len(list)
if n == 1 or n == 0:
return [list]
else:
risult = []
for i in range(n):
primo = list[i]
listaDegliAltri = list[:i] + list[i + 1:]
perms = permutazioni(listaDegliAltri)
for perm in perms:
risult.append([primo] + perm)
return risult
此过程将一个序列作为输入,并作为结果返回一个序列序列,该序列包含起始序列的所有可能排列的集合。
例子:permutations([a, b, c]) = [[a, b, c], [a, c, b], [b, a, c], [b, c, a], [c, a , b], [c, b, a]]
现在,要确定复杂性,我必须编写并求解递推方程。 当列表长为 0 或 1 时,不进行任何操作。 否则,您将运行 n 次迭代循环,其中每次迭代都会在一个元素短于 (n-1) 的列表上调用函数,然后运行内部长n-1。
教授接着写道:
T(0) = T(1) = 1(1为什么?是退货的成本还是其他?)
T(n) = n*(T(n-1) + (n-1)) 对于 n>1
然后他说选择下界然后写(以后什么都不懂):
T(n) > n*T(n-1)
来自:
T(n) > nT(n-1) > n(n-1)T(n-2) > n(n- 1)*(n-2)*T(n-3)> ... > n!
即:
T(n) = Ω(n!)
我不明白,因为它消除了 (n-1) 并且因为它使用了大调而不是等号。所以我什么都不懂。 有人给我解释一下就知道了? 谢谢
【问题讨论】:
【参考方案1】:这只是很多容易出错但非常基本的代数。
M(1) 和 M(0) 为 1 的原因是因为如果您有一个包含 1 个或零个元素的列表,那么该列表本身就是它的唯一排列。例如1
只有一个排列, 也是如此。所以 1 本身与所做的工作无关,但实际上只有一个排列。但也确实,你只是简单地返回它,所以你可以这样想。
现在是更有趣/无聊的部分。
如果你接受
T(0) = T(1) = 1
T(n) = n*(T(n-1) + (n-1)) 对于 n>1
剩下的就是繁琐的代数了。所以首先说 T(n-1)=T(k)。所以
T(n) = n*((k*(T(k-1) + (k-1))) + (n-1))
T(n) = n*(((n-1)*(T(n-1-1) + (n-1-1))) + (n-1))
T(n) = n*((k*(T(n-2) + (n-2))) + (n-1))
T(n) = n^3 + n^2*T(n-2) - 2n^2-n*T(n-2)+n:这只是代数展开.
如果你替换T(n-2),然后用T(k)替换T(n-3),你会看到阶乘模式出现,即n! = n*(n-1)!
【讨论】:
【参考方案2】:您的教授可能应该写成 T(0) = T(1) = Theta(1),这意味着在这些情况下它需要恒定的时间,但是仅仅放置一个像 1 这样的固定常数通常不会改变渐近线。至于其他的,如果你相信的话
T(n) = n*(T(n-1) + Theta(n-1))
(我再次使用 big-Theta 来强调在计算操作时可能存在隐藏的常数乘数),那么您显然明白了
T(n) > n*T(n-1)
因为你减去了正项 Theta(n-1)。其余的遵循阶乘的定义。
【讨论】:
以上是关于生成排列的算法的复杂性的主要内容,如果未能解决你的问题,请参考以下文章