बहुपद समय और छद्म एकात्मक समय के बीच के अंतर को समझने के लिए, हमें "बहुपद समय" का अर्थ क्या है, यह औपचारिक रूप से शुरू करना होगा।
बहुपद समय के लिए सामान्य अंतर्ज्ञान "समय ओ (एन के ) कुछ कश्मीर के लिए है।" उदाहरण के लिए, चयन सॉर्ट समय O (n 2 ) में चलता है , जो बहुपद समय है, जबकि जानवर बल TSP को हल करने में समय O (n · n!) लगता है, जो बहुपद समय नहीं है।
ये रनटाइम सभी कुछ चर n को संदर्भित करते हैं जो इनपुट के आकार को ट्रैक करते हैं। उदाहरण के लिए, चयन प्रकार में, n सरणी में तत्वों की संख्या को संदर्भित करता है, जबकि TSP n में ग्राफ में नोड की संख्या को संदर्भित करता है। इस संदर्भ में वास्तव में "n" की परिभाषा को मानक बनाने के लिए, समय जटिलता की औपचारिक परिभाषा एक समस्या के "आकार" को परिभाषित करती है:
किसी समस्या के लिए इनपुट का आकार उस इनपुट को लिखने के लिए आवश्यक बिट्स की संख्या है।
उदाहरण के लिए, यदि छँटाई एल्गोरिथ्म के लिए इनपुट 32-बिट पूर्णांक का एक सरणी है, तो इनपुट का आकार 32n होगा, जहां n सरणी में प्रविष्टियों की संख्या है। N नोड्स और एम किनारों के साथ एक ग्राफ में, इनपुट को सभी नोड्स की सूची के बाद सभी किनारों की सूची के रूप में निर्दिष्ट किया जा सकता है, जिसके लिए Ω (n + m) बिट्स की आवश्यकता होगी।
इस परिभाषा को देखते हुए, बहुपद समय की औपचारिक परिभाषा निम्नलिखित है:
एक एल्गोरिथ्म बहुपद समय में चलता है यदि इसका रनटाइम O (x k ) कुछ स्थिर कश्मीर के लिए है, जहां x एल्गोरिथम को दिए गए इनपुट के बिट्स की संख्या को दर्शाता है।
ग्राफ़िक्स, सूचियों, पेड़ों आदि को प्रोसेस करने वाले एल्गोरिदम के साथ काम करते समय, यह परिभाषा कमोबेश पारंपरिक परिभाषा से सहमत है। उदाहरण के लिए, मान लें कि आपके पास एक सॉर्टिंग एल्गोरिदम है जो 32-बिट पूर्णांक के सरणियों को सॉर्ट करता है। यदि आप ऐसा करने के लिए चयन प्रकार की तरह कुछ का उपयोग करते हैं, तो रनटाइम, सरणी में इनपुट तत्वों की संख्या के एक फ़ंक्शन के रूप में, ओ (एन 2 ) होगा। लेकिन n कैसे इनपुट सरणी में तत्वों की संख्या, इनपुट के बिट्स की संख्या के अनुरूप है? जैसा कि पहले उल्लेख किया गया है, इनपुट की बिट्स की संख्या x = 32n होगी। इसलिए, यदि हम n के बजाय x के संदर्भ में एल्गोरिथ्म के रनटाइम को व्यक्त करते हैं, तो हमें पता चलता है कि रनटाइम O (x 2 ) है, और इसलिए एल्गोरिथ्म बहुपद समय में चलता है।
इसी तरह, मान लीजिए कि आप एक ग्राफ पर गहराई-पहली खोज करते हैं, जिसमें O (m + n) समय लगता है, जहां m ग्राफ में किनारों की संख्या है और n नोड्स की संख्या है। यह दिए गए इनपुट के बिट्स की संख्या से कैसे संबंधित है? ठीक है, अगर हम मानते हैं कि इनपुट को आसन्न सूची (सभी नोड्स और किनारों की एक सूची) के रूप में निर्दिष्ट किया गया है, तो जैसा कि पहले उल्लेख किया गया है कि इनपुट बिट्स की संख्या x = Ω (m + n) होगी। इसलिए, रनटाइम ओ (एक्स) होगा, इसलिए एल्गोरिथ्म बहुपद समय में चलता है।
हालांकि, चीजें टूट जाती हैं, जब हम संख्याओं पर काम करने वाले एल्गोरिदम के बारे में बात करना शुरू करते हैं। आइए परीक्षण की समस्या पर विचार करें कि कोई संख्या प्रधान है या नहीं। एक संख्या n को देखते हुए, आप परीक्षण कर सकते हैं कि क्या n निम्नलिखित एल्गोरिथ्म का उपयोग कर रहा है:
function isPrime(n):
for i from 2 to n - 1:
if (n mod i) = 0, return false
return true
तो इस कोड की समय जटिलता क्या है? ठीक है, कि आंतरिक लूप ओ (एन) बार चलता है और प्रत्येक बार एन मॉड आई की गणना करने के लिए कुछ मात्रा में काम करता है (वास्तव में रूढ़िवादी ऊपरी सीमा के रूप में, यह निश्चित रूप से ओ (एन 3 ) में किया जा सकता है )। इसलिए, यह समग्र एल्गोरिथ्म समय ओ (एन 4 ) में चलता है और संभवतः बहुत तेज है।
2004 में, तीन कंप्यूटर वैज्ञानिकों ने PRIMES नाम से एक पेपर प्रकाशित किया, जो कि एक संख्या के प्रमुख होने के परीक्षण के लिए एक बहुपद-कालिक एल्गोरिथम दे रहा है। इसे एक ऐतिहासिक परिणाम माना गया। तो कौन सी बड़ी बात है? क्या हमारे पास पहले से ही इसके लिए एक बहुपद-काल एल्गोरिदम नहीं है, अर्थात् ऊपर वाला?
दुर्भाग्य से, हम नहीं करते। याद रखें, समय जटिलता की औपचारिक परिभाषा एल्गोरिथ्म की जटिलता के बारे में बात करती है इनपुट के बिट्स की संख्या के एक फ़ंक्शन के रूप में। हमारा एल्गोरिथ्म समय O (n 4 ) में चलता है , लेकिन इनपुट बिट्स की संख्या के फ़ंक्शन के रूप में वह क्या है? खैर, संख्या n लिखना O (लॉग एन) बिट्स लेता है। इसलिए, यदि हम x को इनपुट n को लिखने के लिए आवश्यक बिट्स की संख्या बताते हैं, तो इस एल्गोरिथ्म का रनटाइम वास्तव में O (2 4x ) है, जो x में बहुपद नहीं है।
यह बहुपद समय और छद्म एकात्मक समय के बीच अंतर का दिल है। एक ओर, हमारा एल्गोरिथ्म हे (एन 4 ) है, जो एक बहुपद की तरह दिखता है, लेकिन दूसरी ओर, बहुपद समय की औपचारिक परिभाषा के तहत, यह बहुपद-समय नहीं है।
एल्गोरिथ्म एक बहुपद-समय एल्गोरिथ्म क्यों नहीं है के लिए एक अंतर्ज्ञान प्राप्त करने के लिए, निम्नलिखित के बारे में सोचें। मान लीजिए मैं चाहता हूं कि एल्गोरिथ्म को बहुत काम करना होगा। अगर मैं इस तरह से एक इनपुट लिखता हूं:
10001010101011
फिर इसे पूरा करने के लिए कुछ सबसे खराब समय लगेगा T
। यदि मैं अब संख्या के अंत में एक बिट जोड़ता हूं , तो इस तरह:
100010101010111
रनटाइम अब (सबसे खराब स्थिति में) 2T होगा। मैं एल्गोरिथ्म केवल एक और बिट जोड़कर काम की मात्रा को दोगुना कर सकता हूं!
एल्गोरिथ्म pseudopolynomial समय में चलता है यदि रनटाइम इनपुट के संख्यात्मक मान में कुछ बहुपद है , बजाय बिट्स की संख्या में इसका प्रतिनिधित्व करने के लिए आवश्यक है। हमारा मुख्य परीक्षण एल्गोरिथ्म एक छद्म एकलोपयोगी समय एल्गोरिथ्म है, क्योंकि यह समय O (n 4 ) में चलता है , लेकिन यह बहुपद-काल एल्गोरिथ्म नहीं है क्योंकि इनपुट लिखने के लिए बिट्स x की संख्या के एक फ़ंक्शन के रूप में, रनटाइम O है (२ ४x )। कारण यह है कि "PRIMES is P" पेपर इतना महत्वपूर्ण था कि उसका रनटाइम (लगभग) O (लॉग 12 n) था, जो बिट्स की संख्या के एक फ़ंक्शन के रूप में O (x 12 ) है।
तो यह बात क्यों है? ठीक है, हमारे पास पूर्णांकों को फैक्टर करने के लिए कई छद्मोप्लोमिनियल समय एल्गोरिदम हैं। हालांकि, ये एल्गोरिदम तकनीकी रूप से, एक्सपोनेंशियल-टाइम एल्गोरिदम हैं। यह क्रिप्टोग्राफी के लिए बहुत उपयोगी है: यदि आप आरएसए एन्क्रिप्शन का उपयोग करना चाहते हैं, तो आपको यह भरोसा करने में सक्षम होने की आवश्यकता है कि हम आसानी से कारक संख्याएं नहीं कर सकते। संख्याओं में बिट्स की संख्या को एक विशाल मूल्य (जैसे 1024 बिट्स) में बढ़ाकर, आप उस समय की मात्रा बना सकते हैं, जिसे pseudopolynomial- टाइम फैक्टरिंग एल्गोरिदम को इतना बड़ा लेना चाहिए कि यह पूरी तरह से और पूरी तरह से फैक्टर के लिए संक्रामक हो जाए संख्या। यदि, दूसरी ओर, हम एक बहुपद- काल फैक्टरिंग एल्गोरिथ्म पा सकते हैं , तो यह जरूरी नहीं है। अधिक बिट्स में जोड़ने से काम बहुत बढ़ सकता है, लेकिन विकास केवल बहुपद विकास होगा, घातीय वृद्धि नहीं।
कहा कि, कई मामलों में स्यूडोपोलिनोमियल समय एल्गोरिदम पूरी तरह से ठीक हैं क्योंकि संख्याओं का आकार बहुत बड़ा नहीं होगा। उदाहरण के लिए, काउंटिंग सॉर्ट में रनटाइम O (n + U) होता है, जहां U सरणी में सबसे बड़ी संख्या है। यह pseudopolynomial समय है (क्योंकि यू के संख्यात्मक मान को लिखने के लिए O (लॉग यू) बिट्स की आवश्यकता होती है, इसलिए रनटाइम इनपुट आकार में घातीय है)। यदि हम यू को कृत्रिम रूप से विवश करते हैं ताकि यू बहुत बड़ा न हो (कहो, अगर हम यू 2 हो जाते हैं), तो रनटाइम ओ (एन) है, जो वास्तव में बहुपद समय है। यह इस प्रकार है कि मूलांक किस प्रकार कार्य करता है: एक समय में संख्याओं को एक सा संसाधित करके, प्रत्येक दौर का रनटाइम O (n) होता है, इसलिए समग्र रनटाइम O (n log U) होता है। यह वास्तव में है बहुपद समय, क्योंकि छांटने के लिए n संख्याओं का उपयोग n (n) बिट्स और लॉग यू का मान सरणी में अधिकतम मान लिखने के लिए आवश्यक बिट्स की संख्या के लिए सीधे आनुपातिक है।
उम्मीद है की यह मदद करेगा!