6

When discussing the worst case runtime $T(n)$ of an algorithm, we attempt to bound $T(n)$ above by some simple function $g(n)$, so that $T(n) = O(g(n))$. When discussing the best case runtime $T(n)$ of an algorithm, we also attempt to bound $T(n)$ above and use $O$ notation.

Why don't we instead attempt to bound the best case runtime from below? Wouldn't it make more sense to put an upper bound on the worst case runtime and a lower bound on the best case runtime, as this will then give us upper and lower bounds on all cases?

I understand that both $O$ and $\Omega$ notations can be useful for discussing best/worst/average case runtime., and that we can put upper and lower bounds on the worst or best case runtimes, respectively. My question is about the convention in the field to list an upper bound rather than a lower bound for the best case runtime (for example, see here and here).

agcha
  • 61
  • 1
  • 4

4 Answers4

7

The symbols $O$, $\Omega$ and $\Theta$ mean at most, at least and exactly, respectively. What these bounds are about, is an entirely separate issue. They can be about best-case or worst-case performance, but you can use these symbols throughout mathematics. To describe a function, one of the things you can do is to give $O$ and $\Omega$ upper and lower bounds, independent of whether your function is related to computer science.

For example, to describe an complicated algorithm (or language) for which you don't have precise bounds yet, but for which you do have rough preliminary bounds, you can say: the best-case of this algorithm runs in $\Omega(n^2)$ and $O(n^3)$ (meaning no better than $n^2$ but no worse than $n^3$) and the worst-case runs in $\Omega(2^{\sqrt{n}})$ and $O(2^{n^{2}})$. This means: I don't know what the worst-case running time is exactly, but my analysis thus far puts it between $2^{\sqrt{n}}$ and $2^{n^{2}}$. Later, it may turn out that the worst-case running time was in fact $\Theta(2^{n})$, and then your $O(2^{n^{2}})$ upper bound, while correct, was not strict.

Lieuwe Vinkhuijzen
  • 4,457
  • 18
  • 28
5

$O$ upper bounds how quickly a function grows, while $\Omega$ lower bounds how quickly a function grows. This a completely separate issue from whether one's considering worst/average/best case runtime analysis, although this distinction causes confusion. Usually we care most about upper bounding the runtime of an algorithm, which is why you'll likely see $O$ bounds most often regardless of which notion of runtime is being considered.

Huck Bennett
  • 359
  • 1
  • 10
0

It is usually easier to get some sort of upper bound (i.e., $O(g(n))$); lower bounds (like $\Omega(g(n))$) don't say much, you want to have an idea of "how long could it take", an answer like "it definitely takes more than" isn't very useful. Useful (but often hard to get) is $\Theta(g(n))$ (upper and lower bound). Besides, some functions just can't be reduced to a simple $\Theta(g(n))$. Consider for example:

$\begin{equation*} f(n) = \begin{cases} n^3 & \text{if \(n\) is odd} \\ n & \text{if \(n\) is even} \end{cases} \end{equation*}$

We have $f(n) = \Omega(n)$ and $f(n) = O(n^3)$, and there is no $\alpha$ so that $f(n) = \Theta(n^\alpha)$. We implicitly require our $g(n)$ monotonic increasing, and that won't work here for $\Theta$.

Note that Sedgewick advocates using $\sim$ when possible:

$\begin{equation*} f(n) \sim g(n) \text{ if and only if } \lim_{n \to \infty} \frac{g(n)}{f(n)} = 1 \end{equation*}$

This gives maximal information. But is harder.

vonbrand
  • 14,204
  • 3
  • 42
  • 52
-1

Big O is used mostly because we want to make sure that the best case time complexity $T(n)$ will never exceed the upper bound time complexity $Cg(n)$. It would be meaningless to talk about big $\Omega$ notation because what we want is a upper bound on $T(n)$.

Himanshu
  • 1
  • 1