किसी भी एल्गोरिथ्म का मूल्यांकन उसकी दक्षता (Efficiency) के आधार पर किया जाता है। दक्षता यह बताती है कि कोई एल्गोरिथ्म कितनी जल्दी और कितने संसाधनों के उपयोग से समस्या का हल करता है। दक्षता को मापने के दो मुख्य पहलू हैं - समय जटिलता (Time Complexity) और स्थान जटिलता (Space Complexity)। समय जटिलता एल्गोरिथ्म के चलने में लगने वाले समय को दर्शाती है, जबकि स्थान जटिलता उपयोग होने वाली मेमोरी को दर्शाती है।
किसी एल्गोरिथ्म की दक्षता को समझने से हम बड़े डेटा पर कौन सा एल्गोरिथ्म चुनना है, इसका सही निर्णय ले सकते हैं। इसी अवधारणा को बिग-ओ नोटेशन (Big-O Notation) से व्यक्त किया जाता है।
एक एल्गोरिथ्म तब कुशल माना जाता है जब: 1. वह कम समय में परिणाम देता है। 2. वह कम मेमोरी का उपयोग करता है। 3. वह बड़े इनपुट के साथ भी सुचारू रूप से चलता है।
एल्गोरिथ्म की दक्षता इनपुट के आकार (n) पर निर्भर करती है। जैसे-जैसे इनपुट का आकार बढ़ता है, वैसे-वैसे एल्गोरिथ्म के मूल कार्यों (ऑपरेशनों) की संख्या भी बढ़ती है। दक्षता का अध्ययन हमें यह बताता है कि यह वृद्धि किस दर पर होती है।
समय जटिलता किसी एल्गोरिथ्म को चलाने में लगने वाले समय की माप है। इसे मूल ऑपरेशनों की संख्या के रूप में इनपुट आकार n के फलन के रूप में व्यक्त किया जाता है। हम वास्तविक समय (सेकंड) नहीं, बल्कि ऑपरेशनों की संख्या में वृद्धि की दर का अध्ययन करते हैं।
# O(1) - स्थिर समय: केवल एक ऑपरेशन
def get_first(lst):
return lst[0]
# O(n) - रैखिक समय: n ऑपरेशन
def linear_search(lst, target):
for item in lst:
if item == target:
return True
return False
# O(n^2) - द्विघात समय: n^2 ऑपरेशन
def bubble_sort(arr):
n = len(arr)
for i in range(n - 1):
for j in range(n - 1 - i):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
बिग-ओ नोटेशन एल्गोरिथ्म की सबसे खराब स्थिति (worst case) में समय जटिलता को व्यक्त करने का मानक तरीका है। यह बताता है कि इनपुट आकार n के बड़े होने पर एल्गोरिथ्म की वृद्धि की ऊपरी सीमा क्या है।
| नोटेशन | नाम | उदाहरण एल्गोरिथ्म |
|---|---|---|
| O(1) | स्थिर समय | सूची का पहला तत्व |
| O(log n) | लघुगणकीय | बाइनरी सर्च |
| O(n) | रैखिक | रैखिक सर्च |
| O(n log n) | रैखिक-लघुगणकीय | मर्ज सॉर्ट, क्विक सॉर्ट |
| O(n²) | द्विघात | बबल सॉर्ट, चयन सॉर्ट |
| O(2^n) | घातांकीय | फिबोनाची (भोला रिकर्शन) |
मान लीजिए n = 10,00,000 (10 लाख) इनपुट: - O(1): 1 ऑपरेशन - O(log n): लगभग 20 ऑपरेशन - O(n): 10,00,000 ऑपरेशन - O(n log n): लगभग 2 करोड़ ऑपरेशन - O(n²): 10^12 ऑपरेशन (अत्यधिक)
यह तालिका स्पष्ट करती है कि एल्गोरिथ्म की जटिलता का चुनाव कितना महत्वपूर्ण है।
स्थान जटिलता एल्गोरिथ्म द्वारा उपयोग की जाने वाली मेमोरी की मात्रा को दर्शाती है। इसमें इनपुट को संग्रहीत करने और एल्गोरिथ्म चलाने के दौरान आवश्यक अतिरिक्त मेमोरी दोनों शामिल हैं।
# O(1) स्थान - इन-प्लेस
def swap(a, b):
return b, a
# O(n) स्थान - नई सूची
def reverse_copy(lst):
return lst[::-1]
किसी एल्गोरिथ्म की जटिलता का विश्लेषण तीन स्थितियों में किया जाता है:
बिग-ओ नोटेशन प्रायः सबसे खराब स्थिति का वर्णन करता है, क्योंकि हमें गारंटी की आवश्यकता होती है।
| एल्गोरिथ्म | सर्वश्रेष्ठ | सबसे खराब |
|---|---|---|
| रैखिक सर्च | O(1) | O(n) |
| बाइनरी सर्च | O(1) | O(log n) |
| एल्गोरिथ्म | सर्वश्रेष्ठ | औसत | सबसे खराब |
|---|---|---|---|
| बबल सॉर्ट | O(n) | O(n²) | O(n²) |
| चयन सॉर्ट | O(n²) | O(n²) | O(n²) |
| इंसर्शन सॉर्ट | O(n) | O(n²) | O(n²) |
किसी कोड की समय जटिलता का आकलन उसकी संरचना देखकर किया जा सकता है। कुछ सामान्य नियम:
# O(log n) वाला कोड
n = 1024
count = 0
while n > 1:
n = n // 2
count += 1
print(count) # 10 (क्योंकि log2(1024) = 10)
इन नियमों के अभ्यास से दिए गए कोड की जटिलता पहचानना आसान हो जाता है, जो वस्तुनिष्ठ प्रश्नों का मुख्य भाग है।
दक्षता की अवधारणा केवल परीक्षा तक सीमित नहीं है, बल्कि वास्तविक सॉफ़्टवेयर में इसका गहरा प्रभाव होता है। उदाहरण के लिए:
एक अकुशल एल्गोरिथ्म उपयोगकर्ता को प्रतीक्षा करवा सकता है या सर्वर को भारी बना सकता है। इसलिए एल्गोरिथ्म का चयन करते समय उसकी जटिलता का विश्लेषण करना एक अच्छे प्रोग्रामर की पहचान है। परीक्षा में यह तर्क लिखने से आपके उत्तर में गहराई आती है।
| क्रम | नाम | विवरण |
|---|---|---|
| O(1) | स्थिर | समय इनपुट से स्वतंत्र |
| O(log n) | लघुगणकीय | हर चरण में आधा |
| O(n) | रैखिक | इनपुट के समानुपाती |
| O(n log n) | रैखिक-लघुगणकीय | कुशल सॉर्ट |
| O(n²) | द्विघात | नेस्टेड लूप |
| O(2^n) | घातांकीय | बहुत धीमा |
| एल्गोरिथ्म | सबसे खराब समय |
|---|---|
| रैखिक सर्च | O(n) |
| बाइनरी सर्च | O(log n) |
| बबल सर्च | O(n²) |
| मर्ज सॉर्ट | O(n log n) |
एल्गोरिथ्म की दक्षता उसकी सफलता का माप है। समय जटिलता और स्थान जटिलता के दो पहलुओं से हम किसी एल्गोरिथ्म का मूल्यांकन करते हैं। बिग-ओ नोटेशन जटिलता को व्यक्त करने का मानक तरीका है, जो सबसे खराब स्थिति की ऊपरी सीमा बताता है। O(1) से O(2^n) तक की वृद्धि दर यह निर्धारित करती है कि कौन सा एल्गोरिथ्म बड़े डेटा के लिए उपयुक्त है। बाइनरी सर्च O(log n) और मर्ज सॉर्ट O(n log n) बड़े डेटा के लिए कुशल हैं, जबकि रैखिक सर्च और बबल सॉर्ट छोटे डेटा के लिए उचित हैं। एल्गोरिथ्म का चुनाव करते समय इनपुट आकार, डेटा की स्थिति और उपलब्ध संसाधनों का ध्यान रखना चाहिए। इस अध्याय से प्राप्त दक्षता की समझ कंप्यूटर विज्ञान की नींव है।