পাঠ ৪২ · ৪৪-এর মধ্যে · মডিউল ৮
Home / Courses / Discrete Mathematics / P বনাম NP

P বনাম NP ও NP-সম্পূর্ণতা পরিচিতি

P vs NP & introduction to NP-completeness
৯ মিনিট পড়া মধ্যবর্তী · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • Class P ও Class NP-এর সঠিক সংজ্ঞা এবং কেন $P \subseteq NP$
  • P = NP প্রশ্নটি কী এবং কেন এটি এত গুরুত্বপূর্ণ
  • NP-সম্পূর্ণতার ধারণা ও তিনটি ক্লাসিক উদাহরণ (SAT, TSP, গ্রাফ কালারিং)
  • "যাচাই করা সহজ, সমাধান করা কঠিন" — এই পার্থক্য কোডে সরাসরি দেখা
  • একটি সমস্যা NP-সম্পূর্ণ চিহ্নিত হলে ব্যবহারিকভাবে কী করা উচিত

১ · Class P — দক্ষভাবে সমাধানযোগ্য

Class PClass P (Polynomial time)এমন সমস্যার শ্রেণি যা একটি ডিটারমিনিস্টিক অ্যালগরিদম দিয়ে $O(n^k)$ সময়ে ($k$ একটি ধ্রুবক) সমাধান করা যায়।-তে সেই সব সমস্যা পড়ে যা একটি ডিটারমিনিস্টিক অ্যালগরিদম দিয়ে পলিনমিয়াল সময়ে ($O(n^k)$, $k$ একটি ধ্রুবক) সমাধান করা যায়। L39-এর ভাষায়: O(1), O(log n), O(n), O(n log n), O(n²), O(n³) — এই সবগুলো ক্লাসের সমস্যাই P-এর অন্তর্ভুক্ত। উদাহরণ: sorting, searching, shortest path খোঁজা (graph traversal) — সবই P-তে।

২ · Class NP — দ্রুত যাচাইযোগ্য

Class NPClass NP (Nondeterministic Polynomial time)এমন সমস্যার শ্রেণি যেখানে একটি প্রস্তাবিত সমাধান দেওয়া থাকলে, তা সঠিক কি না তা পলিনমিয়াল সময়ে যাচাই করা যায় — সমাধান খোঁজাটা যত কঠিনই হোক না কেন।-এর সংজ্ঞা ভিন্ন কোণ থেকে — একটি সমস্যা NP-তে পড়ে যদি তার জন্য একটি প্রস্তাবিত সমাধান (candidate solution) দেওয়া থাকলে, সেটি সঠিক কি না তা পলিনমিয়াল সময়ে যাচাই করা যায় — এমনকি যদি সেই সমাধান খুঁজে বের করা অনেক বেশি সময় নেয়। যেমন একটি ৯×৯ সুডোকুর পূর্ণ সমাধান দেওয়া থাকলে তা সঠিক কি না চেক করা তাৎক্ষণিক — কিন্তু শূন্য থেকে সমাধান খোঁজা অনেক কঠিন।

কেন $P \subseteq NP$

যদি কোনো সমস্যা P-তে থাকে (অর্থাৎ পলিনমিয়াল সময়ে সমাধান করা যায়), তাহলে একটি প্রস্তাবিত সমাধান পাওয়া গেলে সেটিকে যাচাই করার সবচেয়ে সহজ উপায় হলো — নিজে থেকেই সমস্যাটি সমাধান করে ফেলা (পলিনমিয়াল সময়ে) এবং ফলাফল মিলিয়ে দেখা। তাই যা কিছু দ্রুত সমাধান করা যায়, তার প্রস্তাবিত উত্তরও ত্রিভিয়ালি দ্রুত যাচাই করা যায় — অর্থাৎ $P \subseteq NP$।

৩ · খোলা প্রশ্ন — P = NP?

প্রশ্নটি সহজ শোনায়: যা কিছু দ্রুত যাচাই করা যায়, তা কি সবসময় দ্রুত সমাধানও করা যায়? অর্থাৎ $P = NP$? এটি কম্পিউটার সায়েন্স তথা গণিতের সবচেয়ে বিখ্যাত অমীমাংসিত সমস্যাগুলোর একটি — Clay Mathematics Institute-এর সাতটি "Millennium Prize Problem"-এর একটি, যার সমাধানের জন্য \$১০ লক্ষ পুরস্কার ঘোষিত। বেশিরভাগ কম্পিউটার বিজ্ঞানী বিশ্বাস করেন $P \ne NP$ (অর্থাৎ কিছু সমস্যা যাচাই করা সহজ কিন্তু সমাধান করা মৌলিকভাবেই কঠিন), কিন্তু আজ পর্যন্ত এটি প্রমাণিত হয়নি।

৪ · NP-সম্পূর্ণতা — NP-এর সবচেয়ে কঠিন সমস্যা

NP-সম্পূর্ণ (NP-complete)NP-completeNP-এর এমন সমস্যা যার জন্য কোনো পলিনমিয়াল-সময় অ্যালগরিদম পাওয়া গেলে, NP-এর প্রতিটি সমস্যাই পলিনমিয়াল সময়ে সমাধানযোগ্য হয়ে যাবে (অর্থাৎ P=NP প্রমাণিত হবে)। সমস্যাগুলো হলো NP-এর "সবচেয়ে কঠিন" সমস্যা — যদি এদের মধ্যে যেকোনো একটির জন্য একটি পলিনমিয়াল-সময় অ্যালগরিদম পাওয়া যেত, তাহলে NP-এর প্রতিটি সমস্যাই পলিনমিয়াল সময়ে সমাধানযোগ্য হয়ে যেত (অর্থাৎ $P=NP$ প্রমাণিত হতো)। কয়েকটি ক্লাসিক উদাহরণ —

SAT (Boolean Satisfiability)
একটি বুলিয়ান ফর্মুলাকে সন্তুষ্ট করা এমন কোনো ভ্যারিয়েবল অ্যাসাইনমেন্ট আছে কি না। এটিই প্রথম প্রমাণিত NP-সম্পূর্ণ সমস্যা — Cook-Levin থিওরেম (১৯৭১)।
Traveling Salesman (decision version)
"সব শহর ভ্রমণ করে একটি নির্দিষ্ট দৈর্ঘ্যের চেয়ে কম দূরত্বে ফেরত আসা সম্ভব কি?" — L44-এ পুনরায় দেখা যাবে।
গ্রাফ $k$-কালারিং ($k\ge3$)
L22-তে দেখা গ্রাফ কালারিং — $k=2$ (bipartite চেক) P-তে, কিন্তু $k\ge3$ হলেই এটি NP-সম্পূর্ণ হয়ে যায়।
লক্ষণীয় — গ্রাফ কালারিং উদাহরণটি দেখায় সমস্যার সামান্য পরিবর্তনও (২ রঙ বনাম ৩ রঙ) জটিলতা ক্লাসকে P থেকে NP-সম্পূর্ণে ঠেলে দিতে পারে। এই সূক্ষ্ম সীমারেখা চেনাটাই একজন দক্ষ প্রোগ্রামারের গুরুত্বপূর্ণ দক্ষতা।

৫ · ব্যবহারিক শিক্ষা

যখন কোনো সমস্যাকে NP-সম্পূর্ণ হিসেবে চেনা যায়, তখন একটি দ্রুত, সঠিক (exact) অ্যালগরিদম খোঁজায় সময় নষ্ট না করে বরং এই পথগুলো বিবেচনা করা উচিত — approximation algorithm (কাছাকাছি উত্তর, নিশ্চিত সময়ে), heuristic (বেশিরভাগ ক্ষেত্রে ভালো কাজ করে এমন কৌশল, গ্যারান্টি ছাড়া), অথবা সমস্যাটিকে একটি বিশেষ, সহজ কেসে সীমাবদ্ধ করা (যেমন ইনপুট সাইজ ছোট রাখা)।

৬ · কোড: যাচাই সহজ, সমাধান কঠিন

Python
import itertools

# একটি বুলিয়ান ফর্মুলা (৩টি ভ্যারিয়েবল a, b, c):
# (a OR b) AND (NOT b OR c) AND (a OR NOT c)
def formula(a, b, c):
    return (a or b) and ((not b) or c) and (a or (not c))

# ধাপ ১ — ভেরিফিকেশন সহজ (O(1) ফর্মুলা-মূল্যায়ন):
# একটি candidate assignment দেওয়া থাকলে তা যাচাই করতে ফর্মুলাটি শুধু একবার চালাতে হয়
candidate = {"a": True, "b": False, "c": True}
is_satisfied = formula(candidate["a"], candidate["b"], candidate["c"])
print("Candidate assignment:", candidate)
print("এই assignment ফর্মুলাটি সন্তুষ্ট করে কি না:", is_satisfied)

# ধাপ ২ — সমাধান খোঁজা কঠিন: brute force-এ সব 2^k সম্ভাব্য assignment পরীক্ষা করতে হয়
k = 3
tried = 0
satisfying = []
for values in itertools.product([True, False], repeat=k):
    tried += 1
    a, b, c = values
    if formula(a, b, c):
        satisfying.append(values)

print(f"\nমোট {tried} = 2^{k} টি combination brute-force-এ পরীক্ষা করা হলো")
print("সন্তুষ্টকারী assignment(গুলো):", satisfying)
print(f"লক্ষ করুন: k={k} ভ্যারিয়েবলের জন্য brute force-এ 2^{k}={2**k}টি চেষ্টা লাগলো —")
print("k বাড়লে (যেমন k=50) এই সংখ্যা এক্সপোনেনশিয়ালভাবে অসম্ভব হয়ে যাবে, যদিও যাচাই সবসময়ই O(1)।")

    

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

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

প্র ০১ "দ্রুত যাচাইযোগ্য" কেন "দ্রুত সমাধানযোগ্য"-কে বোঝায় না — একটি সহজ, স্বজ্ঞাত (intuitive) উদাহরণ দিন।

একটি ৯×৯ সুডোকু পাজলের কথা ভাবুন (সাধারণীকৃত $n\times n$ সংস্করণ NP-সম্পূর্ণ)। একটি সম্পূর্ণ ভরা গ্রিড দেওয়া হলে, প্রতিটি সারি/কলাম/বক্সে ১-৯ ঠিক একবার আছে কি না চেক করা কয়েক মিলিসেকেন্ডের ব্যাপার — সরাসরি, পলিনমিয়াল সময়ে। কিন্তু একটি খালি (বা আংশিক ভরা) গ্রিড থেকে সেই সমাধান খুঁজে বের করা সম্পূর্ণ ভিন্ন সমস্যা — এখানে সম্ভাব্য অ্যাসাইনমেন্টের সংখ্যা এত বেশি যে brute force ব্যবহারিকভাবে অসম্ভব। "চেক করা সহজ" আর "খুঁজে বের করা সহজ" — সম্পূর্ণ ভিন্ন প্রশ্ন।

প্র ০২ L22-এর গ্রাফ কালারিং-এ $k=2$ (bipartite চেক) P-তে, কিন্তু $k\ge3$ NP-সম্পূর্ণ কেন — এই সূক্ষ্ম সীমারেখাটি ব্যাখ্যা করুন।

$k=2$-এর জন্য একটি সহজ, দ্রুত পরীক্ষা আছে — L22-তে দেখা থিওরেম: একটি গ্রাফ ২-রঙে রঙ করা যায় (bipartite) ঠিক তখনই যখন এতে কোনো odd cycle নেই, এবং এটি একটি সাধারণ BFS/DFS দিয়ে $O(V+E)$ সময়ে চেক করা যায় — কোনো brute force দরকার নেই। কিন্তু $k=3$-এর জন্য এমন কোনো সহজ কাঠামোগত থিওরেম পাওয়া যায়নি — এবং প্রমাণিত হয়েছে এটি NP-সম্পূর্ণ। এই একক সংখ্যার পার্থক্য ($k=2$ বনাম $k=3$) সমস্যার মৌলিক কাঠামোকে সম্পূর্ণ বদলে দেয়।

প্র ০৩ কেউ যদি দাবি করে সে SAT-এর জন্য একটি পলিনমিয়াল-সময় অ্যালগরিদম বের করেছে, এর মানে কী দাঁড়াবে?

SAT NP-সম্পূর্ণ (Cook-Levin থিওরেম, ১৯৭১) — অর্থাৎ NP-এর প্রতিটি সমস্যা পলিনমিয়াল সময়ে SAT-এ রূপান্তরযোগ্য (reduction)। তাই SAT-এর একটি পলিনমিয়াল-সময় সমাধান থাকলে, NP-এর যেকোনো সমস্যাকে প্রথমে SAT-এ রূপান্তর করে (পলিনমিয়াল সময়ে), তারপর সেই দ্রুত SAT সমাধানকারী চালিয়ে সমাধান করা যেত — অর্থাৎ NP-এর প্রতিটি সমস্যাই পলিনমিয়াল সময়ে সমাধানযোগ্য হয়ে যেত। এর মানে $P=NP$ প্রমাণিত হয়ে যেত — কম্পিউটার সায়েন্সের সবচেয়ে বড় খবর হতো, এবং RSA-এর মতো (L28) ক্রিপ্টোগ্রাফিক পদ্ধতির নিরাপত্তার ভিত্তিও নড়ে যেত।

অনুশীলন

  1. পরীক্ষা করুন: কোড সেলে formula-কে এমনভাবে বদলান যাতে কোনো assignment-ই একে সন্তুষ্ট না করে (যেমন return a and (not a))। Run চাপুন — brute force কী বলে?

    satisfying লিস্টটি খালি থাকবে — brute force সব ৮টি combination চেক করে নিশ্চিত করবে কোনোটিই ফর্মুলাটি সন্তুষ্ট করে না (একটি "unsatisfiable" ফর্মুলা)। এটিও যাচাই করাই — brute force এখানেও পলিনমিয়াল সময়ে সমাধান করেনি, বরং সবগুলো সম্ভাবনা exhaustively চেক করেছে।

  2. চিন্তা করুন: আপনার পরিচিত কোনো বাস্তব সমস্যা (যেমন পরীক্ষার রুটিন তৈরি, ডেলিভারি রুট প্ল্যানিং) NP-সম্পূর্ণ-স্বাদের মনে হয় কেন?

    পরীক্ষার রুটিন তৈরি (exam timetabling) — একাধিক শিক্ষার্থী একাধিক পরীক্ষায় বসে, কোনো দুটি পরীক্ষা একই সময়ে হতে পারবে না যদি কোনো শিক্ষার্থী উভয়টিতে থাকে — এটি মূলত গ্রাফ কালারিং সমস্যার একটি রূপ (প্রতিটি পরীক্ষা একটি নোড, শেয়ার্ড শিক্ষার্থী থাকলে একটি edge, "রঙ" = টাইম স্লট)। যেহেতু সাধারণ গ্রাফ কালারিং ($k\ge3$) NP-সম্পূর্ণ, বাস্তব বড় স্কুল/বিশ্ববিদ্যালয়ে এই সমস্যা সমাধানে heuristic ব্যবহার করা হয়, perfect optimal সমাধান নয়।

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

পূর্ববর্তী পাঠ
রিকার্সিভ অ্যালগরিদমের জটিলতা