Important Questions - Theory of Computation

Comprehensive Answers to Top 10 Exam Questions

Q1. What is Mealy Machine and Moore Machine?

Answer:

Mealy Machine and Moore Machine are two types of Finite State Transducers (FST) - finite automata with outputs. They differ in how outputs are produced.

Mealy Machine:

Definition:

A Mealy Machine is a 6-tuple M = (Q, Σ, Δ, δ, λ, q₀) where:

  • Q: Finite set of states
  • Σ: Input alphabet
  • Δ: Output alphabet
  • δ: Q × Σ → Q: State transition function
  • λ: Q × Σ → Δ: Output function (depends on state AND input)
  • q₀: Initial state

Key Characteristics of Mealy Machine:

  • Output depends on current state AND current input
  • Output is associated with transitions (edges)
  • Produces output while making state transition
  • Generally requires fewer states
  • Immediate response to input (no delay)
  • Output length = Input length

Example: Mealy Machine

Design a Mealy machine that outputs 1 when it receives two consecutive 1's, otherwise outputs 0.

State Diagram:

States: q₀ (initial), q₁ (seen one 1)

Transitions (format: input/output):
q₀ --0/0--> q₀
q₀ --1/0--> q₁
q₁ --0/0--> q₀
q₁ --1/1--> q₁
                

Transition Table:

Current State Input: 0 Output Input: 1 Output
q₀ q₀ 0 q₁ 0
q₁ q₀ 0 q₁ 1

Example Run:

Input: 01101

  • Start: q₀
  • Read 0: q₀ → q₀, output 0
  • Read 1: q₀ → q₁, output 0
  • Read 1: q₁ → q₁, output 1 ✓ (two consecutive 1's)
  • Read 0: q₁ → q₀, output 0
  • Read 1: q₀ → q₁, output 0

Output: 00100

Moore Machine:

Definition:

A Moore Machine is a 6-tuple M = (Q, Σ, Δ, δ, λ, q₀) where:

  • Q: Finite set of states
  • Σ: Input alphabet
  • Δ: Output alphabet
  • δ: Q × Σ → Q: State transition function
  • λ: Q → Δ: Output function (depends only on state)
  • q₀: Initial state

Key Characteristics of Moore Machine:

  • Output depends only on current state
  • Output is associated with states (nodes)
  • Produces output when entering a state
  • May require more states than Mealy machine
  • One clock cycle delay in output
  • Easier to design and understand
  • Output length = Input length + 1 (includes initial state output)

Example: Moore Machine

Design a Moore machine that outputs 1 when it has seen two consecutive 1's, otherwise outputs 0.

State Diagram:

States: 
q₀ (initial, output 0)
q₁ (seen one 1, output 0)
q₂ (seen two 1's, output 1)

Transitions:
q₀ --0--> q₀
q₀ --1--> q₁
q₁ --0--> q₀
q₁ --1--> q₂
q₂ --0--> q₀
q₂ --1--> q₂

Outputs:
λ(q₀) = 0
λ(q₁) = 0
λ(q₂) = 1
                

Transition Table:

State Output Input: 0 Input: 1
q₀ 0 q₀ q₁
q₁ 0 q₀ q₂
q₂ 1 q₀ q₂

Example Run:

Input: 0110

  • Start: q₀, output 0
  • Read 0: q₀ → q₀, output 0
  • Read 1: q₀ → q₁, output 0
  • Read 1: q₁ → q₂, output 1 ✓ (in state that saw two 1's)
  • Read 0: q₂ → q₀, output 0

Output: 00010 (5 outputs for 4 inputs)

Detailed Comparison:

Feature Mealy Machine Moore Machine
Output depends on Current state + Current input Current state only
Output associated with Transitions (edges) States (nodes)
Output function λ: Q × Σ → Δ λ: Q → Δ
Number of states Generally fewer May need more
Response time Immediate (synchronous with input) One cycle delay
Output length Equal to input length Input length + 1
Design complexity More complex Simpler, more intuitive
State diagram Output on edges (transitions) Output in states (nodes)
Transition format input/output Only input (output in state)
Practical use When immediate response needed When delay is acceptable

Conversion Between Mealy and Moore:

Important: Mealy and Moore machines are equivalent in computational power. Any Mealy machine can be converted to an equivalent Moore machine and vice versa.

Mealy to Moore Conversion:

  1. For each state q with different outputs for different inputs, create separate states in Moore machine
  2. Each new state corresponds to a (state, output) pair from Mealy machine
  3. May increase number of states

Moore to Mealy Conversion:

  1. Output of Mealy transition = output of destination state in Moore machine
  2. Generally reduces number of states
  3. More straightforward conversion

Applications:

  • Mealy Machines: Digital circuit design, protocol converters, real-time systems
  • Moore Machines: Control systems, sequence detectors, simple state machines

Q2. Explain FSM with Transition Graph and Transition Matrix

Answer:

Finite State Machine (FSM):

A Finite State Machine is a mathematical model of computation consisting of a finite number of states, transitions between those states, and actions. It's the foundation of automata theory.

Formal Definition of FSM:

An FSM is a 5-tuple M = (Q, Σ, δ, q₀, F) where:

  • Q: Finite set of states
  • Σ: Finite input alphabet
  • δ: Q × Σ → Q: Transition function
  • q₀ ∈ Q: Initial/start state
  • F ⊆ Q: Set of final/accepting states

Components of FSM:

  1. States (Q): Represent different configurations/conditions of the system
  2. Input Alphabet (Σ): Set of symbols that the FSM can read
  3. Transitions (δ): Rules defining how to move from one state to another
  4. Start State (q₀): Where the FSM begins execution
  5. Final States (F): States where input is accepted

1. Transition Graph (State Diagram):

A Transition Graph is a visual representation of an FSM using a directed graph.

Components of Transition Graph:

  • Circles/Nodes: Represent states
  • Arrows/Edges: Represent transitions
  • Edge Labels: Input symbols causing transition
  • Incoming Arrow: Indicates start state (no source)
  • Double Circle: Indicates final/accepting state

Example 1: FSM that accepts strings ending with '01'

Transition Graph:

      0         1
  ┌───────┐  ┌──┐
  │       ↓  │  │
  →(q₀)──0──→(q₁)
      ↑       │
      │   1   │
      └───────┘

  q₁──1──→((q₂))
      ↑      │
      │  0   │
      └──────┘

States: Q = {q₀, q₁, q₂}
Start: q₀ (indicated by →)
Final: q₂ (indicated by double circle (( )))
Alphabet: Σ = {0, 1}
                

Explanation:

  • q₀: Initial state (haven't seen required pattern)
  • q₁: Just read a '0' (waiting for '1' to complete '01')
  • q₂: Accepting state (string ends with '01')

Transitions:

  • From q₀: Read 0 → go to q₁; Read 1 → stay in q₀
  • From q₁: Read 0 → stay in q₁; Read 1 → go to q₂
  • From q₂: Read 0 → go to q₁; Read 1 → go to q₀

Test Strings:

  • "01" → q₀→q₁→q₂ ✓ Accepted
  • "101" → q₀→q₀→q₁→q₂ ✓ Accepted
  • "001" → q₀→q₁→q₁→q₂ ✓ Accepted
  • "10" → q₀→q₀→q₁ ✗ Rejected (ends in q₁)
  • "11" → q₀→q₀→q₀ ✗ Rejected (ends in q₀)

2. Transition Matrix (Transition Table):

A Transition Matrix is a tabular representation showing state transitions for each input symbol.

Transition Table for Above FSM:

Current State Input: 0 Input: 1
→ q₀ q₁ q₀
q₁ q₁ *q₂
*q₂ q₁ q₀

Legend:

  • → indicates start state
  • * indicates final/accepting state
  • Each cell shows the next state for given input

Matrix Representation (Mathematical):

For formal mathematical representation, we can use matrices where rows are current states, columns are inputs:

Matrix Form:

For input '0':

M₀ = | q₁  q₁  q₁ |
     (states after reading 0 from q₀, q₁, q₂)
                

For input '1':

M₁ = | q₀  q₂  q₀ |
     (states after reading 1 from q₀, q₁, q₂)
                

Example 2: Even Number of 1's

Design FSM that accepts strings with even number of 1's.

Transition Graph:

       1         1
    ┌─────┐   ┌─────┐
    ↓     │   ↓     │
  →((q₀))     (q₁)
    │  ↑  └───┘  ↑
    │  └─────────┘
    │      0
    └──────────────┐
         0         │
                   ↓
States: {q₀ (even), q₁ (odd)}
Start: q₀
Final: {q₀}
                

Transition Table:

State Input: 0 Input: 1
→*q₀ (even 1's) q₀ q₁
q₁ (odd 1's) q₁ q₀

Working:

  • Start in q₀ (0 ones = even)
  • Every '1' toggles between even/odd
  • '0' doesn't affect count
  • Accept if end in q₀ (even count)

Examples:

  • "011" → even 1's ✓
  • "1001" → even 1's ✓
  • "0" → even 1's (zero) ✓
  • "101" → odd 1's ✗

Example 3: Divisible by 3 (in binary)

FSM that accepts binary numbers divisible by 3.

Transition Table:

State (Remainder) Input: 0 Input: 1 Meaning
→*q₀ q₀ q₁ Remainder 0 (divisible by 3)
q₁ q₂ q₀ Remainder 1
q₂ q₁ q₂ Remainder 2

Logic: When reading binary left-to-right, new value = (old_value × 2 + new_bit) mod 3

Examples:

  • "11" (3 in decimal) → q₀→q₁→q₀ ✓
  • "110" (6 in decimal) → q₀→q₁→q₀→q₀ ✓
  • "1001" (9 in decimal) → q₀→q₁→q₂→q₁→q₀ ✓

Advantages of Transition Graph:

  • Visual: Easy to understand and design
  • Intuitive: Shows flow of computation clearly
  • Quick Analysis: Can trace paths visually
  • Design Tool: Great for initial design

Advantages of Transition Matrix:

  • Compact: Concise representation
  • Implementation: Easy to code (2D array/hash table)
  • Mathematical: Can use matrix operations
  • Complete: Shows all transitions explicitly

Equivalence:

Both representations describe the same FSM - they contain identical information:

  • Graph → Table: List all transitions from diagram
  • Table → Graph: Draw states and add arrows for each table entry

Applications of FSM:

  • Compilers: Lexical analysis (tokenization)
  • Network Protocols: TCP state machine
  • Digital Circuits: Sequential circuit design
  • Game AI: Character behavior (patrol, attack, flee)
  • Text Processing: Pattern matching, regular expressions
  • Control Systems: Traffic lights, vending machines

Q3. What is Pumping Lemma and Applications of Pumping Lemma?

Answer:

Pumping Lemma for Regular Languages:

The Pumping Lemma is a fundamental property that all regular languages must satisfy. It's primarily used as a tool to prove that certain languages are NOT regular.

Statement of Pumping Lemma:

If L is a regular language, then there exists a constant n (called the pumping length) such that:

For any string w ∈ L where |w| ≥ n, the string w can be divided into three parts w = xyz satisfying ALL of these conditions:

  1. |y| > 0: The middle part y is non-empty
  2. |xy| ≤ n: The first two parts xy fit within the first n symbols
  3. ∀i ≥ 0, xyiz ∈ L: We can "pump" y any number of times (including 0) and the resulting string remains in L

Intuition Behind Pumping Lemma:

Why does this work?

  • Regular languages are accepted by DFA with finite states
  • If string is long enough (≥ n states), some state must repeat (Pigeonhole Principle)
  • The loop between repeated states can be traversed 0, 1, 2, ... times
  • This creates the "pumping" behavior

Important Points:

  • n is usually the number of states in the DFA
  • y represents the loop that can be repeated
  • Pumping Lemma is necessary but NOT sufficient - satisfying it doesn't prove regularity!
  • Used to prove languages are NOT regular (proof by contradiction)

How to Use Pumping Lemma (Proof Template):

To prove a language L is NOT regular:

  1. Assume L is regular (for contradiction)
  2. Let n be the pumping length guaranteed by Pumping Lemma
  3. Choose a string w ∈ L where |w| ≥ n (choose strategically!)
  4. Consider all possible divisions w = xyz satisfying conditions 1 and 2
  5. Show that for ANY such division, there exists an i such that xyiz ∉ L
  6. Conclude this contradicts Pumping Lemma, so L is NOT regular

Applications of Pumping Lemma:

Application 1: L = {0n1n | n ≥ 0} is NOT Regular

Language: Equal number of 0's followed by equal number of 1's

Examples: ε, 01, 0011, 000111, ...

Proof:

  1. Assume L is regular with pumping length n
  2. Choose w = 0n1n (clearly w ∈ L and |w| = 2n ≥ n)
  3. By Pumping Lemma, w = xyz where:
    • |y| > 0
    • |xy| ≤ n
  4. Analysis: Since |xy| ≤ n, both x and y consist only of 0's (they're in the first n symbols)
    • So y = 0k for some k > 0
  5. Pump with i = 2: xy2z = 0n+k1n
    • This has MORE 0's than 1's
    • Therefore xy2z ∉ L
  6. Pump with i = 0: xy0z = xz = 0n-k1n
    • This has FEWER 0's than 1's
    • Therefore xz ∉ L
  7. Contradiction! Therefore L is NOT regular ✓

Application 2: L = {ap | p is prime} is NOT Regular

Language: Strings of a's where length is a prime number

Examples: aa, aaa, aaaaa, aaaaaaa (lengths 2, 3, 5, 7, ...)

Proof:

  1. Assume L is regular with pumping length n
  2. Choose w = ap where p is a prime ≥ n (such prime exists by Euclid)
  3. By Pumping Lemma, w = xyz where |y| > 0 and |xy| ≤ n
  4. Let |y| = k where 1 ≤ k ≤ n < p
  5. Pump with i = p: xypz has length:
    • |xyz| + (p-1)|y| = p + (p-1)k = p + pk - k = p(1+k) - k
    • If we choose i = p+1: length = p + p·k = p(1+k)
  6. This is composite (divisible by p and 1+k), not prime!
  7. Contradiction! Therefore L is NOT regular ✓

Application 3: L = {ww | w ∈ {0,1}*} is NOT Regular

Language: Strings that are a word repeated twice

Examples: ε, 00, 11, 0101, 1010, 001001, ...

Proof:

  1. Assume L is regular with pumping length n
  2. Choose w = 0n10n1 (w = (0n1)(0n1), so w ∈ L)
  3. By Pumping Lemma, w = xyz where |y| > 0 and |xy| ≤ n
  4. Since |xy| ≤ n, y consists only of 0's from first part
  5. Pump with i = 2: xy2z adds more 0's to first occurrence
    • First part: 0n+k1 (where k = |y| > 0)
    • Second part: 0n1 (unchanged)
    • Not of form ww anymore!
  6. Contradiction! Therefore L is NOT regular ✓

Application 4: L = {0n1m | n ≠ m} is NOT Regular

Language: Strings with unequal number of 0's and 1's

Proof (using closure properties):

  1. Assume L is regular
  2. Regular languages are closed under complement
  3. So L̄ = {0n1m | n = m} ∪ {strings not of form 0*1*} would be regular
  4. Regular languages are closed under intersection with regular languages
  5. L̄ ∩ 0*1* = {0n1n | n ≥ 0} would be regular
  6. But we proved {0n1n} is NOT regular!
  7. Contradiction! Therefore L is NOT regular ✓

Application 5: L = {0i1j | i > j} is NOT Regular

Language: More 0's than 1's

Proof:

  1. Assume L is regular with pumping length n
  2. Choose w = 0n+11n ∈ L (n+1 > n)
  3. By Pumping Lemma, w = xyz where |xy| ≤ n, |y| > 0
  4. So y = 0k for some k > 0
  5. Pump with i = 0: xz = 0n+1-k1n
    • If k = 1: we get 0n1n where n = n, not i > j!
    • If k > 1: we get 0n+1-k1n where n+1-k ≤ n
    • Either way, xz ∉ L
  6. Contradiction! Therefore L is NOT regular ✓

Common Non-Regular Languages (Using Pumping Lemma):

Language Description Why Not Regular
{0n1n} Equal 0's and 1's Need to count and match
{ww} Repeated string Need to remember first half
{w wR} Palindromes Need to match forward and backward
{ap} Prime length Need to check primality
{a} Perfect squares Need arithmetic computation
{anbncn} Three-way equality Need to count three types

Key Applications Summary:

  1. Proving Non-Regularity: Main use - show languages require more than finite memory
  2. Understanding Limitations: Shows what DFA/NFA/Regex cannot do
  3. Theoretical Foundation: Separates regular from context-free languages
  4. Compiler Design: Determines when to use lexer vs parser
  5. Algorithm Analysis: Indicates when more powerful models needed

Important Reminder:

Pumping Lemma CANNOT prove a language IS regular!

  • It's only a necessary condition, not sufficient
  • Some non-regular languages satisfy pumping lemma
  • To prove regularity: construct DFA/NFA/regex or use closure properties

Q4. Explain Context Free Grammar, Regular Grammar and Derivation Grammar

Answer:

1. Context-Free Grammar (CFG):

Definition:

A Context-Free Grammar is a 4-tuple G = (V, T, P, S) where:

  • V: Finite set of variables (non-terminals) - usually uppercase letters
  • T: Finite set of terminals (alphabet symbols) - usually lowercase letters
  • P: Finite set of production rules of the form A → α where:
    • A ∈ V (single variable on left side)
    • α ∈ (V ∪ T)* (string of variables and terminals on right side)
  • S ∈ V: Start symbol

Key Features of CFG:

  • "Context-Free" means: Variable A can be replaced by α regardless of context (symbols around A don't matter)
  • More powerful than regular grammars - can handle nested structures
  • Left side has EXACTLY ONE variable
  • Right side can have any combination of variables and terminals
  • Can generate Context-Free Languages (CFL)

Example 1: Balanced Parentheses

S → ε
S → (S)
S → SS
                

Generates: ε, (), (()), ()(), ((())), (())(), ()(()), ...

Derivation of "(()())":

S ⇒ (S)           [Apply S → (S)]
  ⇒ (SS)          [Apply S → SS]
  ⇒ ((S)S)        [Apply first S → (S)]
  ⇒ ((S)(S))      [Apply second S → (S)]
  ⇒ (()())        [Apply both S → ε]
                

Example 2: Arithmetic Expressions

E → E + E
E → E * E
E → (E)
E → id
                

Generates: id, id+id, id*id, (id+id)*id, ...

Note: This grammar is ambiguous (multiple parse trees possible)

Example 3: {0n1n | n ≥ 0}

S → 0S1
S → ε
                

Derivations:

  • n=0: S ⇒ ε
  • n=1: S ⇒ 0S1 ⇒ 01
  • n=2: S ⇒ 0S1 ⇒ 00S11 ⇒ 0011
  • n=3: S ⇒ 0S1 ⇒ 00S11 ⇒ 000S111 ⇒ 000111

This language is NOT regular but IS context-free!

2. Regular Grammar:

A Regular Grammar is a restricted form of CFG that generates exactly the Regular Languages.

Types of Regular Grammars:

Right-Linear Grammar: All productions of the form:

  • A → wB (terminal string followed by ONE variable)
  • A → w (terminal string only)

Where A, B ∈ V and w ∈ T*

Left-Linear Grammar: All productions of the form:

  • A → Bw (ONE variable followed by terminal string)
  • A → w (terminal string only)

Restrictions in Regular Grammar:

  • At most ONE variable on right side
  • If variable present, must be at END (right-linear) or START (left-linear)
  • Cannot mix right-linear and left-linear in same grammar
  • No recursion in the middle

Example 1: Right-Linear Grammar

Language: Strings ending with 'ab'

S → aS | bS | aB
B → b
                

Analysis:

  • S → aS or bS: Read any symbol, stay in S
  • S → aB: Read 'a', prepare for final 'b'
  • B → b: Generate final 'b'

Generates: ab, aab, bab, aaab, abab, ababab, ...

Example 2: Left-Linear Grammar

Language: (ab)*

S → Sab | ε
                

Generates: ε, ab, abab, ababab, ...

Example 3: Binary Strings with Even 0's

S → 1S | 0A | ε
A → 1A | 0S
                

Analysis:

  • S: even number of 0's seen
  • A: odd number of 0's seen
  • Reading 1 doesn't change state
  • Reading 0 toggles between S and A

Comparison: Regular vs Context-Free Grammar:

Feature Regular Grammar Context-Free Grammar
Production form A → wB or A → w
(restricted)
A → α
(any string)
Variables on right At most ONE, at end/start Any number, anywhere
Recursion Only tail/head recursion Any recursion (including nested)
Example production S → aB ✓
S → ABc ✗
S → aB ✓
S → ABc ✓
Languages generated Regular Languages Context-Free Languages
Can describe Patterns without counting Nested structures, counting
Example (01)* ✓
0ⁿ1ⁿ ✗
(01)* ✓
0ⁿ1ⁿ ✓
Automaton Finite Automata Pushdown Automata

3. Derivation in Grammar:

A derivation is a sequence of production rule applications that transforms the start symbol into a terminal string.

Types of Derivations:

1. Leftmost Derivation:

Always replace the leftmost variable in each step.

Example Grammar:

E → E + T | T
T → T * F | F
F → (E) | id
                

Leftmost derivation of "id + id * id":

E ⇒ E + T                [Replace leftmost E]
  ⇒ T + T                [Replace leftmost E]
  ⇒ F + T                [Replace leftmost T]
  ⇒ id + T               [Replace leftmost F]
  ⇒ id + T * F           [Replace leftmost T]
  ⇒ id + F * F           [Replace leftmost T]
  ⇒ id + id * F          [Replace leftmost F]
  ⇒ id + id * id         [Replace leftmost F]
                

2. Rightmost Derivation:

Always replace the rightmost variable in each step.

Rightmost derivation of "id + id * id":

E ⇒ E + T                [Replace rightmost E]
  ⇒ E + T * F            [Replace rightmost T]
  ⇒ E + T * id           [Replace rightmost F]
  ⇒ E + F * id           [Replace rightmost T]
  ⇒ E + id * id          [Replace rightmost F]
  ⇒ T + id * id          [Replace rightmost E]
  ⇒ F + id * id          [Replace rightmost T]
  ⇒ id + id * id         [Replace rightmost F]
                

Derivation Notation:

  • ⇒: Derives in one step (one production application)
  • ⇒*: Derives in zero or more steps
  • ⇒⁺: Derives in one or more steps
  • lm: Leftmost derivation
  • rm: Rightmost derivation

Parse Tree:

A parse tree (or derivation tree) is a graphical representation of a derivation.

Parse Tree for "id + id":

           E
          /|\
         / | \
        E  +  T
        |     |
        T     F
        |     |
        F     id
        |
       id
                

Properties:

  • Root: Start symbol (E)
  • Internal nodes: Variables
  • Leaves: Terminals
  • Reading leaves left-to-right gives the derived string
  • Same parse tree for both leftmost and rightmost derivations!

Language Generated by Grammar:

L(G) = {w ∈ T* | S ⇒* w}

The language consists of all terminal strings that can be derived from start symbol.

Important Concepts:

  1. Sentential Form: Any string derivable from S (can contain variables and terminals)
  2. Sentence: Sentential form containing only terminals (w ∈ T*)
  3. Ambiguity: Grammar is ambiguous if some string has multiple parse trees
  4. Equivalence: Two grammars are equivalent if they generate same language

Example: Ambiguous Grammar

E → E + E | E * E | id
                

String "id + id * id" has TWO parse trees:

Tree 1: (id + id) * id [add first]

Tree 2: id + (id * id) [multiply first]

This is ambiguous! Need to rewrite with precedence levels.

Applications:

  • Programming Languages: Syntax specification
  • Compilers: Parsing source code
  • Natural Language Processing: Sentence structure
  • XML/HTML: Document structure
  • Formal Verification: Protocol specification

Q5. Explain the Chomsky Normal Form and Greibach Normal Form

Answer:

Normal forms are standardized formats for Context-Free Grammars that simplify analysis and implementation while preserving the language generated.

1. Chomsky Normal Form (CNF):

Definition:

A Context-Free Grammar is in Chomsky Normal Form if every production is in one of these forms:

  1. A → BC: Variable derives exactly TWO variables
  2. A → a: Variable derives single terminal
  3. S → ε: Start symbol can derive empty string (only if ε ∈ L)

Restrictions:

  • If S → ε exists, S cannot appear on right side of any production
  • No ε-productions except possibly S → ε
  • No unit productions (A → B)

Why Chomsky Normal Form?

  • Standard Format: Every CFG can be converted to CNF
  • Binary Tree: Parse trees become binary trees
  • Parsing: Enables efficient parsing algorithms (CYK algorithm)
  • Complexity Analysis: Easy to prove bounds on derivation length
  • Theorem Proving: Simplifies proofs about CFGs

Properties of CNF:

  • For string of length n, derivation has exactly 2n-1 steps
  • Parse tree height ≥ log₂(n)
  • Every non-ε CFL has CNF grammar

Example 1: Simple CNF Grammar

S → AB
S → BC
A → BA
A → a
B → CC
B → b
C → AB
C → a
                

✓ All productions are either A → BC or A → a form

Converting to Chomsky Normal Form:

Step-by-step algorithm:

Step 1: Add New Start Symbol

Create new start S₀ → S to ensure start doesn't appear on right side

Original: S → ASA | aB
Add: S₀ → S
                

Step 2: Eliminate ε-Productions

Remove all A → ε (except possibly S → ε)

Original:
S → ASA | aB
A → B | ε
B → b | ε

After eliminating ε:
S → ASA | SA | AS | S | aB | a
A → B
B → b
                

Step 3: Eliminate Unit Productions

Remove all A → B (single variable productions)

Before: A → B, B → b
After: A → b (substitute)

Result:
S → ASA | SA | AS | S | aB | a
A → b
B → b
                

Step 4: Replace Terminals in Long Productions

For productions with terminals mixed with variables, create new variables for terminals

S → ASA becomes S → A₁SA₁ with A₁ → a
S → aB becomes S → A₁B with A₁ → a

After:
S → A₁SA₁ | SA | AS | A₁B
A₁ → a
A → b
B → b
                

Step 5: Break Long Productions

Productions with >2 variables broken into binary productions

S → A₁SA₁ (3 variables) breaks into:
S → A₁C₁
C₁ → SA₁

Final CNF:
S → A₁C₁ | SA | AS | A₁B
C₁ → SA₁
A₁ → a
A → b
B → b
                

Complete Example: Convert to CNF

Original Grammar:

S → ASA | aB
A → B | S
B → b | ε
                

Step 1: New start

S₀ → S
S → ASA | aB
A → B | S
B → b | ε
                

Step 2: Eliminate ε (B → ε makes B nullable)

S₀ → S
S → ASA | aB | a
A → B | S
B → b
                

Step 3: Eliminate unit productions

S₀ → ASA | aB | a
S → ASA | aB | a
A → b | ASA | aB | a
B → b
                

Step 4: Replace terminals

T_a → a
T_b → b
S₀ → ASA | T_aB | a
S → ASA | T_aB | a
A → b | ASA | T_aB | a
B → b
                

Step 5: Break long productions (ASA has 3 symbols)

S₀ → AC₁ | T_aB | a
S → AC₁ | T_aB | a
C₁ → SA
A → b | AC₁ | T_aB | a
B → b
T_a → a
                

Final CNF ✓

2. Greibach Normal Form (GNF):

Definition:

A Context-Free Grammar is in Greibach Normal Form if every production is in the form:

A → aα

Where:

  • a ∈ T: Terminal symbol (MUST be first)
  • α ∈ V*: String of zero or more variables

Exception: S → ε allowed if ε ∈ L(G)

Why Greibach Normal Form?

  • Direct Terminal Generation: Every step produces exactly one terminal
  • Predictable Derivation: For string of length n, exactly n derivation steps
  • PDA Construction: Direct conversion to Pushdown Automata
  • Leftmost Derivation: Easy to construct leftmost derivations

Properties of GNF:

  • Derivation length = String length (one terminal per step)
  • No left recursion
  • Every non-ε CFL has GNF grammar
  • One-to-one mapping with PDA transitions

Example 1: Simple GNF Grammar

S → aAB | bB | a
A → aA | bB | a
B → bB | b
                

✓ Every production starts with terminal

✓ Followed by zero or more variables

Derivation of "aba":

S ⇒ aAB     [Produce 'a']
  ⇒ abB     [Produce 'b']
  ⇒ aba     [Produce 'a']
                

Exactly 3 steps for 3 terminals!

Example 2: L = {0ⁿ1ⁿ | n ≥ 1} in GNF

S → 0S1 | 01
                

Wait, this is NOT in GNF! (has terminal at end)

Correct GNF:

S → 0A
A → 0A1 | 01
                

Or better:

S → 0SA₁ | 0A₁
A₁ → 1
                

Now every production starts with terminal ✓

Converting to Greibach Normal Form:

More complex than CNF conversion:

  1. Convert to CNF first
  2. Eliminate left recursion
  3. Ensure every production starts with terminal
  4. May require introducing many new variables

Example: Eliminate Left Recursion

Original (has left recursion):

A → Aα | β (where β doesn't start with A)
                

Converted (no left recursion):

A → βA'
A' → αA' | ε
                

For GNF, further transform to start with terminal

Comparison: CNF vs GNF:

Feature Chomsky Normal Form Greibach Normal Form
Production form A → BC or A → a A → aα (α is variables)
Number of symbols Exactly 1 or 2 1 terminal + any number of variables
Terminal position Alone or generated last Always FIRST
Parse tree Binary tree Terminal at every level
Derivation steps 2n-1 for string of length n Exactly n for string of length n
Left recursion Allowed Not allowed
Conversion ease Easier to convert to More complex conversion
Main use Parsing (CYK algorithm) PDA construction
Example S → AB, A → a S → aAB, A → a

Applications:

  • CNF: CYK parsing algorithm, complexity analysis, proving language properties
  • GNF: Direct PDA construction, top-down parsing, compiler design

Important Theorem:

Every Context-Free Language (except possibly empty string) can be generated by:

  • A grammar in Chomsky Normal Form
  • A grammar in Greibach Normal Form

Both normal forms have same expressive power as general CFGs!

Q6. What is Push Down Automata and Also Explain DPDA

Answer:

Pushdown Automata (PDA):

A Pushdown Automaton is a finite automaton with an additional stack memory. It's the computational model for Context-Free Languages.

Formal Definition:

A PDA is a 7-tuple P = (Q, Σ, Γ, δ, q₀, Z₀, F) where:

  • Q: Finite set of states
  • Σ: Input alphabet
  • Γ: Stack alphabet
  • δ: Q × (Σ ∪ {ε}) × Γ → P(Q × Γ*): Transition function
    • δ(q, a, X) = {(p₁, γ₁), (p₂, γ₂), ...}
    • From state q, reading a, with X on stack top
    • Can go to state pᵢ and replace X with γᵢ
  • q₀ ∈ Q: Initial state
  • Z₀ ∈ Γ: Initial stack symbol
  • F ⊆ Q: Final states (for acceptance by final state)

Components of PDA:

  1. Input Tape: Contains input string, read-only, left-to-right
  2. Finite Control: Maintains current state
  3. Stack: Unlimited LIFO memory
    • Can push symbols onto stack
    • Can pop symbols from stack
    • Can read top symbol without popping

How PDA Works:

In state q, reading input a, with X on stack top:
1. Pop X from stack
2. Based on δ(q, a, X), choose transition (p, γ)
3. Go to state p
4. Push string γ onto stack (rightmost symbol on top)
5. Move to next input (if a ≠ ε)
            

Acceptance Methods:

  1. Acceptance by Final State:
    • Input accepted if PDA reaches final state after reading entire input
    • Stack can be non-empty
  2. Acceptance by Empty Stack:
    • Input accepted if stack becomes empty after reading entire input
    • No final states needed

Important: Both acceptance methods are equivalent in power - can convert between them!

Example 1: PDA for L = {0ⁿ1ⁿ | n ≥ 1}

Idea: Push all 0's onto stack, pop one for each 1

PDA Design:

States: {q₀, q₁, q₂}
Stack Alphabet: {0, Z₀}
                

Transitions:

State Input Stack Top Next State Stack Action
q₀ 0 Z₀ q₀ Push 0 (0Z₀)
q₀ 0 0 q₀ Push 0 (00)
q₀ 1 0 q₁ Pop 0 (ε)
q₁ 1 0 q₁ Pop 0 (ε)
q₁ ε Z₀ q₂ Pop Z₀ (ε)

Trace for "0011":

(q₀, 0011, Z₀)   [Start]
⊢ (q₀, 011, 0Z₀)  [Push 0]
⊢ (q₀, 11, 00Z₀)  [Push 0]
⊢ (q₁, 1, 0Z₀)    [Pop 0]
⊢ (q₁, ε, Z₀)     [Pop 0]
⊢ (q₂, ε, ε)      [Accept - reached final state]
                

Example 2: PDA for Balanced Parentheses

Language: Well-formed parentheses

Transitions:

  • δ(q, '(', Z₀) = {(q, (Z₀)} - Push ( on empty stack
  • δ(q, '(', '(') = {(q, (()} - Push ( on stack
  • δ(q, ')', '(') = {(q, ε)} - Pop ( when seeing )
  • δ(q, ε, Z₀) = {(f, Z₀)} - Accept if stack has only Z₀

Examples:

  • "(())" ✓ - Balanced
  • "()()" ✓ - Balanced
  • "(()" ✗ - Too many open
  • "())" ✗ - Too many close

Power of PDA:

  • More powerful than FA: Can recognize {0ⁿ1ⁿ}
  • Equivalent to CFG: L recognized by PDA ⟺ L generated by CFG
  • Less powerful than TM: Cannot recognize {0ⁿ1ⁿ2ⁿ}

Deterministic Pushdown Automata (DPDA):

Definition of DPDA:

A PDA is deterministic if it satisfies:

  1. At most one transition: For every (q, a, X), |δ(q, a, X)| ≤ 1
  2. No ε-ambiguity: If δ(q, ε, X) is defined, then δ(q, a, X) must be undefined for all a ∈ Σ

In other words: No choice in transitions!

Key Differences: DPDA vs NPDA:

Feature DPDA (Deterministic) NPDA (Nondeterministic)
Transitions At most one choice Multiple choices allowed
Behavior Predictable path Can explore multiple paths
ε-transitions Restricted (no ambiguity) Unrestricted
Languages Deterministic CFL (DCFL) All CFL
Power LESS powerful MORE powerful
Closure under complement YES (closed) NO (not closed)
Examples {0ⁿ1ⁿ}, LR(k) languages {wwᴿ}, all CFL
Real-world Programming language parsers Theoretical model

Example: DPDA for {0ⁿ1ⁿ | n ≥ 1}

δ(q₀, 0, Z₀) = (q₀, 0Z₀)     ✓ Only one choice
δ(q₀, 0, 0) = (q₀, 00)       ✓ Only one choice
δ(q₀, 1, 0) = (q₁, ε)        ✓ Only one choice
δ(q₁, 1, 0) = (q₁, ε)        ✓ Only one choice
δ(q₁, ε, Z₀) = (q₂, Z₀)      ✓ Only one ε-transition
                                 and no input transition
                                 from (q₁, Z₀)

This is DETERMINISTIC ✓
                

Languages NOT Recognized by DPDA:

L = {wwᴿ | w ∈ {a,b}*} (Even Palindromes)

Problem: DPDA cannot determine the middle point!

  • NPDA can nondeterministically guess middle
  • DPDA has no way to know when to switch from pushing to popping
  • Example: "abba" - when to stop pushing and start popping?

Conclusion: {wwᴿ} is CFL but NOT DCFL

DCFL ⊂ CFL (Proper Subset):

  • Every DCFL is CFL (DPDA is special case of NPDA)
  • Not every CFL is DCFL ({wwᴿ} is counterexample)
  • Therefore: DCFL ⊂ CFL (proper subset)

Applications:

  • NPDA: Theoretical model, proving language properties
  • DPDA: Practical parsing (LR parsers, compiler design)
  • Programming Languages: Most languages designed to be DCFL
  • XML/HTML Parsing: Deterministic parsing

Important Results:

  • PDA (by final state) ≡ PDA (by empty stack)
  • PDA ≡ CFG (same expressive power)
  • DPDA ≠ NPDA (DPDA less powerful)
  • DCFL is closed under complement (CFL is not)

Q7. What is Turing Machine. Explain in Detail

Answer:

A Turing Machine (TM) is the most powerful computational model in automata theory. It was proposed by Alan Turing in 1936 as a mathematical model of computation that defines an abstract machine.

Formal Definition:

A Turing Machine is a 7-tuple M = (Q, Σ, Γ, δ, q₀, B, F) where:

  • Q: Finite set of states
  • Σ: Input alphabet (symbols that can appear in input)
  • Γ: Tape alphabet where Σ ⊂ Γ (all symbols that can appear on tape)
  • δ: Q × Γ → Q × Γ × {L, R}: Transition function
    • δ(q, X) = (p, Y, D)
    • In state q, reading X, go to state p, write Y, move Direction D
  • q₀ ∈ Q: Initial/Start state
  • B ∈ Γ: Blank symbol (B ∉ Σ)
  • F ⊆ Q: Set of final/accepting states

Components of Turing Machine:

  1. Infinite Tape:
    • Divided into cells, each holding one symbol from Γ
    • Infinite in both directions
    • Initially contains input string, rest is blank (B)
  2. Tape Head:
    • Points to one cell on tape
    • Can read and write symbols
    • Can move LEFT or RIGHT one cell at a time
  3. Finite Control:
    • Has finite number of states
    • Controls behavior based on current state and tape symbol

How Turing Machine Works:

At each step:
1. Read symbol X at current tape position
2. Based on current state q and symbol X:
   - Change to new state p
   - Write new symbol Y at current position
   - Move head LEFT (L) or RIGHT (R)
3. Repeat until reaching accepting or rejecting state
            

Visual Representation:

    Finite Control
    +----------+
    | State: q |
    +----------+
         ↓
    ... B | 0 | 1 | 0 | B | B ...
              ↑
           Tape Head
           (currently at position with '1')
                

Instantaneous Description (ID):

Configuration of TM at any moment: X₁X₂...qXᵢXᵢ₊₁...Xₙ

  • q is current state
  • Xᵢ is symbol under tape head
  • X₁...Xᵢ₋₁ are symbols to the left
  • Xᵢ₊₁...Xₙ are symbols to the right

Moves of TM:

Notation: ID₁ ⊢ ID₂ (ID₁ yields ID₂ in one move)

Example:

If δ(q, X) = (p, Y, R) then:
    X₁X₂...qXXᵢ₊₁...Xₙ ⊢ X₁X₂...YpXᵢ₊₁...Xₙ
    (Replace X with Y, move right to state p)

If δ(q, X) = (p, Y, L) then:
    X₁X₂...Xᵢ₋₁qXXᵢ₊₁...Xₙ ⊢ X₁X₂...pXᵢ₋₁YXᵢ₊₁...Xₙ
    (Replace X with Y, move left to state p)
            

Acceptance/Rejection:

  1. Acceptance by Final State:
    • TM accepts if it enters a final state (q ∈ F)
    • Input completely processed or not doesn't matter
  2. Acceptance by Halting:
    • TM accepts if it halts (no move defined)
    • TM rejects if it enters infinite loop

Example 1: TM for L = {0ⁿ1ⁿ | n ≥ 1}

Idea: Match each 0 with corresponding 1

Algorithm:

  1. Replace leftmost 0 with X
  2. Move right past all 0's and 1's
  3. Replace leftmost 1 with Y
  4. Move left back to start
  5. Repeat until all 0's matched with 1's
  6. Accept if tape has only X's and Y's

States:

  • q₀: Start state
  • q₁: After replacing 0 with X, searching for 1
  • q₂: After replacing 1 with Y, going back
  • q₃: Checking if done
  • q₄: Accept state

Transition Table:

Current State Read Symbol Next State Write Symbol Direction
q₀ 0 q₁ X R
q₀ Y q₃ Y R
q₁ 0 q₁ 0 R
q₁ Y q₁ Y R
q₁ 1 q₂ Y L
q₂ 0 q₂ 0 L
q₂ Y q₂ Y L
q₂ X q₀ X R
q₃ Y q₃ Y R
q₃ B q₄ B R

Trace for input "0011":

1. q₀0011B     [Start]
2. Xq₁011B     [Replace 0 with X, move right]
3. X0q₁11B     [Skip 0]
4. X0q₂Y1B     [Replace 1 with Y, move left]
5. Xq₂0Y1B     [Move left]
6. q₂X0Y1B     [Move left]
7. Xq₀0Y1B     [Back at X, move right]
8. XXq₁Y1B     [Replace 0 with X, move right]
9. XXYq₁1B     [Skip Y]
10. XXq₂YYB    [Replace 1 with Y, move left]
11. Xq₂XYYB    [Move left]
12. XXq₀YYB    [Back at X, move right]
13. XXYq₃YB    [No more 0's, check]
14. XXYYq₃B    [Move right]
15. XXYYBq₄    [Accept! ✓]
                

Example 2: TM for Addition

Language: Binary addition (compute m + n)

Input: 0ᵐ10ⁿ (m and n in unary)

Output: 0ᵐ⁺ⁿ

Algorithm:

  1. Replace the separator '1' with '0'
  2. Erase the rightmost '0'

Example: 000100 → 000000 → 00000 (3+2=5)

Types of Turing Machines:

Type Description Power
Single-tape TM One tape (basic model) Universal
Multi-tape TM Multiple tapes with separate heads Same as single-tape
Non-deterministic TM Multiple transitions possible Same as deterministic
Universal TM Can simulate any other TM Universal computation

Church-Turing Thesis:

Thesis: Any function that is "effectively computable" can be computed by a Turing Machine.

Meaning: TM captures the essence of what it means to compute!

  • All reasonable computational models equivalent to TM
  • Modern computers = Turing Machines (with finite memory)
  • If TM can't solve it, no algorithm can

Languages Recognized by TM:

  1. Recursively Enumerable (RE):
    • L is RE if some TM accepts all strings in L
    • TM may loop forever on strings not in L
    • Semi-decidable
  2. Recursive:
    • L is recursive if some TM accepts L and halts on all inputs
    • TM always halts (accept or reject)
    • Decidable
    • Recursive ⊂ RE (proper subset)

Power Comparison:

Machine Memory Languages
Finite Automata None (only states) Regular Languages
Pushdown Automata Stack (LIFO) Context-Free Languages
Turing Machine Infinite Tape Recursively Enumerable

Applications and Significance:

  • Foundation of Computer Science: Defines limits of computation
  • Complexity Theory: Basis for P, NP, etc.
  • Undecidability: Proves some problems have no algorithm (Halting Problem)
  • Programming Languages: All modern languages equivalent to TM
  • AI and Computation: Understanding what machines can/cannot do

Important Facts:

  • TM is the MOST POWERFUL computational model
  • Deterministic TM = Nondeterministic TM (same power)
  • Multi-tape TM = Single-tape TM (same power)
  • Every modern computer is a TM with finite tape
  • Halting Problem is undecidable (TM cannot solve it for all TMs)

Q8. Explain the P, NP, NP-Complete, and NP-Hard Problems

Answer:

Computational complexity theory classifies problems based on the computational resources (time, space) required to solve them. The P, NP, NP-Complete, and NP-Hard classes form the foundation of this classification.

1. P (Polynomial Time):

Definition:

P is the class of decision problems that can be solved by a deterministic Turing Machine in polynomial time.

Formally: P = {L | L can be decided in O(nᵏ) time for some constant k}

  • Solution algorithm runs in O(nᵏ) time
  • Efficient, tractable problems
  • Practically solvable

Characteristics of P:

  • Deterministic: One computational path
  • Efficient: Polynomial time means feasible for large inputs
  • Closed under: Union, intersection, complement, concatenation
  • Decidable: Always halts with answer

Examples of P Problems:

Problem Time Complexity
Sorting O(n log n)
Binary Search O(log n)
Graph Connectivity O(V + E)
Shortest Path (Dijkstra) O(V²) or O(E log V)
Minimum Spanning Tree O(E log V)
Primality Testing (AKS) O((log n)¹²)
Matrix Multiplication O(n²·³⁷³)

2. NP (Nondeterministic Polynomial Time):

Definition:

NP is the class of decision problems where a "yes" answer can be verified in polynomial time.

Two equivalent definitions:

  1. Nondeterministic TM: Can be solved in polynomial time by non-deterministic TM
  2. Verifier-based: Given solution (certificate), can verify it in polynomial time

Characteristics of NP:

  • Verification: Easy to check solution, hard to find it
  • Certificate: Needs "proof" or "witness" that can be verified quickly
  • Relationship: P ⊆ NP (if you can solve in poly time, you can verify in poly time)
  • Unknown: Whether P = NP is biggest open problem in CS!

Examples of NP Problems:

Problem Verification
Hamiltonian Cycle Given a cycle, check if it visits all vertices once - O(n)
Traveling Salesman Given a tour, check if total distance ≤ k - O(n)
3-SAT Given assignment, check if formula satisfied - O(n)
Vertex Cover Given set of k vertices, check if covers all edges - O(E)
Subset Sum Given subset, check if sum = target - O(n)

Note: All these problems have exponential time solutions but polynomial time verification!

3. NP-Complete:

Definition:

A problem L is NP-Complete if:

  1. L ∈ NP: L is in NP (can verify solution in poly time)
  2. L is NP-Hard: Every problem in NP can be reduced to L in polynomial time

Meaning: NP-Complete problems are the "hardest" problems in NP!

Significance of NP-Complete:

  • If ANY NP-Complete problem can be solved in polynomial time, then P = NP
  • If ANY NP-Complete problem cannot be solved in polynomial time, then P ≠ NP
  • All NP-Complete problems are "equally hard"
  • Can reduce any NP-Complete problem to any other in poly time

Proving NP-Completeness:

To prove problem X is NP-Complete:

  1. Show X ∈ NP: Give polynomial-time verification algorithm
  2. Show X is NP-Hard: Reduce known NP-Complete problem to X in polynomial time

Common NP-Complete Problems:

Problem Description
SAT Boolean satisfiability (first proven NP-Complete - Cook-Levin 1971)
3-SAT SAT with clauses of exactly 3 literals
Hamiltonian Cycle Does graph have cycle visiting each vertex once?
TSP (decision) Is there tour of length ≤ k?
Vertex Cover Can k vertices cover all edges?
Clique Is there complete subgraph of size k?
Graph Coloring Can graph be colored with k colors?
Subset Sum Does subset sum to target?
Knapsack (decision) Can value ≥ V be achieved with weight ≤ W?

4. NP-Hard:

Definition:

A problem L is NP-Hard if:

Every problem in NP can be reduced to L in polynomial time.

Important: L does NOT need to be in NP!

  • At least as hard as hardest problems in NP
  • May not even be decision problems
  • May not be in NP (could be even harder!)

NP-Hard vs NP-Complete:

  • NP-Complete = NP ∩ NP-Hard
  • NP-Hard problems may be harder than NP (not verifiable in poly time)
  • Optimization versions of NP-Complete problems are often NP-Hard but not NP-Complete

Examples of NP-Hard (but not NP-Complete):

Problem Why NP-Hard but not NP-Complete?
TSP (optimization) Find shortest tour (not decision problem)
Halting Problem Undecidable (not even in NP)
General Game Playing Harder than NP
Knapsack (optimization) Maximize value (not decision problem)

Complexity Class Hierarchy:

                    Undecidable Problems
                           ↑
                      NP-Hard Problems
                           ↑
                 NP-Complete Problems
                      ↗          ↖
                    NP            ?
                     ↑            ?
                     P            ?
                     
            P ⊆ NP (proven)
            P = NP? (unknown - million dollar question!)
            NP-Complete ⊆ NP-Hard
            NP-Complete = NP ∩ NP-Hard
            

Visual Relationship:

┌─────────────────────────────────────┐
│           NP-Hard                   │
│  ┌──────────────────────────────┐   │
│  │         NP                   │   │
│  │  ┌─────────────────────┐     │   │
│  │  │    NP-Complete      │     │   │
│  │  │  (Hardest in NP)    │     │   │
│  │  └─────────────────────┘     │   │
│  │  ┌──────────┐                │   │
│  │  │    P     │                │   │
│  │  │  (Easy)  │                │   │
│  │  └──────────┘                │   │
│  └──────────────────────────────┘   │
│  Optimization TSP, etc.             │
└─────────────────────────────────────┘
                

The P vs NP Question:

The Million Dollar Question:

Does P = NP?

If P = NP:

  • Every problem with poly-time verifiable solution has poly-time solving algorithm
  • Would revolutionize cryptography (most encryption breakable!)
  • Many practical problems become efficiently solvable

If P ≠ NP: (most believe this)

  • Some problems inherently harder than others
  • Cryptography remains secure
  • NP-Complete problems have no efficient solution

Prize: $1,000,000 (Clay Mathematics Institute Millennium Prize)

Practical Implications:

Class Approach
P Solve optimally with exact algorithm
NP-Complete Use approximation algorithms, heuristics, or solve small instances
NP-Hard Same as NP-Complete, possibly harder

Summary:

  • P: Efficiently solvable
  • NP: Efficiently verifiable
  • NP-Complete: Hardest problems in NP
  • NP-Hard: At least as hard as NP-Complete
  • P ⊆ NP ⊆ NP-Hard
  • NP-Complete = NP ∩ NP-Hard

Q9. Explain the Hamiltonian Problem with Example

Answer:

The Hamiltonian Path/Cycle Problem is a classic problem in graph theory and one of the most well-known NP-Complete problems in computer science.

Definitions:

Hamiltonian Path:

A path in a graph that visits each vertex exactly once.

  • Starts at one vertex, ends at another
  • Never repeats a vertex
  • May or may not use all edges

Hamiltonian Cycle (or Circuit):

A cycle in a graph that visits each vertex exactly once and returns to starting vertex.

  • Closed path (cycle)
  • Visits every vertex exactly once
  • Returns to starting vertex

Formal Problem Statement:

Decision Problem: Given a graph G = (V, E), does there exist a Hamiltonian path/cycle in G?

  • Input: Graph G with n vertices
  • Output: YES if Hamiltonian path/cycle exists, NO otherwise
  • Complexity: NP-Complete

Example 1: Graph WITH Hamiltonian Cycle

Graph:
        A ---- B
        |      |
        |      |
        D ---- C

Edges: {(A,B), (B,C), (C,D), (D,A)}

Hamiltonian Cycle: A → B → C → D → A ✓
    - Visits all 4 vertices exactly once
    - Returns to starting vertex A
    - This is a Hamiltonian Cycle!

Other Hamiltonian Cycles:
    B → C → D → A → B
    C → D → A → B → C
    D → A → B → C → D
    (All are rotations/reflections of same cycle)
                

Example 2: Graph WITHOUT Hamiltonian Cycle

Graph:
        A ---- B ---- C
        |             |
        |             |
        D ----------- E

Edges: {(A,B), (B,C), (C,E), (E,D), (D,A)}

Try all possible paths starting from A:
    A → B → C → E → D → ? (need to return to A, but no edge from D to A)
    A → D → E → C → B → ? (need to return to A, but no edge from B to A)
    
Problem: After visiting all vertices, cannot return to start!
Hamiltonian Cycle: DOES NOT EXIST ✗

However, Hamiltonian PATH exists:
    B → A → D → E → C ✓ (visits all vertices once)
                

Example 3: Complete Graph K₅

Complete graph with 5 vertices (every vertex connected to every other):

        A
       /|\\\
      / | \\\
     /  |  \\\
    B---+---C
     \  |  /
      \ | /
       \|/
        D---E

Every pair of vertices connected!

Hamiltonian Cycle exists: A → B → C → D → E → A ✓

In fact, complete graph Kₙ (n ≥ 3) ALWAYS has Hamiltonian cycle!

Number of distinct Hamiltonian cycles in Kₙ: (n-1)!/2
For K₅: (5-1)!/2 = 24/2 = 12 distinct cycles
                

Example 4: Detailed Trace

Graph:

        1 ---- 2
       /|      |\\
      / |      | \\
     /  |      |  \\
    5   |      |   3
     \  |      |  /
      \ |      | /
       \|      |/
        6 ---- 4

Edges: {(1,2), (1,5), (1,6), (2,3), (2,4), (3,4), (4,6), (5,6)}
                

Find Hamiltonian Cycle:

Try starting from vertex 1:

Attempt 1: 1 → 2 → 3 → 4 → 6 → 5 → ?
    Need edge (5,1) but doesn't exist ✗

Attempt 2: 1 → 2 → 4 → 3 → ?
    Stuck, can't reach remaining vertices ✗

Attempt 3: 1 → 2 → 4 → 6 → 5 → ?
    Need edge (5,3) but doesn't exist ✗

Attempt 4: 1 → 5 → 6 → 4 → 3 → 2 → ?
    Need edge (2,1) - YES, exists! ✓

Hamiltonian Cycle Found: 1 → 5 → 6 → 4 → 3 → 2 → 1 ✓
                

Properties and Characteristics:

Property Description
Complexity NP-Complete (no known polynomial-time algorithm)
Related to Traveling Salesman Problem
Graph types Applies to directed/undirected graphs
Verification Easy - check if path visits all vertices (O(n))
Finding solution Hard - may need to try exponential paths

Necessary Conditions (Not Sufficient):

For Hamiltonian Cycle to exist:

  • Degree: Every vertex must have degree ≥ 2
  • Connectivity: Graph must be connected
  • No Cut Vertex: Removing one vertex shouldn't disconnect graph (for some cases)

Note: These are necessary but NOT sufficient conditions!

Sufficient Conditions:

Dirac's Theorem (1952):

If G has n ≥ 3 vertices and every vertex has degree ≥ n/2, then G has Hamiltonian cycle.

Example: Graph with 6 vertices where each vertex has degree ≥ 3

Ore's Theorem (1960):

If G has n ≥ 3 vertices and for every pair of non-adjacent vertices u, v: deg(u) + deg(v) ≥ n, then G has Hamiltonian cycle.

Weaker condition than Dirac's theorem

Special Cases:

Graph Type Hamiltonian Cycle?
Complete Graph Kₙ (n ≥ 3) Always YES
Cycle Cₙ Always YES (the cycle itself)
Tree Only if path (no cycles allowed)
Bipartite Graph Only if both partitions have equal size
Petersen Graph YES (but not planar Hamiltonian)

Algorithms:

  1. Backtracking:
    • Try all possible paths systematically
    • Time: O(n!) - exponential
    • Works for small graphs
  2. Dynamic Programming:
    • Held-Karp algorithm
    • Time: O(n²2ⁿ)
    • Better than naive but still exponential
  3. Heuristics:
    • Nearest neighbor, genetic algorithms
    • No guarantee of finding solution
    • Fast but may miss existing cycles

Backtracking Algorithm:

HamiltonianCycle(graph G, path, pos):
    if pos == n:  // All vertices included
        if edge exists from path[pos-1] to path[0]:
            return true  // Cycle found!
        else:
            return false
    
    for each vertex v in G:
        if isSafe(v, graph, path, pos):
            path[pos] = v
            if HamiltonianCycle(G, path, pos+1):
                return true
            path[pos] = -1  // Backtrack
    
    return false

isSafe(v, graph, path, pos):
    // Check if vertex v can be added at position pos
    if edge doesn't exist from path[pos-1] to v:
        return false
    if v already in path:
        return false
    return true
                

Applications:

  • Route Planning: Visit all cities exactly once
  • Puzzle Solving: Knight's tour on chessboard
  • DNA Sequencing: Finding optimal sequence assembly
  • Circuit Design: Testing all components
  • Computer Graphics: Polygon vertex ordering

Relationship to TSP:

  • Hamiltonian Cycle is special case of TSP
  • TSP: Find shortest Hamiltonian cycle (optimization)
  • Hamiltonian: Does ANY Hamiltonian cycle exist? (decision)
  • Both are NP-Complete/NP-Hard

Important Facts:

  • Finding Hamiltonian cycle is NP-Complete
  • Verifying a cycle is Hamiltonian is O(n) - easy!
  • No known polynomial-time algorithm
  • For dense graphs (many edges), more likely to have Hamiltonian cycle
  • First proven NP-Complete by Richard Karp (1972)

Q10. Explain Traveling Salesman Problem with Example

Answer:

The Traveling Salesman Problem (TSP) is one of the most famous and extensively studied problems in combinatorial optimization and computational complexity theory.

Problem Statement:

Informal Description:

A salesman must visit n cities exactly once each, then return to the starting city. What is the shortest possible route?

Formal Definition:

Given:

  • Set of n cities
  • Distance d(i,j) between every pair of cities i and j

Find: A tour (Hamiltonian cycle) that minimizes total distance traveled

Objective: Minimize Σ d(city_i, city_{i+1}) for all cities in tour

Two Versions:

Version Problem Type Complexity
Decision TSP Is there a tour with distance ≤ k? NP-Complete
Optimization TSP Find tour with minimum distance NP-Hard (harder!)

Example 1: Small TSP Instance (4 Cities)

Cities: A, B, C, D

Distance Matrix:

A B C D
A 0 10 15 20
B 10 0 35 25
C 15 35 0 30
D 20 25 30 0

All Possible Tours (starting from A):

Tour 1: A → B → C → D → A
    Distance: 10 + 35 + 30 + 20 = 95

Tour 2: A → B → D → C → A
    Distance: 10 + 25 + 30 + 15 = 80 ✓ BEST!

Tour 3: A → C → B → D → A
    Distance: 15 + 35 + 25 + 20 = 95

Tour 4: A → C → D → B → A
    Distance: 15 + 30 + 25 + 10 = 80 ✓ BEST!

Tour 5: A → D → B → C → A
    Distance: 20 + 25 + 35 + 15 = 95

Tour 6: A → D → C → B → A
    Distance: 20 + 30 + 35 + 10 = 95

Optimal Tour: A → B → D → C → A (or reverse)
Optimal Distance: 80
                

Note: For n=4 cities, there are (4-1)!/2 = 3 unique tours

Number of Possible Tours:

  • For n cities: (n-1)!/2 unique tours
  • n=4: 3 tours
  • n=5: 12 tours
  • n=10: 181,440 tours
  • n=20: 60,822,550,204,416,000 tours!
  • Grows factorially - exponential explosion!

Example 2: Geometric TSP (Cities on Plane)

Cities with (x,y) coordinates:
    A = (0, 0)
    B = (3, 0)
    C = (3, 4)
    D = (0, 4)

This forms a rectangle!

Calculate Euclidean distances:
    d(A,B) = √[(3-0)² + (0-0)²] = 3
    d(B,C) = √[(3-3)² + (4-0)²] = 4
    d(C,D) = √[(0-3)² + (4-4)²] = 3
    d(D,A) = √[(0-0)² + (4-0)²] = 4
    d(A,C) = √[(3-0)² + (4-0)²] = 5
    d(B,D) = √[(0-3)² + (4-0)²] = 5

Compare tours:
    A → B → C → D → A: 3 + 4 + 3 + 4 = 14 ✓ OPTIMAL
    A → B → D → C → A: 3 + 5 + 3 + 5 = 16
    A → C → B → D → A: 5 + 4 + 5 + 4 = 18

Optimal: Follow rectangle perimeter = 14
                

Algorithms for TSP:

1. Exact Algorithms:

Algorithm Time Complexity Description
Brute Force O(n!) Try all permutations
Dynamic Programming (Held-Karp) O(n²2ⁿ) Better but still exponential
Branch and Bound O(n!) worst case Prunes search space

Brute Force Algorithm:

TSP_BruteForce(cities[], dist[][]):
    min_distance = ∞
    best_tour = null
    
    for each permutation P of cities:
        current_distance = 0
        for i = 0 to n-1:
            current_distance += dist[P[i]][P[(i+1) % n]]
        
        if current_distance < min_distance:
            min_distance = current_distance
            best_tour = P
    
    return (best_tour, min_distance)

Time Complexity: O(n!) - try all (n-1)! tours
Space: O(n)
Practical limit: ~15 cities
                

2. Approximation Algorithms:

Nearest Neighbor Heuristic:

Greedy approach: Always go to nearest unvisited city

NearestNeighbor(start_city):
    current = start_city
    visited = {start_city}
    tour = [start_city]
    total_distance = 0
    
    while visited.size < n:
        nearest = city with minimum dist[current][city]
                  where city not in visited
        tour.append(nearest)
        visited.add(nearest)
        total_distance += dist[current][nearest]
        current = nearest
    
    total_distance += dist[current][start_city]  // Return home
    return (tour, total_distance)

Time Complexity: O(n²)
Approximation: No guarantee (can be arbitrarily bad!)
                

Example with 4 cities:

Start at A:
    Nearest to A: B (distance 10)
    Nearest to B: D (distance 25, C=35)
    Nearest to D: C (distance 30, only unvisited)
    Return to A: distance 15
    
Tour: A → B → D → C → A
Total: 10 + 25 + 30 + 15 = 80 ✓ (happens to be optimal!)

Note: Nearest neighbor doesn't always find optimal!
                

2-Approximation Algorithm (MST-based):

For metric TSP: Guarantees tour ≤ 2 × optimal

Algorithm:
1. Find Minimum Spanning Tree (MST) of cities
2. Do DFS traversal of MST (visits each edge twice)
3. Create shortcut tour by skipping repeated vertices

Guarantee: Tour length ≤ 2 × OPT
Time: O(n² log n) using Prim's algorithm

Why it works:
- MST cost ≤ OPT (removing one edge from optimal tour gives spanning tree)
- DFS traversal = 2 × MST cost
- Shortcuts only reduce distance (triangle inequality)
- Therefore: Final tour ≤ 2 × MST ≤ 2 × OPT
                

Christofides Algorithm (1.5-approximation):

Best known approximation for metric TSP

Algorithm:
1. Find MST of graph
2. Find vertices with odd degree in MST
3. Find minimum-weight perfect matching on odd-degree vertices
4. Combine MST and matching to form Eulerian graph
5. Find Eulerian tour
6. Convert to Hamiltonian tour by skipping repeated vertices

Guarantee: Tour length ≤ 1.5 × OPT
Time: O(n³)

This is the best known polynomial-time approximation!
                

Special Cases:

TSP Variant Constraint Complexity
Euclidean TSP Points in 2D plane with Euclidean distance NP-Hard but admits PTAS
Metric TSP Distances satisfy triangle inequality NP-Hard, 1.5-approximation exists
Asymmetric TSP d(i,j) ≠ d(j,i) Generally harder
Bottleneck TSP Minimize maximum edge in tour Can be solved in O(n² log n)

Applications:

  • Logistics: Delivery route optimization (FedEx, Amazon)
  • Manufacturing: PCB drilling, robot arm movement
  • DNA Sequencing: Fragment assembly
  • Astronomy: Telescope observation scheduling
  • Microchip Production: X-ray crystallography
  • Network Design: Laying fiber optic cables

Real-World Solutions:

  • Concorde TSP Solver: Solved 85,900 city instance!
  • LKH (Lin-Kernighan-Helsgaun): State-of-the-art heuristic
  • Genetic Algorithms: Good for large instances
  • Simulated Annealing: Escapes local optima
  • Ant Colony Optimization: Nature-inspired approach

Comparison with Hamiltonian Cycle:

Feature Hamiltonian Cycle TSP
Goal Find ANY cycle visiting all vertices Find SHORTEST such cycle
Type Decision problem Optimization problem
Complexity NP-Complete NP-Hard
Distances Not considered Central to problem
Approximation N/A (yes/no answer) Various algorithms exist

Important Facts:

  • TSP is NP-Hard (optimization) and NP-Complete (decision version)
  • No polynomial-time exact algorithm known (unless P=NP)
  • Christofides gives 1.5-approximation for metric TSP
  • Euclidean TSP admits PTAS (1+ε approximation)
  • General TSP cannot be approximated within any constant factor (unless P=NP)
  • Modern solvers can handle thousands of cities
  • Record: Largest solved instance has 85,900 cities!

Why TSP is Important:

  • Fundamental problem in optimization
  • Benchmark for algorithm development
  • Many real-world problems reduce to TSP
  • Drives research in approximation algorithms
  • Tests limits of computational methods