[computer-science] What are the differences between NP, NP-Complete and NP-Hard?

This is a very informal answer to the question asked.

Can 3233 be written as the product of two other numbers bigger than 1? Is there any way to walk a path around all of the Seven Bridges of Königsberg without taking any bridge twice? These are examples of questions that share a common trait. It may not be obvious how to efficiently determine the answer, but if the answer is 'yes', then there's a short and quick to check proof. In the first case a non-trivial factorization of 51; in the second, a route for walking the bridges (fitting the constraints).

A decision problem is a collection of questions with yes or no answers that vary only in one parameter. Say the problem COMPOSITE={"Is n composite": n is an integer} or EULERPATH={"Does the graph G have an Euler path?": G is a finite graph}.

Now, some decision problems lend themselves to efficient, if not obvious algorithms. Euler discovered an efficient algorithm for problems like the "Seven Bridges of Königsberg" over 250 years ago.

On the other hand, for many decision problems, it's not obvious how to get the answer -- but if you know some additional piece of information, it's obvious how to go about proving you've got the answer right. COMPOSITE is like this: Trial division is the obvious algorithm, and it's slow: to factor a 10 digit number, you have to try something like 100,000 possible divisors. But if, for example, somebody told you that 61 is a divisor of 3233, simple long division is a efficient way to see that they're correct.

The complexity class NP is the class of decision problems where the 'yes' answers have short to state, quick to check proofs. Like COMPOSITE. One important point is that this definition doesn't say anything about how hard the problem is. If you have a correct, efficient way to solve a decision problem, just writing down the steps in the solution is proof enough.

Algorithms research continues, and new clever algorithms are created all the time. A problem you might not know how to solve efficiently today may turn out to have an efficient (if not obvious) solution tomorrow. In fact, it took researchers until 2002 to find an efficient solution to COMPOSITE! With all these advances, one really has to wonder: Is this bit about having short proofs just an illusion? Maybe every decision problem that lends itself to efficient proofs has an efficient solution? Nobody knows.

Perhaps the biggest contribution to this field came with the discovery a peculiar class of NP problems. By playing around with circuit models for computation, Stephen Cook found a decision problem of the NP variety that was provably as hard or harder than every other NP problem. An efficient solution for the boolean satisfiability problem could be used to create an efficient solution to any other problem in NP. Soon after, Richard Karp showed that a number of other decision problems could serve the same purpose. These problems, in a sense the "hardest" problems in NP, became known as NP-complete problems.

Of course, NP is only a class of decision problems. Many problems aren't naturally stated in this manner: "find the factors of N", "find the shortest path in the graph G that visits every vertex", "give a set of variable assignments that makes the following boolean expression true". Though one may informally talk about some such problems being "in NP", technically that doesn't make much sense -- they're not decision problems. Some of these problems might even have the same sort of power as an NP-complete problem: an efficient solution to these (non-decision) problems would lead directly to an efficient solution to any NP problem. A problem like this is called NP-hard.