大 O 有 2 个变量相乘

Big O with 2 variables which multiply together

如果我采用函数:

def nested_multiplier(a, b):
    """
    returns a*b
    """
    count = 0
    for i in range(a):
        for j in range(b):
            count += 1
    return count

这里很明显,就赋值次数而言,复杂度将是 a * b。

到目前为止还不错。

因此,如果我想根据 a 计算大 O,我想我必须考虑该函数具有 O(n),因为在这种情况下我必须将 b 视为常数值?

同样,如果我想要 b 的大 O,出于同样的原因,它将是 O(n)。

这似乎是有道理的,但直觉上,对于像这样的嵌套迭代块,我期望 O(n^2) 或其他一些指数类型的值。当您考虑具有相同值的 a 和 b 时,这是完全合理的(即让 a = 5 并让 b = 5 将有 25 个分配)。

那么用大 O 表示法表达这个函数的复杂性的正确方法是什么?

好吧,基本上就像你自己说的那样:

如果您的参数之一 ab 将成为 常量 那么时间复杂度将是 O(b)O(a),因为它不依赖于常数因子。

但是,如果 ab 都可以任意大,那么渐近时间复杂度(a -> infb -> inf)将为 O(a * b) .

关键是大 O 表示法描述了 渐近 复杂性,因此考虑小 a 和 [=11 的运行时可能会有点混乱=] 直观地说,当其中一个是常数时,当你让另一个值向无穷大增长时,线性运行时间再次有意义。

您可以在 O(n) 表示法中使用两个变量。例如,此 graph complexity question 同时使用顶点数和边数进行复杂性分析。在你的情况下,答案将是 O(a*b),或者如果你想要它更像 n,你可以使用 O(n*m)。

假设 b 或 a 为常量仅使用 O(n) 表示法中的一个变量对分析有误导性。始终使用影响复杂性的每个输入。

Big O 是衡量输入大小的函数。如果你测量它,例如n = |a| + |b|或者n = max(|a|,|b|)那么复杂度就是O(n^2),用单个参数来表达是最合理的。另一方面,您可以简单地将其保留为 O(a*b)。除非您打算修复其中一个值,否则说它是 O(a)O(b) 是一种误导。