So, for those of you out there that fancy yourself computer scientists, I hope you
feel some pride seeing this definition. I mean, how cool is it that our
discipline came up with such a great concept of an NP-complete problem? The
fact that there's a universal problem that simultaneously encodes all
computational problems in which you can efficiently recognize a solution.
There remains, however, a niggling issue. In general, when you're confronted with a
mathematical definition, like the definition of NP-completeness that I just
gave you, you should demand two things. The first thing you should demand is an
explanation of why you should care. That is, if the definition is met, if
satisfied, what are the interesting consequences.
I'd like to think I've given you a very satisfying answer of that question for
the definition of NP-completeness. I've argued that if a problem is
NP-complete, then that's strong evidence of computational interactability. In the
sense that polynomial-time algorithm for this NP-complete problem, if one
hypothetically existed, that would automatically solve efficiently thousands
of fundamental computational problems, anything for which you can efficiently
recognize solution. But, the second thing you should demand
from somebody who offers you a mathematical definition is examples.
Do things that I care about actually meet this definition?
And NP-completeness, I haven't shown you anything.
And indeed, when you look at this interpretation, a single problem that
simultaneously is encoding all problems with efficiently recognizable solutions.
You might well wonder, could such objects ever exist? And the reason the theory of
NP-completeness is so powerful, and over the past 40 years has been exported from
computer science to all kinds of other disciplines is that, that question also
has an incredibly satisfying answer. It turns out, tons of problems are not
merely in NP. They don't merely have officially
recognizable solution. Thousands and thousands of problems are
in fact, NP-complete as hard as any other problems in NP.
So, both the definition of NP-completeness and the facts that
amazingly there exist NP-complete problems, that's due to independently
Steve Cook and Leonid Levin. So, Cook and Levin came up with their
largely similar theories independently. Cook was at that time as he is today, at
the University of Toronto. Leonid Levin was behind the Iron Curtain,
so he was working in the Soviet Union. So, it took awhile before his results
were known in the West. These days, Levin is a professor at
Boston University. Both Cook and Levin proved not just the
basic existence result, but also gave some hints that problems that people
really care about are also going to be NP-complete.
For example, some constraint satisfaction problems like 3 snaps.
But the vast scope of NP-completeness, the sheer breadth of problems that would
eventually be proven NP-complete, was first made clear in a 1972 paper by
Richard Karp. In that paper, he showed 21 different
problems are NP-complete, including the traveling salesman problem,
and various problems that many different communities had been stuck on for
decades. And now, became clear that
NP-completeness was the fundamental obstacle preventing progress in efficient
algorithm across many, many domains. So, another thing that's amazing about
NP-completeness, and a big reason for why it's been so successfully exported from,
first of all, theoretical computer science to computer science more broadly,
and then beyond into engineering and the other sciences, is that it's quite easy
to stand on the shoulders of these giants and prove that new problems, problems
that you care about, are also NP-complete.
So, imagine that there is some computational problem pi that you really
care about. This is just crucial to the project that
you're working on, and you're stuck. You've been trying for weeks to solve it,
throwing everything in your tool box added.
You tried greedy algorithms, divide and conquer, dynamic programming,
randomization. You've thrown every data structure in the book out of hash tables,
heap search trees. Nothing works.
You can't come up with an efficient algorithm.
At that point, you should contemplate the possibility that the issue is not your
own lack of cleverness or ingenuity. The issue is not having few, too few
tools in your programmer toolbox. Perhaps, the issue is intractability of
the computational problem that you're trying to solve.
So, when you reach this point of exasperation, it's time to consider
applying the following 2-step recipe, for establishing that the problem pi is
NP-complete. Of course, the problem doesn't go, go
away just because you prove it's NP-complete, but you should approach it
using a different algorithmic strategy. And we'll discuss some of the most
popular such strategies of approaching NP-complete problems in the rest of this
course. So, let me state the 2-step recipe just
at a, at a very high level. So, the first thing you need to do is
settle on a suitable choice of an NP-complete problem, pi prime.
The second thing you need to do is you need to show that pi prime reduces to the
problem you care about pi. That shows that your problem is at least
as hard as this NP-complete problem, in the sense that the NP-complete problem
reduces to yours. And therefore, your problem, assuming
it's an NP, is NP-complete as well. So clearly, the devil is in the details
of successfully executing this 2-step recipe.
And you might well be wondering, well, how on Earth do I know which NP-complete
problem pi prime I should use? And then secondly, how am I going to come
up with this reduction from this NP-complete problem pi prime, to my own
problem pi? But, don't be intimidated by either of
these two steps. With just a little bit of practice, you
can actually get quite good at both of these steps and execute this recipe
successfully in a lot of different cases. So, one thing that should make the first
step less intimidating is there are some excellent lists of NP-complete problems.
In particular, simple ones that tend to be useful in devising your own
reductions. And the canonical such list is the book
by Garey and Johnson called Computers and Intractability.
It's from 1979, but it's still incredibly useful.
I don't think I know of another Computer Science book that's more than 30 years
old which is as useful as this one. So, there still remains the question of
how you actually come up with one of these reductions from a known NP-complete
problem pi prime to the problem you actually you care about, pi.
But, don't be intimidated by this step either.
So, first of all, as an algorithms person, you should be thinking about
reductions all the time, anyways. You should be a very natural note of
thought for you. For example, when we first started
talking about all pair of shortest paths, we quickly observed that it reduces to
the single shortest path problem. So, that mentality of, of solving one
problem using another is equally useful in the design of NP-completeness
reductions. And also, there's a lot of resources
available to gain facility with NP-completeness reductions.
You can look into various algorithms textbooks.
Generally, they have lots of examples. The Garey & Johnson book is a good one.
There are some online courses that study NP-completeness in more depth.
Those resources will give you a lot of examples of NP-completeness reductions.
It'll offer some tips on how to come up with them yourself and, most importantly,
practice will make perfect. So, I strongly encourage you to take
advantage of those resources. I think you'll be pleased to have
NP-completeness as part of your toolbox. Certainly, nobody wins if you spend weeks
or months of your life in inadvertently trying to prove that P=NP.