পাঠ ৪৪ · ৫৬-এর মধ্যে · মডিউল ১০
Home / Courses / Formal Language & Automata Theory / Theory of Computation / ক্লাস NP ও ভেরিফায়ার

ক্লাস NP ও ভেরিফায়ার

The class NP & verifiers
৮ মিনিট পড়া উচ্চ · Advanced Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • NP-এর ভেরিফায়ার-ভিত্তিক ফরমাল সংজ্ঞা — সার্টিফিকেট ও পলিনমিয়াল-টাইম ভেরিফিকেশন
  • NP-এর নন-ডিটারমিনিস্টিক-TM ভিত্তিক সংজ্ঞা এবং দুটি সংজ্ঞার সমতুল্যতার স্বজ্ঞা
  • SAT কেন NP-তে — একটি সত্যিকারের Python ভেরিফায়ার দিয়ে দেখা
  • $\mathrm{P} \subseteq \mathrm{NP}$ কেন সহজে প্রমাণযোগ্য, এবং P-vs-NP প্রশ্নের প্রথম আভাস

১ · NP — ভেরিফায়ার সংজ্ঞা

একটি ল্যাঙ্গুয়েজ $L$ NPNondeterministic Polynomial time-তে থাকে যদি একটি পলিনমিয়াল-টাইম ভেরিফায়ার $V$ ও একটি পলিনমিয়াল বাউন্ড $p(n)$ থাকে, যাতে —

$$w \in L \iff \exists \text{ certificate } c \text{ with } |c| \leq p(|w|) \text{ such that } V(w, c) \text{ accepts}$$

অর্থাৎ, NP-এর ল্যাঙ্গুয়েজগুলো এমন — যদি উত্তর "হ্যাঁ" হয়, তাহলে একটি সংক্ষিপ্ত (পলিনমিয়াল-length) "প্রমাণ"/সার্টিফিকেট আছে যা দ্রুত চেক করা যায় — এমনকি যদি সেই সার্টিফিকেট খুঁজে বের করা কঠিন হয়। এটিই NP-এর সবচেয়ে গুরুত্বপূর্ণ, ব্যবহারিক অন্তর্দৃষ্টি — "খুঁজে বের করা কঠিন, যাচাই করা সহজ।"

২ · NP — নন-ডিটারমিনিস্টিক TM সংজ্ঞা ও সমতুল্যতা

সমতুল্যভাবে (M8/L36-এর NTM ধারণার সরাসরি পুনর্ব্যবহার): $L \in \mathrm{NP}$ যদি কোনো নন-ডিটারমিনিস্টিক TM $L$-কে পলিনমিয়াল সময়ে ডিসাইড করে — এখানে "নন-ডিটারমিনিস্টিক সময়" মানে সবচেয়ে দীর্ঘ accepting শাখার length (L36-এর branching-tree ফ্রেমিং-এর সরাসরি পুনর্ব্যবহার)।

দুই সংজ্ঞার সমতুল্যতার স্বজ্ঞা (intuition) সংক্ষেপে — একটি NTM-এর accepting শাখা (যে নির্দিষ্ট নন-ডিটারমিনিস্টিক পছন্দের সিকোয়েন্স accept-এ নিয়ে যায়) ঠিক একটি সার্টিফিকেট; উল্টোদিকে, একটি সার্টিফিকেট নন-ডিটারমিনিস্টিকভাবে "গেস" করে তারপর ডিটারমিনিস্টিকভাবে ভেরিফাই করলেই একটি NTM পাওয়া যায়।

NP সংক্ষিপ্ত সার্টিফিকেট আছে, দ্রুত যাচাইযোগ্য P পলিনমিয়াল সময়ে সরাসরি সমাধানযোগ্য P ⊆ NP — স্ট্রিক্ট কি না, তা এখনও অজানা (L49)
P-এর প্রতিটি ল্যাঙ্গুয়েজই NP-তে (সার্টিফিকেট উপেক্ষা করে সরাসরি সমাধান চালানো যায়) — কিন্তু containment স্ট্রিক্ট কি না তা অজানা।

৩ · উদাহরণ — SAT NP-তে

SATBoolean Satisfiabilityএকটি বুলিয়ান ফর্মুলার ভেরিয়েবলগুলোতে TRUE/FALSE বসিয়ে ফর্মুলাটিকে TRUE করা যায় কি না (বুলিয়ান স্যাটিসফায়াবিলিটি) — একটি প্রদত্ত বুলিয়ান ফর্মুলার ভেরিয়েবলগুলোতে এমন কোনো TRUE/FALSE অ্যাসাইনমেন্ট আছে কি না যা পুরো ফর্মুলাকে TRUE করে? SAT NP-তে, কারণ সার্টিফিকেট হলো একটি প্রস্তাবিত অ্যাসাইনমেন্ট (পলিনমিয়াল length — প্রতি ভেরিয়েবলে এক বিট), আর সেটি যাচাই করা (ফর্মুলায় বসিয়ে মূল্যায়ন করা) মাত্র পলিনমিয়াল সময়ে সম্ভব — যদিও সার্টিফিকেট হাতে না পেয়ে একটি সন্তোষজনক অ্যাসাইনমেন্ট খুঁজে বের করা অনেক বেশি কঠিন বলে বিশ্বাস করা হয় (L46-এর কুক-লেভিন থিওরেমের সরাসরি foreshadowing, যা দেখাবে SAT শুধু NP-তে নয়, বরং একটি সুনির্দিষ্ট অর্থে NP-এর সবচেয়ে কঠিন সমস্যাগুলোর একটি)।

৪ · P ⊆ NP

একটি সহজ কিন্তু গুরুত্বপূর্ণ পর্যবেক্ষণ — প্রতিটি পলিনমিয়াল-সময়ে-ডিসাইডেবল ল্যাঙ্গুয়েজ ($\mathrm{P}$-তে) একইসাথে পলিনমিয়াল-সময়ে-যাচাইযোগ্যও ($\mathrm{NP}$-তে) — সার্টিফিকেটকে সম্পূর্ণ উপেক্ষা করে সরাসরি P-এর অ্যালগরিদম চালালেই হয়। তাই $\mathrm{P} \subseteq \mathrm{NP}$। এই containment স্ট্রিক্ট ($\mathrm{P} \subsetneq \mathrm{NP}$) নাকি আসলে সমতা ($\mathrm{P} = \mathrm{NP}$) — এটিই L49-এর বিখ্যাত, এখনও-অমীমাংসিত প্রশ্ন, কম্পিউটার সায়েন্সের একক সবচেয়ে বিখ্যাত খোলা সমস্যা।

Python
# SAT ভেরিফায়ার (পলিনমিয়াল-টাইম, eval()/exec()/re ছাড়াই -- সরাসরি nested-tuple structure মূল্যায়ন)

def eval_formula(node, assignment):
    if isinstance(node, str):
        return assignment[node]          # একটি ভেরিয়েবলের নাম
    op = node[0]
    if op == 'not':
        return not eval_formula(node[1], assignment)
    if op == 'and':
        return eval_formula(node[1], assignment) and eval_formula(node[2], assignment)
    if op == 'or':
        return eval_formula(node[1], assignment) or eval_formula(node[2], assignment)
    raise ValueError(f"অজানা অপারেটর: {op}")

def verify_sat(formula, assignment):
    # সার্টিফিকেট (assignment) দেওয়া থাকলে, ফর্মুলাটি সন্তুষ্ট হয় কি না -- লিনিয়ার সময়ে যাচাই
    return eval_formula(formula, assignment)

# formula = x3 AND (x1 OR NOT x2)
formula = ('and', ('or', 'x1', ('not', 'x2')), 'x3')

satisfying_assignment = {'x1': True, 'x2': True, 'x3': True}
unsatisfying_assignment = {'x1': True, 'x2': True, 'x3': False}

print("সন্তোষজনক অ্যাসাইনমেন্ট:", satisfying_assignment)
print("verify_sat ফলাফল:", verify_sat(formula, satisfying_assignment), "(প্রত্যাশিত: True)")
print()
print("অসন্তোষজনক অ্যাসাইনমেন্ট:", unsatisfying_assignment)
print("verify_sat ফলাফল:", verify_sat(formula, unsatisfying_assignment), "(প্রত্যাশিত: False)")

# ---- ব্রুট-ফোর্স SAT সলভার -- জেনুইনভাবে সঠিক, কিন্তু এক্সপোনেনশিয়াল (সব 2^n সম্ভাব্য অ্যাসাইনমেন্ট চেষ্টা করে) ----
import itertools

def brute_force_sat(formula, variables):
    for bits in itertools.product([False, True], repeat=len(variables)):
        assignment = dict(zip(variables, bits))
        if verify_sat(formula, assignment):
            return assignment
    return None   # কোনো সন্তোষজনক অ্যাসাইনমেন্ট নেই

variables = ['x1', 'x2', 'x3']
found = brute_force_sat(formula, variables)
print()
print(f"brute_force_sat 2^{len(variables)} = {2**len(variables)}টি অ্যাসাইনমেন্ট চেষ্টা করে খুঁজে পেল:", found)
print("cross-check: verify_sat দিয়ে এই পাওয়া অ্যাসাইনমেন্ট যাচাই:", verify_sat(formula, found))

    
লক্ষ্য করুন verify_sat লিনিয়ার সময়ে (ফর্মুলার আকারে) চলে — নির্বিশেষে ভেরিয়েবল সংখ্যা যতই হোক। কিন্তু brute_force_sat-কে ভেরিয়েবল সংখ্যা $n$-এর জন্য $2^n$টি সম্ভাব্য অ্যাসাইনমেন্ট চেষ্টা করতে হয় — ঠিক L43-এর এক্সপোনেনশিয়াল-গ্রোথের বাস্তব উদাহরণ। এটিই NP-এর মূল বার্তা — যাচাই দ্রুত, কিন্তু (এই ব্রুট-ফোর্স পদ্ধতিতে) খুঁজে বের করা ধীর।
মূল কথা · Key takeaway

NP হলো সেইসব ল্যাঙ্গুয়েজের ক্লাস যেখানে "হ্যাঁ" উত্তরের একটি সংক্ষিপ্ত, দ্রুত-যাচাইযোগ্য সার্টিফিকেট থাকে — SAT এর ধ্রুপদী উদাহরণ। $\mathrm{P} \subseteq \mathrm{NP}$ সহজেই প্রমাণযোগ্য, কিন্তু এই containment স্ট্রিক্ট কি না তা এখনও অমীমাংসিত। পরের পাঠে (L45) আমরা দেখব কীভাবে সমস্যাগুলোর কঠিনতা একে অপরের সাথে রিডাকশন-এর মাধ্যমে তুলনা করা যায় — এবং সেখান থেকেই NP-কমপ্লিটনেসের ধারণা আসবে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ "NP" নামের অর্থ কি "Not Polynomial" (পলিনমিয়াল নয়)? এটি একটি সাধারণ ভুল ধারণা — সঠিক ব্যাখ্যা কী?

না, এটি একটি সাধারণ ভুল ধারণা। NP মানে "Nondeterministic Polynomial time" — নন-ডিটারমিনিস্টিক TM দিয়ে পলিনমিয়াল সময়ে ডিসাইডযোগ্য। এটি "পলিনমিয়াল নয়" বোঝায় না — বরং $\mathrm{P} \subseteq \mathrm{NP}$ থিওরেম অনুযায়ী প্রতিটি P-ল্যাঙ্গুয়েজই NP-তেও আছে। NP-এর ভেতরেই এমন সমস্যা থাকতে পারে যেগুলো আসলে P-তেও আছে (যেমন গ্রাফ রিচেবিলিটি) — NP কেবল "পলিনমিয়াল-টাইম যাচাইযোগ্য" বোঝায়, "পলিনমিয়াল-টাইম সমাধানযোগ্য নয়" নয়।

প্র ০২ উপরের কোড সেলে brute_force_sat একটি সন্তোষজনক অ্যাসাইনমেন্ট খুঁজে পেলে, সেই ফলাফলকে verify_sat দিয়ে আবার যাচাই করার কী প্রয়োজন?

এটি একটি স্বাধীন সঠিকতা-চেক (correctness cross-check) — brute_force_sat এবং verify_sat সম্পূর্ণ ভিন্ন কোড-পথ (একটি সব সম্ভাবনা খুঁজে বেড়ায়, অন্যটি একটি নির্দিষ্ট অ্যাসাইনমেন্ট সরাসরি মূল্যায়ন করে) — তাই যদি দুটোই একমত হয় (উভয়ে True বলে), সেটি একটি জেনুইন, কোড-এক্সিকিউশন-ভিত্তিক নিশ্চয়তা দেয় যে পাওয়া সমাধানটি সত্যিই সঠিক, শুধু ধরে নেওয়া নয়। এটিই এই কোর্সের একটি নিয়ম — যেকোনো "খুঁজে পাওয়া" ফলাফল একটি স্বতন্ত্র ভেরিফায়ার দিয়ে ক্রস-চেক করা।

প্র ০৩ যদি কেউ দাবি করে "আমি এই SAT ফর্মুলার একটি সন্তোষজনক অ্যাসাইনমেন্ট পেয়েছি," তাহলে আপনি সেই দাবি কতক্ষণে যাচাই করতে পারবেন — ফর্মুলা যতই বড় বা জটিল হোক না কেন?

পলিনমিয়াল সময়ে — আসলে verify_sat/eval_formula ফর্মুলার আকারে (নোডের সংখ্যায়) লিনিয়ার সময়ে চলে, প্রতিটি নোড ঠিক একবার মূল্যায়ন করা হয়। এটিই NP-এর সংজ্ঞাগত বৈশিষ্ট্য — দাবিকৃত সার্টিফিকেট যতই "খুঁজে বের করতে" কঠিন হোক না কেন, একবার হাতে পেলে তা যাচাই করা সবসময় দ্রুত, ফর্মুলার আকার নির্বিশেষে ভেরিয়েবল সংখ্যায় এক্সপোনেনশিয়াল নয়।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোড সেলে formula-টি এমনভাবে পরিবর্তন করুন যাতে এটি কোনো অ্যাসাইনমেন্টেই সন্তুষ্ট না হয় (একটি unsatisfiable ফর্মুলা, যেমন ('and', 'x1', ('not', 'x1')))। Run চেপে দেখুন brute_force_sat কী ফেরত দেয়।

    ('and', 'x1', ('not', 'x1')) কখনোই সন্তুষ্ট হতে পারে না — x1 এবং NOT x1 একসাথে কখনোই True হতে পারে না। তাই brute_force_sat সব সম্ভাব্য অ্যাসাইনমেন্ট (এখানে x1 একমাত্র ভেরিয়েবল হলে ২টি) চেষ্টা করেও কোনোটাই সন্তুষ্ট করতে না পেরে None ফেরত দেবে — সঠিকভাবে চিহ্নিত করে যে ফর্মুলাটি unsatisfiable।

  2. চিন্তা করুন: ধরুন একটি ভেরিফায়ার $V$ পলিনমিয়াল সময়ে চলে, কিন্তু সার্টিফিকেটের length ইনপুট length-এর এক্সপোনেনশিয়াল — এই ল্যাঙ্গুয়েজ কি এখনও NP-এর সংজ্ঞা পূরণ করে? কেন বা কেন নয়?

    না — NP-এর সংজ্ঞায় সার্টিফিকেটের length স্পষ্টভাবে ইনপুট length-এ পলিনমিয়ালভাবে বাউন্ডেড হতে হবে ($|c| \leq p(|w|)$)। যদি সার্টিফিকেট এক্সপোনেনশিয়ালি বড় হতে পারে, তাহলে শুধু সার্টিফিকেটটি পড়তেই এক্সপোনেনশিয়াল সময় লাগবে, তাই পুরো ভেরিফিকেশন প্রক্রিয়া (V-এর নিজস্ব পলিনমিয়াল-টাইম হওয়া সত্ত্বেও) সামগ্রিকভাবে পলিনমিয়াল থাকবে না — এই শর্তটি NP-এর সংজ্ঞার একটি অপরিহার্য অংশ।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
L43 · টাইম কমপ্লেক্সিটি ও ক্লাস P