4.
Tractable and Intractable Problems
1. Tractable and Intractable Problems
In computational complexity, problems are classified based on how efficiently they can be solved.
The efficiency of an algorithm is usually measured in terms of time complexity, which indicates how
the running time grows with the size of the input.
Polynomial Time
Polynomial time refers to the time required by a computer to solve a problem where the running
time is expressed as a polynomial function of the input size n. An algorithm is said to run in
polynomial time if its worst-case time complexity is of the form O(nᵏ), where k is a constant.
Tractable Problems
A tractable problem is one that can be solved by a polynomial-time algorithm. Such problems are
considered efficient and practically solvable. The upper bound on the running time of these
problems is polynomial.
Examples of tractable problems:
Searching an unordered list
Searching an ordered list
Multiplication of integers
Finding a Minimum Spanning Tree (MST) in a graph
Intractable Problems
An intractable problem is one that cannot be solved using a polynomial-time algorithm. The lower
bound on the running time of such problems is generally exponential. These problems become
impractical to solve as the input size grows.
Examples of intractable problems:
Listing all permutations of n numbers
Tower of Hanoi problem (worst-case running time is at least 2n−1 )
What Constitutes Reasonable Time?
The standard definition of reasonable or efficient computation is polynomial time.
For an input of size n, an algorithm is considered efficient if its worst-case running time is O(nᵏ) for
some constant k.
Polynomial time examples:
O(1)
O(n)
O(n log n)
O(n²)
O(n³)
Not polynomial time (inefficient):
O(2ⁿ)
O(nⁿ)
O(n!)
4.1. Computability of Algorithms
In computer science, problems are grouped into complexity classes based on their computational
difficulty. A complexity class is a set of problems that share similar resource requirements.
Using complexity theory, we study:
Problems that cannot be solved by computers
Problems that can be efficiently solved (polynomial time)
Problems for which no efficient solution exists (only exponential-time algorithms)
The two primary computational resources are time and space.
Time complexity measures the number of steps required to solve or verify a problem.
Space complexity measures the amount of memory required by the algorithm.
An algorithm with time complexity O(nᵏ) is considered a polynomial-time algorithm and scales well.
Algorithms with time complexity O(kⁿ) are exponential and scale poorly.
4.2. Complexity Classes
Complexity classes help organize problems with similar computational behavior. The major classes
discussed are P, NP, Co-NP, NP-Hard, and NP-Complete.
P Class
The P class consists of decision problems that can be solved by a deterministic machine in polynomial
time.
Features of P Class
Solutions are easy to find.
Problems are solvable both in theory and in practice.
These problems are considered tractable.
Most basic algorithmic problems belong to this class.
Example: Greatest Common Divisor (GCD)
Given two positive integers a and b, the GCD is the largest number that divides both.
Example:
Input: a = 20, b = 28
Output: 4
Java Program:
class GFG {
static int gcd(int a, int b) {
int result = [Link](a, b);
while (result > 0) {
if (a % result == 0 && b % result == 0)
break;
result--;
return result;
public static void main(String[] args) {
int a = 20, b = 28;
[Link](gcd(a, b));
NP Class
The NP (Nondeterministic Polynomial Time) class consists of decision problems whose solutions are
hard to find but easy to verify in polynomial time using a deterministic machine.
Features of NP Class
Solutions may be difficult to compute.
Given a solution, verification is fast.
All P problems are included in NP.
Example Explanation
Consider a company with 1000 employees and 200 rooms. Certain employees cannot share a room.
Finding a valid assignment is difficult, but verifying a given assignment is easy. Hence, this problem
belongs to NP.
Boolean Satisfiability Problem (SAT)
SAT asks whether a Boolean formula can be made true by assigning appropriate truth values to
variables.
Satisfiable: There exists an assignment that makes the formula true.
Unsatisfiable: No such assignment exists.
Example:
F= A ∧¬ B → satisfiable
G= A ∧ ¬ A → unsatisfiable
SAT is a classic NP problem.
Co-NP Class
Co-NP is the complement of NP.
If a problem is in NP, then its complement belongs to Co-NP.
Features
“No” answers can be verified in polynomial time.
Only one answer (yes or no) needs to be verified efficiently.
Example:
Checking whether a number is not prime
NP-Hard Class
An NP-Hard problem is at least as hard as the hardest problems in NP.
Features
Not all NP-Hard problems belong to NP.
Verification itself may be difficult.
Every NP problem can be reduced to an NP-Hard problem in polynomial time.
Examples:
Halting Problem
Quantified Boolean Formula
No Hamiltonian Cycle
NP-Complete Class
A problem is NP-Complete if it is both NP and NP-Hard.
Features
Every NP problem can be reduced to an NP-Complete problem.
Solving one NP-Complete problem efficiently implies P = NP.
Examples:
Hamiltonian Cycle
SAT
Vertex Cover
Summary of Complexity Classes
Complexity Class Characteristic Feature
P Easily solvable in polynomial time
NP Yes answers verifiable in polynomial time
Co-NP No answers verifiable in polynomial time
NP-Hard At least as hard as NP problems
NP-Complete Both NP and NP-Hard
4.3 NP and NP-Complete
Introduction
In computational complexity theory, problems are classified based on the amount of computational
resources required to solve them. Among the most important complexity classes are NP and NP-
Complete. These classes help in understanding whether a problem can be solved efficiently or
whether only its solution can be verified efficiently.
NP (Nondeterministic Polynomial Time)
The class NP consists of decision problems whose solutions can be verified in polynomial time by a
deterministic machine. Even if finding the solution is difficult, once a solution is provided, its
correctness can be checked efficiently. The term nondeterministic refers to a theoretical model of
computation in which multiple possible choices can be explored simultaneously.
In practical terms, NP problems are those for which a solution can be guessed and then verified in
polynomial time. This verification process makes NP an important class in complexity theory.
Characteristics of NP
Problems in NP are decision problems with yes or no answers. A proposed solution, called a
certificate, can be verified in polynomial time. All problems that belong to class P are also members
of NP. However, it is not known whether every NP problem can be solved in polynomial time.
Examples of NP Problems
The Boolean Satisfiability Problem is a classic NP problem in which the goal is to determine whether
a Boolean formula can be made true by assigning suitable truth values to variables. The Hamiltonian
Cycle problem asks whether a graph contains a cycle that visits each vertex exactly once. The Subset
Sum problem involves determining whether a subset of given numbers adds up to a specific value. In
all these cases, verifying a proposed solution is efficient.
Relationship Between P and NP
Every problem in class P is also in NP because if a problem can be solved in polynomial time, its
solution can obviously be verified in polynomial time. However, whether P is equal to NP remains
one of the biggest unsolved problems in computer science.
NP-Complete
A problem is said to be NP-Complete if it satisfies two conditions. First, the problem must belong to
NP, meaning its solution can be verified in polynomial time. Second, the problem must be NP-Hard,
meaning every problem in NP can be reduced to it in polynomial time. NP-Complete problems are
considered the hardest problems in NP.
Significance of NP-Complete Problems
NP-Complete problems are important because if any one of them is solved in polynomial time, then
all problems in NP can be solved in polynomial time. This would imply that P equals NP. Due to their
complexity, NP-Complete problems are often approached using approximation algorithms and
heuristics in practical applications.
Examples of NP-Complete Problems
Some well-known NP-Complete problems include the Boolean Satisfiability Problem, 3-SAT, Vertex
Cover, Clique problem, Hamiltonian Cycle problem, and the decision version of the Traveling
Salesman Problem.
Polynomial-Time Reduction
Polynomial-time reduction is a technique used to compare the complexity of problems. If a problem
A can be transformed into problem B in polynomial time, then B is at least as hard as A. This
technique is used extensively to prove that a problem is NP-Complete.
Importance of NP and NP-Complete Classes
The study of NP and NP-Complete problems helps computer scientists understand the limitations of
efficient computation. These classes play a crucial role in algorithm design, cryptography, artificial
intelligence, scheduling, and optimization problems.
[Link]-Hard Problems
Introduction to NP-Hard
In computational complexity theory, NP-Hard problems represent a class of problems that are
extremely difficult to solve efficiently. A problem is classified as NP-Hard if it is at least as hard as the
hardest problems in NP (Nondeterministic Polynomial time). This means that every problem in NP
can be reduced to an NP-Hard problem using a polynomial-time reduction.
NP-Hard problems define the upper boundary of computational difficulty. They help in identifying
problems for which no efficient (polynomial-time) algorithm is currently known and are widely used
to study the limits of algorithmic problem-solving.
Definition of NP-Hard
A problem X is said to be NP-Hard if for every problem Y in NP, Y ≤p X, where ≤p denotes polynomial-
time reducibility.
Key points of the definition:
NP-Hard problems may or may not belong to NP.
They are not required to be decision problems.
Solution verification may not be possible in polynomial time.
Characteristics of NP-Hard Problems
NP-Hard problems exhibit the following characteristics:
No known polynomial-time algorithm exists.
The computational time grows exponentially with input size.
They include optimization, decision, and search problems.
Exact solutions are impractical for large inputs.
Approximation or heuristic solutions are often used.
Types of NP-Hard Problems
NP-Hard problems can be broadly classified into the following types:
Optimization NP-Hard Problems
These problems aim to find the best possible solution among many feasible solutions.
Examples:
Travelling Salesman Problem (Optimization)
Knapsack Problem (Optimization)
Vehicle Routing Problem
Search NP-Hard Problems
These problems require finding a valid solution without necessarily optimizing it.
Example:
Finding a Hamiltonian path in a graph
Decision-related NP-Hard Problems
Some decision problems are NP-Hard when they are harder than NP-Complete problems or are
extensions of them.
Example:
Scheduling problems with constraints
Polynomial-Time Reduction
Polynomial-time reduction is the primary technique used to prove NP-Hardness. If a known NP-
Complete problem can be transformed into another problem in polynomial time, then the target
problem is NP-Hard.
Steps involved:
1. Choose a known NP-Complete problem.
2. Convert its input to the input of the new problem.
3. Show that the conversion takes polynomial time.
4. Prove that solving the new problem solves the original problem.
Example NP-Hard Problems
Travelling Salesman Problem (Optimization)
The Travelling Salesman Problem asks for the shortest route that visits each city exactly once and
returns to the starting city. The optimization version is NP-Hard because it is harder than its decision
version, which is NP-Complete.
Knapsack Problem (Optimization)
The objective is to maximize the total value of selected items without exceeding the given weight
capacity. The optimization version of this problem is NP-Hard.
Code Example: NP-Hard Problem
0/1 Knapsack Problem (Optimization Version)
The following Python program demonstrates solving the NP-Hard Knapsack problem using dynamic
programming. Although this approach works efficiently for small inputs, the general problem remains
NP-Hard.
def knapsack(capacity, weights, values, n):
dp = [[0 for _ in range(capacity + 1)] for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(capacity + 1):
if weights[i - 1] <= w:
dp[i][w] = max(
values[i - 1] + dp[i - 1][w - weights[i - 1]],
dp[i - 1][w]
else:
dp[i][w] = dp[i - 1][w]
return dp[n][capacity]
# Example execution
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 5
n = len(values)
print("Maximum value:", knapsack(capacity, weights, values, n))
Applications of NP-Hard Problems
NP-Hard problems are widely encountered in real-world scenarios such as:
Task and job scheduling
Network design
Cryptography
Artificial intelligence
Resource allocation and logistics
Due to their complexity, approximate or heuristic algorithms are commonly used instead of exact
algorithms.
Importance of NP-Hard Problems
Understanding NP-Hard problems helps computer scientists identify problems that are unlikely to
have efficient exact solutions. They guide researchers toward approximation methods and help
establish the theoretical boundaries of algorithmic computation.
If any NP-Hard problem were solved in polynomial time, it would imply P = NP, which remains one of
the most important unsolved problems in computer science.
[Link]’s Theorem
Introduction
Cook’s Theorem is a foundational result in computational complexity theory. It was proposed by
Stephen Cook in 1971 and is also known as the Cook–Levin Theorem. This theorem was the first to
formally identify an NP-Complete problem, thereby laying the foundation for the theory of NP-
Completeness.
Cook’s Theorem establishes a deep connection between problems in the class NP and the Boolean
Satisfiability Problem (SAT). It shows that SAT is at least as hard as any problem in NP, making it the
first known NP-Complete problem.
Statement of Cook’s Theorem
Cook’s Theorem states that:
The Boolean Satisfiability Problem (SAT) is NP-Complete.
This means:
1. SAT belongs to NP.
2. Every problem in NP can be reduced to SAT in polynomial time.
As a result, SAT is one of the hardest problems in NP.
Boolean Satisfiability Problem (SAT)
The Boolean Satisfiability Problem asks whether there exists an assignment of truth values (true or
false) to variables such that a given Boolean formula evaluates to true.
Example Boolean formula:
¿
If there exists at least one assignment of variables that makes the formula true, the formula is said to
be satisfiable.
SAT is a decision problem, which makes it suitable for classification under NP and NP-Complete
problems.
Why SAT is in NP
SAT belongs to NP because:
A solution (truth assignment) can be guessed.
The correctness of the solution can be verified in polynomial time by evaluating the Boolean
formula.
Thus, SAT satisfies the definition of NP.
Polynomial-Time Reduction
The core idea behind Cook’s Theorem is polynomial-time reduction. The theorem proves that any
problem in NP can be reduced to SAT in polynomial time.
This is done by:
Representing the computation of a nondeterministic Turing machine as a Boolean formula.
Ensuring that the Boolean formula is satisfiable if and only if the Turing machine accepts the
input.
This construction shows that SAT captures the difficulty of all NP problems.
Importance of Cook’s Theorem
Cook’s Theorem is important because:
It introduced the concept of NP-Completeness.
It provided a method to prove other problems NP-Complete using reductions from SAT.
It helped classify hundreds of real-world problems as NP-Complete.
Without Cook’s Theorem, the systematic study of computational hardness would not be possible.
Consequences of Cook’s Theorem
Once SAT was proven NP-Complete:
Other problems such as 3-SAT, Clique, Vertex Cover, and Hamiltonian Cycle were also proven
NP-Complete through reductions.
Researchers began focusing on approximation algorithms and heuristics.
The P vs NP problem gained importance.
If SAT is solved in polynomial time, then P = NP.
Example Problem (SAT)
Consider the Boolean formula:
¿
Truth assignment:
x = false
y = true
z = true
This assignment satisfies all clauses; hence, the formula is satisfiable.
Code Example: SAT Solver (Brute Force)
The following Python program checks whether a Boolean formula is satisfiable by trying all possible
truth assignments. This demonstrates the concept behind SAT.
from itertools import product
def is_satisfiable():
# Variables: x, y, z
for x, y, z in product([False, True], repeat=3):
if (x or y) and ((not x) or z) and ((not y) or z):
print("Satisfiable with:")
print("x =", x, "y =", y, "z =", z)
return
print("Not satisfiable")
is_satisfiable()
Applications of Cook’s Theorem
Cook’s Theorem is widely applied in:
Compiler optimization
Hardware verification
Artificial intelligence
Cryptography
Automated theorem proving
It helps identify problems that are unlikely to have efficient exact solutions.
Limitations
Cook’s Theorem does not prove whether P = NP.
It does not provide an efficient algorithm for SAT.
The reduction process is theoretical and complex
[Link] NP (Class NP)
Introduction to NP
In computational complexity theory, NP stands for Nondeterministic Polynomial Time. It is one of the
most important complexity classes used to classify decision problems based on how efficiently their
solutions can be verified. The class NP contains problems for which a proposed solution can be
checked for correctness in polynomial time using a deterministic algorithm.
The term “nondeterministic” comes from the theoretical model of computation called the
nondeterministic Turing machine, which can explore multiple computation paths simultaneously. If at
least one of these paths leads to an accepting state in polynomial time, the problem is said to belong
to NP.
Definition of Standard NP
A decision problem belongs to the class NP if:
A solution (certificate) exists for every “yes” instance, and
The correctness of that solution can be verified in polynomial time by a deterministic Turing
machine.
Thus, NP focuses on verification efficiency, not necessarily on the efficiency of finding the solution.
Deterministic vs Nondeterministic Computation
In deterministic computation, an algorithm follows a single sequence of steps for a given input. In
nondeterministic computation, the machine can choose among multiple possible moves at each
step. If any sequence of choices leads to acceptance within polynomial time, the input is accepted.
Although nondeterministic machines are theoretical, NP problems are practically interpreted as
problems whose solutions can be verified quickly once given.
Characteristics of NP Problems
Standard NP problems have the following properties:
They are decision problems (answer is yes or no).
A valid solution can be verified in polynomial time.
Finding the solution may take exponential time.
NP includes all problems in class P.
Many NP problems are candidates for NP-Complete classification.
Relationship Between P and NP
The class P consists of problems that can be both solved and verified in polynomial time. Since any
problem that can be solved quickly can also be verified quickly, P is a subset of NP.
P ⊆ NP
Whether P equals NP is one of the biggest open problems in computer science.
Standard Examples of NP Problems
Boolean Satisfiability Problem (SAT)
Given a Boolean formula, determine whether there exists an assignment of truth values that makes
the formula true. SAT belongs to NP because a truth assignment can be verified in polynomial time.
Hamiltonian Cycle Problem
Given a graph, determine whether there exists a cycle that visits every vertex exactly once. A
proposed cycle can be checked efficiently, so the problem belongs to NP.
Vertex Cover Problem
Given a graph and an integer k, determine whether there exists a set of k vertices that covers all
edges. Verification is polynomial.
Clique Problem
Given a graph and an integer k, determine whether the graph contains a clique of size k. Checking a
given clique is polynomial-time.
Certificate and Verifier Concept
For NP problems, a certificate is a proposed solution, and a verifier is a polynomial-time algorithm
that checks the certificate.
Example:
Problem: Hamiltonian Cycle
Certificate: A sequence of vertices
Verifier: Checks if the sequence forms a valid cycle visiting all vertices exactly once
Example Problem Explanation
Consider the Subset Sum Problem:
Given a set of integers and a target sum, determine whether there exists a subset whose sum equals
the target.
If a subset is provided, verifying that the sum matches the target takes polynomial time. Therefore,
Subset Sum belongs to NP.
Code Example: NP Problem Verification
Subset Sum – Verification Approach
# Verifying a solution for Subset Sum (NP problem)
def verify_subset_sum(subset, target):
return sum(subset) == target
# Example
subset = [3, 4, 5]
target = 12
if verify_subset_sum(subset, target):
print("Valid solution: Subset sum equals target")
else:
print("Invalid solution")
Importance of Standard NP
The class NP is important because it defines the boundary between problems that are easy to verify
and those that may be computationally difficult to solve. Many real-world problems in scheduling,
optimization, cryptography, and artificial intelligence naturally fall into NP.
Understanding NP helps in identifying problems that may not have efficient algorithms and motivates
the study of approximation and heuristic methods.
[Link] Problems and Reduction Techniques
Introduction
In computational complexity theory, not all problems are equally difficult. Some problems are so
hard that if one of them can be solved efficiently, then many other problems can also be solved
efficiently. Such problems are called complete problems. Reduction techniques are used to formally
prove that a problem belongs to a particular complexity class, especially NP-Complete.
The study of complete problems and reductions helps identify the hardest problems in a complexity
class and understand the limits of efficient computation.
Complete Problems
A problem is said to be complete for a complexity class if it satisfies two conditions:
1. The problem belongs to the given complexity class.
2. Every other problem in that class can be reduced to it in polynomial time.
Complete problems represent the hardest problems within a complexity class.
NP-Complete Problems
A problem is NP-Complete if:
It belongs to NP, and
Every problem in NP can be reduced to it in polynomial time.
NP-Complete problems are the most important type of complete problems studied in computer
science.
Examples of NP-Complete problems:
Boolean Satisfiability Problem (SAT)
3-SAT
Vertex Cover
Clique
Hamiltonian Cycle
Subset Sum
If any NP-Complete problem is solved in polynomial time, then P = NP.
First NP-Complete Problem
The Boolean Satisfiability Problem (SAT) was the first problem proven to be NP-Complete using
Cook’s Theorem. Once SAT was established as NP-Complete, many other problems were proven NP-
Complete using reductions from SAT.
Reduction Techniques
A reduction is a way of converting one problem into another such that a solution to the second
problem gives a solution to the first problem.
Polynomial-Time Reduction
A problem A is said to be polynomial-time reducible to problem B if:
Any instance of A can be transformed into an instance of B in polynomial time.
A solution to B can be used to solve A.
Notation:
A ≤p B
This means B is at least as hard as A.
Purpose of Reduction Techniques
Reduction techniques are used to:
Prove NP-Hardness
Prove NP-Completeness
Compare the difficulty of problems
Avoid designing new algorithms for already hard problems
Steps to Prove NP-Completeness Using Reduction
To prove that a problem X is NP-Complete:
1. Show that X belongs to NP.
2. Choose a known NP-Complete problem Y.
3. Reduce Y to X in polynomial time.
4. Conclude that X is NP-Complete.
Example Reduction: SAT to 3-SAT
In this reduction:
SAT is reduced to 3-SAT.
Any Boolean formula is converted into an equivalent formula where each clause has exactly
three literals.
The transformation is done in polynomial time.
The new formula is satisfiable if and only if the original formula is satisfiable.
This proves that 3-SAT is NP-Complete.
Example Reduction: Vertex Cover
The Vertex Cover problem asks whether a graph contains a set of k vertices such that every edge is
incident to at least one selected vertex.
To prove Vertex Cover is NP-Complete:
Show that it belongs to NP.
Reduce a known NP-Complete problem (such as Clique) to Vertex Cover.
The reduction ensures that solving Vertex Cover solves Clique.
Types of Reductions
Many-One Reduction
One problem is reduced to another using a single transformation.
Turing Reduction
A problem is solved using an oracle that solves another problem.
Polynomial-time many-one reductions are most commonly used in NP-Completeness proofs.
Code Example: Reduction Idea (Subset Sum Verification)
The following code demonstrates the verification concept used in NP and NP-Complete problems.
# Verifier for Subset Sum problem (NP-Complete)
def verify_subset_sum(numbers, subset, target):
total = 0
for i in range(len(numbers)):
if subset[i] == 1:
total += numbers[i]
return total == target
# Example
numbers = [3, 7, 10, 12]
subset = [1, 0, 1, 0] # selecting 3 and 10
target = 13
if verify_subset_sum(numbers, subset, target):
print("Valid subset sum solution")
else:
print("Invalid solution")
This code reflects the idea that solutions can be verified in polynomial time, even if finding them is
difficult.
Importance of Complete Problems
Complete problems:
Represent the hardest problems in a class
Help classify new problems
Guide algorithm designers toward approximation and heuristics
Form the basis of complexity theory research
Applications
Complete problems and reduction techniques are applied in:
Scheduling and planning
Cryptography
Network design
Artificial intelligence
Compiler optimization