O(n log n) में median खोजना
- सूची को sort करने के बाद median चुनने का सबसे सरल तरीका
- comparison-based sorting की time complexity
O(n log n)होती है - कोड उदाहरण:
def nlogn_median(l): l = sorted(l) if len(l) % 2 == 1: return l[len(l) // 2] else: return 0.5 * (l[len(l) // 2 - 1] + l[len(l) // 2])
औसतन O(n) में median खोजना
-
"quickselect" एल्गोरिद्म का उपयोग करके औसतन linear time में median पाया जा सकता है
-
Tony Hoare द्वारा विकसित recursive एल्गोरिद्म
-
प्रक्रिया:
- सूची से एक random index चुनकर उसे pivot के रूप में सेट करें
- pivot के आधार पर सूची को दो समूहों में बाँटें:
- pivot से छोटे या उसके बराबर elements
- pivot से बड़े elements
- उस समूह में recursively खोजें जिसमें median शामिल है
-
कोड उदाहरण:
import random def quickselect_median(l, pivot_fn=random.choice): if len(l) % 2 == 1: return quickselect(l, len(l) // 2, pivot_fn) else: return 0.5 * (quickselect(l, len(l) // 2 - 1, pivot_fn) + quickselect(l, len(l) // 2, pivot_fn)) def quickselect(l, k, pivot_fn): if len(l) == 1: assert k == 0 return l[0] pivot = pivot_fn(l) lows = [el for el in l if el < pivot] highs = [el for el in l if el > pivot] pivots = [el for el in l if el == pivot] if k < len(lows): return quickselect(lows, k, pivot_fn) elif k < len(lows) + len(pivots): return pivots[0] else: return quickselect(highs, k - len(lows) - len(pivots), pivot_fn)
औसत O(n) का प्रमाण
- यदि pivot सूची को लगभग आधे में बाँटता है, तो हर recursive call पिछले चरण के लगभग आधे डेटा पर काम करती है
- गणितीय प्रमाण:
C = n + n/2 + n/4 + n/8 + ... = 2n = O(n)
deterministic O(n)
-
worst case में भी linear time की गारंटी
-
pivot चुनने के लिए "median-of-medians" एल्गोरिद्म का उपयोग
-
प्रक्रिया:
- सूची को 5-5 के समूहों में बाँटें
- हर समूह को sort करें और उसका median चुनें
- medians के median को pivot के रूप में चुनें
-
कोड उदाहरण:
def pick_pivot(l): assert len(l) > 0 if len(l) < 5: return nlogn_median(l) chunks = chunked(l, 5) full_chunks = [chunk for chunk in chunks if len(chunk) == 5] sorted_groups = [sorted(chunk) for chunk in full_chunks] medians = [chunk[2] for chunk in sorted_groups] median_of_medians = quickselect_median(medians, pick_pivot) return median_of_medians def chunked(l, chunk_size): return [l[i:i + chunk_size] for i in range(0, len(l), chunk_size)]
सारांश
- quickselect एल्गोरिद्म उचित pivot चुनने पर linear time में median खोज सकता है
- median-of-medians एल्गोरिद्म pivot चुनने की ऐसी विधि है जो worst case में भी linear time की गारंटी देती है
- व्यवहार में random pivot selection काफी प्रभावी होता है
GN⁺ का सार
- यह लेख median खोजने के विभिन्न एल्गोरिद्म समझाता है, खासकर linear time में median खोजने की विधि पर केंद्रित है
- quickselect एल्गोरिद्म औसतन तेज है, लेकिन worst case से निपटने के लिए median-of-medians एल्गोरिद्म का उपयोग किया जा सकता है
- वास्तविक अनुप्रयोगों में random pivot selection अधिकांश मामलों में पर्याप्त रूप से प्रभावी होता है
- समान कार्यक्षमता वाला एक और एल्गोरिद्म introselect है, जिसका उपयोग C++ standard library में किया जाता है
1 टिप्पणियां
Hacker News राय