使用Big O计算算法复杂度

时间:2014-01-22 17:53:38

标签: algorithm big-o complexity-theory

我正在尝试使用Big O来计算算法的不同变体的复杂性。

该算法的简化描述如下:

让我们将“转换器”视为一个函数,它接受某个对象并将其转换为另一个表示。每个转换器定义其域和范围。

有一个例程,它接受一个源对象(即一个转换对象),一个转换器函数列表和预期的转换类型。

它在转换器列表上进行迭代,直到找到一个转换器,其域和范围与要转换的对象和预期的转换类型兼容。

据我所知,其复杂程度应为O(n),因为它直接取决于转换器的数量。

现在,如果每个转换器可能需要递归地调用转换例程一定次数,那么复杂性会是多少?

例如,它可能需要将源对象的某些组件转换为其他对象,这些对象稍后将被组合为要返回的对象(原始转换的目标)。

据我了解,非正式地给出了:

n + m1( n + m2 (n + m3 (...)) ) )

其中:

  • n衡量找到原始转换器的工作量。
  • m1应由转换例程转换的源对象子组件的数量。
  • m2原始m1对象的最大子组件数。
  • 等...

作为一个额外的细节,每次递归调用时,转换的子组件数量应该减少。

这是对的吗?如果是这样,我应该如何将此公式减少为Big O表示法?

最后,如果有一种智能索引系统允许我在转换器列表中快速找到正确的转换器功能,那么复杂性会是多少? 据我所知,在最简单的情况下,转换器不会递归地调用转换函数,这应该是O(log n),对吗?

但是,如果每个转换器(如前一种情况)可能需要递归调用转换函数,那么基于索引的算法的复杂性会是多少?

1 个答案:

答案 0 :(得分:0)

  

据我所知,其复杂程度应为O(n),因为它直接取决于转换器的数量。

不一定。渐近复杂度与输入的大小(以字节为单位)有关。如果您的对象具有恒定大小,那么总输入大小(您的N)将渐近地与转换器的数量成比例,因此迭代它们将是O(N)。另一方面,如果你的对象很大 - 比如m乘m矩阵,其中m是转换器的数量 - 那么你的N将与m ^ 2成比例,迭代将是O(m),只有O(sqrt(n))。另一个重要的情况是当转换器的数量由常量限制而不是调用者可以设置为他想要的高度时 - 在迭代为O(1)的情况下。

  

现在,如果每个转换器可能需要递归地调用转换例程一定次数,那么复杂性会是多少?

很难说不知道转换器做了什么。就我们所知,他们可能会进入无限循环而永远不会返回结果。

  

据我了解,这给出了

n + m1( n + m2 (n + m3 (...)) ) )

不一定,首先,内部调用可能不是n,因为对象大小或转换器列表可能已更改。

另外,目前你的公式是非正式的。您应该尝试将其转换为真正的重复。


回到你的问题,我得到的印象是你的对象有点像节点树,你遍历这个树以将int转换成其他东西。在这种情况下,通过查看数据结构而不是尝试重复,可能更容易找到复杂性。例如,如果我们知道初始对象的每个节点最终都被处理一次,那么(假设我们有n个节点),我们的总运行时间将是处理单个节点的成本的n倍。如果处理节点由查找转换器所需的时间占主导地位,则处理节点的复杂度为O(m),其中m是转换器的数量。另一方面,如果处理该节点的成本(在您已经转换子节点之后)大于那个,那么您将忽略查找转换器的成本并改为使用它。

假设一旦你处理了子节点就占用一个节点很便宜(比如恒定时间),那么我们的总时间复杂度是O(n * m),其中n是节点数,m是转换器数。现在我们只需要将其转换为N.如果n和m都是O(n)(taht,对象和转换器列表都是我们想要的那么大)那么复杂度将是O(N ^ 2) )。如果对象是我们想要的那么大(n是O(N))但是转换器列表具有有限的大小(m是O(1))则n * m是O(N)。等等。