Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 70

Understanding Complexity Class P

Recommended resources

Hello! Welcome to your next lesson on Computational Complexity.

In our last session, we established a formal method for analyzing the efficiency of algorithms by defining the time complexity of a Turing Machine, , and using Big-O notation to describe its growth. We moved from asking "can this problem be solved?" to "how long does it take to solve it?".

Today, we will use that foundation to build one of the most important concepts in all of computer science: the complexity class P. This lesson will formally define the boundary between what we consider "computationally tractable" (efficiently solvable) and "intractable" problems. Understanding this class is the first major step in mapping the landscape of computational complexity and is essential for tackling the famous P vs. NP problem later on.

1. The Line Between "Fast" and "Slow"

Your practical experience in software and AI development has likely given you an intuition for which algorithms are fast and which are slow. An algorithm that scales linearly with input size feels very different from one that requires checking every possible combination of inputs. Complexity theory formalizes this intuition by drawing a line between polynomial-time algorithms and exponential-time algorithms.

  • Polynomial time: The running time is bounded by for some constant . Examples include , , , and .
  • Exponential time: The running time grows as for some constant . Examples include and .

The difference in growth is not just academic; it has profound practical consequences.

Chapter 10. The Complexity Classes P and NP

To see just how dramatic this difference is, let's read an excerpt from these lecture notes by Prof. Stewart Weiss. It provides a vivid illustration of why exponential-time algorithms are considered 'intractable'.

Please read from the beginning of the introduction on page 2, down to the end of the paragraph that begins 'Is this bad?'. This section discusses the practical impact of an exponential running time (specifically, 2^n) and introduces the concept of an intractable problem.

As the reading highlights, even a massive increase in computing power barely makes a dent in the size of problems we can solve with an exponential-time algorithm. In contrast, polynomial-time algorithms scale much more gracefully. This distinction is the primary motivation for defining our first major complexity class.


2. Formal Definition of the Class P

We can now formalize this notion of "efficiently solvable" using the language of Turing Machines and time complexity.

First, let's be precise about what a polynomial-time algorithm is in this context.

Definition: Polynomial-Time Turing Machine
A deterministic Turing Machine is said to run in polynomial time if there exists a constant such that its time complexity is in .

With this, we can define the complexity class P.

Lecture 61/65: Time Complexity Classes P And NP

This short video clip provides a concise formal definition of the complexity class P.

Watch the first 1 minute and 13 seconds of this video. It presents the definition and the formal notation for the class P.

As the video explained, the class P is the set of all languages that can be decided by a deterministic Turing Machine in polynomial time. Remember that for this module, we focus on decision problems—problems with a "yes" or "no" answer.

Definition: The Complexity Class P
The complexity class P is the set of all languages for which there exists a deterministic Turing Machine that decides in polynomial time.

Formally, we can express this as the union of all polynomial time-complexity classes:

Here, represents the set of all languages decidable by a deterministic TM in time.

Polynomial Time Complexity Classes
This diagram illustrates that P is the set of all problems solvable in polynomial time. A problem solvable in \(O(n)\) is also in \(O(n^2)\), and so on. P encompasses all such classes.
Test your understanding!

In the last lesson, we analyzed a Turing Machine for the palindrome language that ran in time. Does the language of palindromes belong to the class P? Why or why not?

Show answer

Yes, the language of palindromes is in P. The definition of P requires that there exists some deterministic TM that decides the language in polynomial time. Since we found an algorithm that runs in , and is a polynomial, the language is in P. (In fact, a more optimized algorithm using a two-tape TM can do it in time, which is also polynomial.)


3. The Significance of P: Robustness and Closure

You might wonder why we use Turing Machines, which are quite abstract, and why polynomial time is the "right" boundary for tractability.

  1. Robustness Across Models: A key insight in complexity theory is that most "reasonable" deterministic models of computation are polynomially equivalent. This means that a problem solvable in polynomial time on a Turing Machine is also solvable in polynomial time on a random-access machine (RAM), which more closely models a real computer, and vice-versa. This principle, sometimes called the Cobham-Edmonds thesis, gives us confidence that the class P is a fundamental property of problems, not just an artifact of the TM model. Your experience building complex systems in Python is based on a RAM model, and it's this equivalence that allows us to apply these theoretical results to practical computing.

  2. Closure Under Composition: Polynomials have a nice closure property: if you substitute a polynomial into another polynomial, the result is still a polynomial. In programming terms, this means if you have a polynomial-time algorithm that makes calls to a polynomial-time subroutine, the overall algorithm remains polynomial-time. This aligns with how we build complex software from smaller, efficient modules.


4. Examples of Problems in P

To make the class P more concrete, let's look at a couple of important problems that belong to it.

The PATH Problem

One of the most fundamental graph problems is determining reachability.

Problem: PATH
Input: A directed graph and two vertices .
Question: Is there a directed path from to in ?

This problem is clearly in P. Algorithms like Breadth-First Search (BFS) and Depth-First Search (DFS), which you've likely encountered in your studies, solve this efficiently. A BFS starting from will find if and only if a path exists. The running time of BFS is , which is a polynomial function of the size of the graph encoding.

Lecture 61/65: Time Complexity Classes P And NP

Let's watch a demonstration of a polynomial-time algorithm for the PATH problem, which proves its membership in P.

Watch the segment from 01:13 to 04:18. It describes the PATH problem and sketches a marking algorithm (similar to BFS/DFS) that solves it in polynomial time.

All Context-Free Languages

In our earlier modules, we spent a lot of time on Context-Free Languages (CFLs). It turns out that the decision problem for any CFL—that is, "given a string and a CFG , is ?"—is in P.

This is a powerful result, as it covers a vast and useful class of languages, including the syntax of most programming languages. The video you just watched also touches on this.

Lecture 61/65: Time Complexity Classes P And NP

Let's continue with the same video to see why all CFLs are in P.

Watch the segment from 04:18 to 05:50. It explains that since parsing algorithms for CFLs exist that run in polynomial time (specifically, O(n^3)), all CFLs are in the class P. The mention of dynamic programming might remind you of similar techniques used in your own projects.

The algorithm mentioned, which runs in , is a variant of the CYK algorithm (Cocke-Younger-Kasami), which we will study in more detail later in the course. For now, the key takeaway is that deciding membership in any CFL is a tractable problem.


Conclusion

In this lesson, we transitioned from measuring time to classifying problems based on it. We established a formal definition for the class of problems considered "efficiently solvable."

Key Takeaways:

  • A problem is considered tractable if there is a deterministic algorithm that solves it in polynomial time, i.e., with a time complexity of for some constant .
  • The complexity class P is the set of all decision problems that can be solved by a deterministic Turing Machine in polynomial time.
  • The choice of polynomial time as the threshold for tractability is robust because it is largely independent of the specific deterministic model of computation used (e.g., TM vs. a real computer).
  • Many fundamental problems, such as PATH in graphs and membership in any context-free language, belong to the class P.

Preview of the Next Lesson:
We've now defined a class for problems we know how to solve efficiently. But what about problems like the Traveling Salesperson Problem or Circuit Satisfiability from our introductory reading, for which no polynomial-time algorithm is known? These problems have a different, fascinating property: while we can't seem to find a solution quickly, we can verify a proposed solution quickly. This leads us to our next major topic: the definition of the complexity class NP.