We consider the running time of an algorithm as a function of the length of the string representing its input

Definition: Let be a deterministic Turing machine that halts on all inputs. The time complexity of is the function , where is the maximum number of steps that uses on any input of length

We say runs in time and that is an time Turing machine

Coming up with precise expressions for time complexity is burdensome and generally unnecessary

Definition: We say that , if for every , for some , in which case is an asymptotic upper bound for

Bounds of the form are called polynomial bounds and bounds of the form are called exponential bounds

Definition: We say that if

The difference between big- and small- is analogous to the difference between and

How much time does a single-tape Turing machine need to decide ?

To measure this more clearly, we give low-level descriptions

“On input string :

  1. Scan across the tape and reject if a is found to the right of a
  2. Repeat if both s and s remain on the tape:
  3. Scan across the tape, crossing off a single and a single
  4. If neither s nor s remain on the tape, accept otherwise reject

We consider these stages separately and come to

Definition: The time complexity class is the collection of all languages that are decidable by an time Turing machine

So we know at least , but can we do better?

“On input string :

  1. Scan across the tape and reject if a is found to the right of a
  2. Repeat if both s and s remain on the tape:
  3. Scan across the tape and reject if the total remaining s and s is odd
  4. Scan across the tape, crossing off every other starting with the first and then every other starting with the first
  5. If neither s nor s remain on the tape, accept otherwise reject

We see that the complexity of is

In fact, any language that can be decided in time on a single-tape Turing machine is regular (see Kobayashi)

With a second tape, we can solve this in linear time, by treating the second tape as a stack

Even though these models of computation are equivalent in computability theory, they still affect the complexity of languages

Theorem: Every time multitape Turing machine has an equivalent time single-tape Turing machine

This is because of how we can simulate a multitape machine with one tape; we store the tapes consecutively and scan across the entire tape (which can require up to a multiple of space) to decide our next move

Definition: The running time of a nondeterministic Turing machine is the function where is the maximum number of steps that uses on any branch of its computation on any input of length

Theorem: Every time nondeterministic single-tape Turing machine has an equivalent time deterministic single-tape Turing machine

Without going into too much depth, this is an intuitive result that reflects how we can simulate a search through the machine’s decision tree

The Class P

Exponential time algorithms are effectively unusable, and typically arise from brute-force searching the space of solutions

Because of this, we declare that all reasonable deterministic computational models are polynomially equivalent, where reasonable vaguely refers to models approximating running times on actual computers

Note that we’ve already shown a polynomial equivalence between single and multi-tape Turing machines

This discussion focuses on aspects of complexity that are unaffected by polynomial differences, which allows us to discuss some important fundamental properties of algorithms

In practice, the difference between and is very important, but complexity theory also takes a much broader look at runtime complexity

Definition: is the class of languages that are decidable in polynomial time on a single-tape Turing machine,

is invariant for all reasonable models of computation and corresponds roughly to the class of problems that are realistically solvable on a computer

This threshold has proven to be very useful, and polynomial time algorithms can almost always be reduced in order to a point of practical utility

To actually describe algorithms, we give high-level descriptions without reference to particular computational models, in order to avoid tedious details of tapes and head motions

We still use to refer to a reasonable encoding methods of an object, where all reasonable methods for an object are polynomially equivalent

To encode graphs, we often use an adjacency matrix

Theorem: is in

We can use a breadth-first search to decide

Theorem: is in

We cannot simply search through every possible divisor, since the length of an encoding for is exponential in , but we can use the well-known Euclidean algorithm for calculating the greatest common divisor of and , and conclude that they are relatively prime if

Theorem: Every context-free language is a member of

We use a dynamic programming approach, where each subproblem tracks the symbols that can generate the through th range of the input string

We break down a subproblem of length into smaller parts by considering each possible split, so this takes

The Class NP

Many problems have not yielded polynomial time problems, and essentially can only be solved with brute-force

Let’s start with an example

A Hamiltonian path in a directed graph is a directed path through a graph that goes through each node exactly once

We can easily make an exponential time algorithm for , but no one knows if a polynomial time solution exists

However, has polynomial verifiability, meaning we can verify whether a potential solution is valid in polynomial time

Definition: A verifier for a language is an algorithm , where

A polynomial time verifier runs in polynomial time in the length of , and a language is polynomially verifiable if it has a polynomial time verifier

acts as additional information, essentially a certificate or proof that belongs to

In the case of , would look like an actual Hamiltonian path from to

Definition: is the class of languages that have polynomial time verifiers

comes from nondeterministic polynomial time, an alternative characterization of the class

Theorem: A language is in it is decided by some nondeterministic polynomial time Turing machine

For the forward definition of this theorem, means has a polynomial time verifier , which runs in , so we can nondeterministically select the string and run it on

For the other direction, we treat as a description of the nondeterministic choice to be made at each step

Definition: is the set of languages decided by some time nondeterministic Turing machine

The class is insensitive to the choice of reasonable nondeterministic computational model

contains the languages that are complements of languages in , or problems where you must verify something is not present

It is unknown whether is different than

Even more than this, we are unable to prove the existence of a single language in that is not in , even though it seems almost obvious

The question of whether is one of the greatest unsolved problems in theoretical computer science and modern mathematics

Most researchers believe they are not equal, since solving the problem would have enormous implications, however proving otherwise is still beyond reach

We can prove , but this is not enough (and pretty intuitive already)