- A problem is said to be polynomial if there exists an algorithm that solves the problem in time T(n)=O(n
^{c}), where c is a constant. - Examples of polynomial problems:
- Sorting: O(n log n) = O(n
^{2}) - All-pairs shortest path: O(n
^{3}) - Minimum spanning tree: O(E log E)= O(E
^{2})

- Sorting: O(n log n) = O(n
- A problem is said to be exponential if no polynomial-time algorithm
can be developed for it and if we can find an algorithm that solves it in
O(n
^{u(n)}), where u(n) goes to infinity as n goes to infinity. - The world of computation can be subdivided into three classes:
- Polynomial problems (P)
- Exponential problems (E)
- Intractable (non-computable) problems (I)

- There is a very large and important class of problems that
- we know how to solve exponentially,
- we don't know how to solve polynomially, and
- we don't know if they can be solved polynomially at all

This class is a gray area between the P-class and the E-class. It will be studied in this chapter.

- Definition 1 of NP: A problem is said to be Nondeterministically Polynomial (NP) if we can find a nodeterminsitic Turing machine that can solve the problem in a polynomial number of nondeterministic moves.
- For those who are not familiar with Turing machines, two alternative
definitions of NP will be developed.
- Definition 2 of NP: A problem is said to be NP if
- its solution comes from a finite set of possibilities, and
- it takes polynomial time to verify the correctness of a candidate solution

- Remark: It is much easier and faster to "grade" a solution than to find a solution from scratch.
- We use NP to designate the class of all nondeterministically polynomial problems.
- Clearly, P is a subset of NP
- A very famous open question in Computer Science:
P = NP ? - To give the 3rd alternative definition of NP, we introduce an
imaginary, non-implementable instruction, which we call
"choose()".
- Behavior of "choose()":
- if a problem has a solution of N components, choose(i) magically returns the i-th component of the CORRECT solution in constant time
- if a problem has no solution, choose(i) returns mere "garbage", that is, it returns an uncertain value.

- An NP algorithm is an algorithm that has 2 stages:
- The first stage is a guessing stage that uses choose() to find a solution to the problem.
- The second stage checks the correctness of the solution produced by the first stage. The time of this stage is polynomial in the input size n.

- Template for an NP algorithm:

begin /* The following for-loop is the guessing stage*/ for i=1 to N do X[i] := choose(i); endfor /* Next is the verification stage */ Write code that does not use "choose" and that verifies if X[1:N] is a correct solution to the problem. end

- Remark: For the algorithm above to be polynomial, the solution size N must be polynomial in n, and the verification stage must be polynomial in n.
- Definition 3 of NP: A problem is said to be NP if there exists an
NP algorithm for it.
- Example of an NP problem: The Hamiltonian Cycle (HC) problem
- Input: A graph G
- Question: Goes G have a Hamiltonian Cycle?

- Here is an NP algorithm for the HC problem:

begin /* The following for-loop is the guessing stage*/ for i=1 to n do X[i] := choose(i); endfor /* Next is the verification stage */ for i=1 to n do for j=i+1 to n do if X[i] = X[j] then return(no); endif endfor endfor for i=1 to n-1 do if (X[i],X[i+1]) is not an edge then return(no); endif endfor if (X[n],X[1]) is not an edge then return(no); endif return(yes); end

- The solution size of HC is O(n), and the time of the verification
stage is O(n
^{2}). Therefore, HC is NP. - The K-clique problem is NP
- Input: A graph G and an integer k
- Question: Goes G have a k-clique?

- Here is an NP algorithm for the K-clique problem:

begin /* The following for-loop is the guessing stage*/ for i=1 to k do X[i] := choose(i); endfor /* Next is the verification stage */ for i=1 to k do for j=i+1 to k do if (X[i] = X[j] or (X[i],X[j]) is not an edge) then return(no); endif endfor endfor return(yes); end

- The solution size of the k-clique is O(k)=O(n), and the time of
the verification stage is O(n
^{2}). Therefore, the k-clique problem is NP.

- Definition:
A yes-no problem consists of an instance (or input I) and a yes-no
question Q.
- The yes-no version of the HC problem was described above, and so was the yes-no version of the k-clique problem.
- The following are additional examples of well-known yes-no problems.
- The subset-sum problem:
- Instance: a real array a[1:n]
- Question: Can the array be partitioned into two parts that add up to the same value?

- The satisfiability problem (SAT):
- Instance: A Boolean Expression F
- Question: Is there an assignment to the variables in F so that F evaluates to 1?

- The Treveling Salesman Problem

**The original formulation**:- Instance: A weighted graph G
- Question: Find a minimum-weight Hamiltonian Cycle in G.

**The yes-no formulation**:- Instance: A weighted graph G and a real number d
- Question: Does G have a Hamiltonian cycle of weight <= d?

- Notation: If P stands for a yes-no problem, then
- I
_{P}: denotes an instance of P - Q
_{P}: denotes the question of P - Answer(Q
_{P},I_{P}): denotes the answer to the question Q_{P}given input I_{P}

- I
- Let P and R be two yes-no problems
- Definition: A transform
(that transforms a problem P to a problem R) is
an algorithm T such that:
- The algorithm T takes polynomial time
- The input of T is I
_{P}, and the output of T is I_{R} - Answer(Q
_{P},I_{P})=Answer(Q_{R},I_{R})

- Definition: We say that problem problem P reduces to problem R if there exists a transform from P to R.

- Definition: A problem R is NP complete if
- R is NP
- Every NP problem P reduces to R

- An equivalent but casual definition: A problem R is NP-complete if R is the "most difficult" of all NP problems.
- Theorem: Let P and R be two problems. If P reduces to R and R is polynomial, then P is polynomial.
- Proof:
- Let T be the transform that transforms P to R. T is
a polynomial time algorithm that transforms
I
_{P}to I_{R}such thatAnswer(Q _{P},I_{P}) = Answer(Q_{R},I_{R}) - Let A
_{R}be the polynomial time algorithm for problem R. Clearly, A takes as input I_{R}, and returns as output Answer(Q_{R},I_{R}) - Design a new algorithm A
_{P}as follows:

Algorithm A_{P}(input: I_{P})

begin

I_{R}:= T(I_{P});

x := A_{R}(I_{R});

return x;

end - Note that this algorithm A
_{P}returns the correct answer Answer(Q_{P},I_{P}) because x = A_{R}(I_{R}) = Answer(Q_{R},I_{R}) = Answer(Q_{P},I_{P}). - Note also that the algorithm A
_{P}takes polynomial time because both T and A_{R}

Q.E.D.

- Let T be the transform that transforms P to R. T is
a polynomial time algorithm that transforms
I
- The intuition derived from the previous theorem is that if a problem P reduces to problem R, then R is at least as difficult as P.
- Theorem: A problem R is NP-complete if
- R is NP, and
- There exists an NP-complete problem R
_{0}that reduces to R

- Proof:
- Since R is NP, it remain to show that any arbitrary NP problem P reduces to R.
- Let P be an arbitrary NP problem.
- Since R
_{0}is NP-complete, it follows that P reduces to R_{0} - And since R
_{0}reduces to R, it follows that P reduces to R (by transitivity of transforms).

Q.E.D. - The previous theorem amounts to a strategy for proving new
problems to be NP complete. Specifically, to problem a new problem R to be
NP-complete, the following steps are sufficient:
- Prove R to be NP
- Find an already known NP-complete problem R
_{0}, and come up with a transform that reduces R_{0}to R.

- For this strategy to become effective, we need at least one
NP-complete problem. This is provided by Cook's
Theorem below.
- Cook's Theorem: SAT is NP-complete.

- The k-clique problem was laready shown to be NP.
- It remain to prove that an NP-complete problem reduces to k-clique
- Theorem: SAT reduces to the k-clique problem
- Proof:
- Let F be a Boolean expression.
- F can be put into a conjunctive normal form:
F=F
_{1}F_{2}...F_{r}

where every factor F_{i}is a sum of literals (a literal is a Bollean variable or its complement) - Let k=r and G=(V,E) defined as follows:

V={<x_{i},F_{j}> | x_{i}is a variable in F_{j}}

E={(<x_{i},F_{j}> , <y_{s},F_{t}>) | j !=t and x_{i}!= y_{s}'}

where y_{s}' is the complement of y_{s} - We prove first that if F is satisfiable, then there is a k-clique.
- Assume F is satisfiable
- This means that there is an assignment that makes F equal to 1
- This implies that F
_{1}=1, F_{2}=1, ... , F_{r}=1 - Therefore, in every factor F
_{i}there is (at least) one variable assigned 1. Call that variable z_{i} - As a result, <z
_{1},F_{1}>, <z_{2},F_{2}>, ... , <z_{k},F_{k}> is a k-clique in G because they are k distinct nodes, and each pair (<z_{i},F_{i}> , <z_{j},F_{j}>) forms an edge since the endpoints come from different factors and z_{i}!= z_{j}' due to the fact that they are both assigned 1. - We finally prove that if G has a k-clique, then F is satistiable
- Assume G has a k-clique <u
_{1},F_{1}>, <u_{2},F_{2}>, ... , <u_{k},F_{k}> which are pairwise adjacent - These k nodes come the k fifferent factors, one per factor, becuae no two nodes from the same factor can be adjacent
- Furthermore, no two u
_{i}and u_{j}are complements because the two nodes <u_{i},F_{i}> and <u_{j},F_{j}> are adjacent, and adjacent nodes have non-complement first-components. - As a result, we can consistently assign each u
_{i}a value 1. - This assignment makes each F
_{i}equal to 1 because u_{i}is one of the additive literals in F_{i} - Consequently, F is equal to 1.

- An illustration of the prrof will be carried out in class on

F=(x_{1}+ x_{2})(x_{1}' + x_{3})(x_{2}+ x_{3}')