एक स्लाइडिंग विंडो माध्यिका की गणना के लिए Nontrivial एल्गोरिथ्म


25

मुझे चल रहे माध्य की गणना करने की आवश्यकता है:

  • इनपुट: , k , वेक्टर ( x 1 , x 2 , , x n )nk(x1,x2,,xn)

  • आउटपुट: वेक्टर , जहां y i का माध्य है ( x i , x i + 1 , , x i + k - 1 )(y1,y2,,ynk+1)yi(xi,xi+1,,xi+k1)

(सन्निकटन के साथ कोई धोखा नहीं; मैं सटीक समाधान करना चाहूंगा। तत्व बड़े पूर्णांक हैं।)xi

एक तुच्छ एल्गोरिथ्म है जो आकार का खोज ट्री बनाए रखता है ; कुल चलने का समय O ( n log k ) है । (यहां "खोज ट्री" कुछ कुशल डेटा संरचना को संदर्भित करता है जो लॉगरिंथ समय में सम्मिलन, विलोपन, और मध्ययुगीन प्रश्नों का समर्थन करता है।)kO(nlogk)

हालांकि, यह मुझे थोड़ा बेवकूफ लगता है। हम प्रभावी रूप से सीखना होगा सभी आकार के सभी खिड़कियों के भीतर आदेश आँकड़े ही नहीं, माध्यिकाओं। इसके अलावा, यह व्यवहार में बहुत आकर्षक नहीं है, खासकर यदि k बड़ा है (बड़े खोज पेड़ धीमी गति से होते हैं, स्मृति खपत में ओवरहेड गैर-तुच्छ है, कैश-दक्षता अक्सर खराब होती है, आदि)।kk

क्या हम कुछ बेहतर कर सकते हैं?

क्या कोई निचली सीमा है (उदाहरण के लिए, तुलनात्मक मॉडल के लिए तिर्यक एल्गोरिथ्म asymptotically इष्टतम है)?


संपादित करें: डेविड एप्पस्टीन ने तुलनात्मक मॉडल के लिए एक अच्छा निचला भाग दिया! मुझे आश्चर्य है कि अगर तुच्छ एल्गोरिथ्म की तुलना में कुछ अधिक चतुर करना संभव है?

उदाहरण के लिए, क्या हम इन पंक्तियों के साथ कुछ कर सकते हैं: इनपुट वेक्टर को आकार भागों में विभाजित करें ; प्रत्येक भाग को क्रमबद्ध करें (प्रत्येक तत्व के मूल पदों का ध्यान रखें); और फिर किसी भी सहायक डेटा संरचनाओं के बिना कुशलता से चल रहे मध्यस्थों को खोजने के लिए टुकड़ावार छांटे वेक्टर का उपयोग करें? बेशक यह अभी भी ( एन लॉग के ) होगा , लेकिन व्यवहार में सरणियों में खोज पेड़ों को बनाए रखने की तुलना में बहुत तेजी से होता है।kO(nlogk)


संपादित करें 2: सईद कुछ कारणों को देखना चाहता था कि मुझे क्यों लगता है कि खोज के पेड़ के संचालन की तुलना में छंटनी तेज है। यहाँ बहुत ही तेज़ बेंचमार्क हैं, , n = 10 8 के लिए :k=107n=108

  • ≈ 8s: k के साथ वैक्टर को छांटनाn/kk प्रत्येक तत्वों के
  • । 10 एस: तत्वों के साथ एक सदिश छँटाईn
  • ≈ 80: सम्मिलन और आकार का एक हैश तालिका में हटाए गए कश्मीरnk
  • ≈ 390s: सम्मिलन और आकार का एक संतुलित खोज पेड़ काट-छांट कश्मीरnk

हैश तालिका तुलना के लिए वहाँ है; यह इस आवेदन में कोई सीधा उपयोग नहीं है।

सारांश में, हमारे पास सॉर्टिंग बनाम संतुलित खोज ट्री ऑपरेशन के प्रदर्शन में लगभग 50 का अंतर है। और चीजें बहुत खराब हो जाती हैं अगर हम बढ़ाते हैं ।k

(तकनीकी विवरण: डेटा = यादृच्छिक 32-बिट पूर्णांक। कंप्यूटर = एक सामान्य आधुनिक लैपटॉप। मानक पुस्तकालय दिनचर्या (std :: सॉर्ट) और डेटा संरचनाओं (std :: multiset, std ::) का उपयोग करके परीक्षण कोड C ++ में लिखा गया था। unsorted_multiset)। मैंने दो अलग-अलग C ++ कंपाइलर (GCC और Clang) का उपयोग किया, और मानक पुस्तकालय के दो अलग-अलग कार्यान्वयन (libstdc ++ और libc ++)। परंपरागत रूप से, std :: multiset को अत्यधिक अनुकूलित लाल-काले वृक्ष के रूप में लागू किया गया है।)


1
मुझे नहीं लगता कि आप सुधार कर पाएंगे । कारण, अगर आप एक खिड़की को देखो एक्स टी , , x t + k - 1 , आप कभी भी संख्याओं x t + k में से कोई भी नियम नहीं बना सकतेnlogkxt,...,xt+k1भविष्य की खिड़की के मध्यस्थ होने से। इसका मतलब है कि किसी भी समय आपको कम से कमकश्मीररखना होगाxt+k2,...,xt+k1डेटा संरचना में 2 पूर्णांक, और यह लॉग टाइम से कम समय में अपडेट नहीं होता है। k2
आरबी

मेरे लिए आपका तुच्छ एल्गोरिथ्म नहीं O ( n लॉग k ) प्रतीत होता है , क्या मैं कुछ गलत समझ रहा हूं? और मुझे लगता है कि इस वजह से आपको बड़ी k के साथ समस्या है , अन्यथा लॉगरिदमिक कारक व्यावहारिक अनुप्रयोगों में कुछ भी नहीं है, इस एल्गोरिथ्म में कोई बड़ा छिपी स्थिरांक भी नहीं है। O((nk)klogk)O(nlogk)k
सईद

@ सईद: तुच्छ एल्गोरिथ्म में, आप तत्वों को एक-एक करके संसाधित करते हैं; कदम में आप जोड़ना एक्स मैं खोज पेड़ से और (अगर मैं > कश्मीर ) आप भी हटाने एक्स मैं - कश्मीर खोज पेड़ से। यह n चरण है, जिनमें से प्रत्येक O ( log k ) समय लेता है । ixii>kxiknO(logk)
जुल्का सुमेला

तो आपका मतलब है कि आपके पास एक संतुलित खोज वृक्ष है जो आकस्मिक खोज वृक्ष नहीं है?
सईद

1
@ सईद: कृपया ध्यान दें कि मेरे बेंचमार्क में मैंने मंझले लोगों को खोजने की कोशिश भी नहीं की। मैंने अभी आकार k के खोज ट्री में सम्मिलन और n विलोपन किया है , और इन कार्यों को O ( लॉग k ) समय लेने की गारंटी है । आपको बस यह स्वीकार करने की आवश्यकता है कि खोज ट्री ऑपरेशन छँटाई की तुलना में अभ्यास में बहुत धीमी है। आप इसे आसानी से देखेंगे यदि आप एक सॉर्टिंग एल्गोरिदम लिखने की कोशिश करते हैं जो एक संतुलित खोज ट्री में तत्वों को जोड़कर काम करता है - यह निश्चित रूप से ( एन लॉग एन ) समय में काम करता है , लेकिन यह अभ्यास में हास्यास्पद रूप से धीमा होगा, और बहुत अधिक बर्बाद करेगा स्मृति का। nnkO(logk)O(nlogn)
जुक्का सुओमेला

जवाबों:


32

यहाँ छँटाई से एक कम बाउंड है। किसी इनपुट सेट की लंबाई के अनुसार n को सॉर्ट किया जाना है, अपनी रनिंग माध्यिका समस्या के लिए एक इनपुट बनाएं जिसमें n की संख्या 1 है - S की न्यूनतम से छोटी संख्या की , फिर S की , फिर n - की तुलना में बड़ी संख्या की 1 प्रतियां S की अधिकतम , और सेट k = 2 n - 1 । इस इनपुट के रनिंग माध्य S के क्रमबद्ध क्रम के समान हैं ।Snn1SSn1Sk=2n1S

इसलिए गणना के एक तुलना मॉडल में, समय की आवश्यकता होती है। संभवतः यदि आपके इनपुट पूर्णांक हैं और आप पूर्णांक एल्गोरिदम का उपयोग करते हैं तो आप बेहतर कर सकते हैं।Ω(nlogn)


6
यह उत्तर वास्तव में मुझे आश्चर्यचकित करता है कि क्या काफिला भी सुरक्षित है: एक कुशल छँटाई एल्गोरिथ्म दिया, क्या हमें एक कुशल चल मंझला एल्गोरिथ्म मिलता है? (उदाहरण के लिए, क्या कुशल पूर्णांक छँटाई एल्गोरिथ्म का अर्थ है पूर्णांक के लिए एक कुशल चल मंझला एल्गोरिथ्म? या एक IO- कुशल छँटाई एल्गोरिथ्म एक IO- कुशल चल मंझला एल्गोरिथ्म प्रदान करता है?)
Jukka Suomela

1
एक बार फिर, आपके उत्तर के लिए बहुत धन्यवाद, इसने वास्तव में मुझे सही रास्ते पर सेट किया और सॉर्टिंग-आधारित माध्य फ़िल्टर एल्गोरिथ्म के लिए प्रेरणा दी! अंत में मैं 1991 से एक पेपर खोजने में सक्षम था जो मूल रूप से वही तर्क प्रस्तुत करता था जो आप यहां देते हैं, और पैट मॉरिन ने 2005 से एक और प्रासंगिक पेपर को एक संकेतक दिया; रेफरी देखें। [६] और [९] यहां
जुका सुओमेला

9

संपादित करें: यह एल्गोरिथ्म अब यहां प्रस्तुत किया गया है: http://arxiv.org/abs/1406.1717


हां, इस समस्या को हल करने के लिए यह निम्नलिखित ऑपरेशन करने के लिए पर्याप्त है:

  • क्रमबद्ध वैक्टर, के साथ प्रत्येक कश्मीर तत्वों।n/kk
  • लीनियर-टाइम पोस्ट-प्रोसेसिंग करें।

बहुत मोटे तौर पर, यह विचार है:

  • इनपुट के दो आसन्न ब्लॉकों पर विचार करें, और , दोनों के साथ कश्मीर तत्वों; तत्वों रहने दो एक 1 , एक 2 , , एक कश्मीर और 1 , बी 2 , , इनपुट वेक्टर x में उपस्थिति के क्रम में b kabka1,a2,...,akb1,b2,...,bkx
  • इन ब्लॉकों को क्रमबद्ध करें और ब्लॉक के भीतर प्रत्येक तत्व की रैंक जानें।
  • वैक्टर में वृद्धि और पूर्ववर्ती / उत्तराधिकारी संकेत के साथ ताकि सूचक चेन का पालन करते हुए हम एक बढ़ते क्रम में तत्वों पार कर सकते हैं। इस तरह से हम का निर्माण किया है दोगुना सूचियों जुड़ा हुआ एक ' और 'abab
  • एक-एक करके लिंक्ड सूची से सभी तत्वों को हटाने के लिए, उपस्थिति के विपरीत क्रम में, कश्मीर , कश्मीर - 1 , , बी । जब भी हम किसी तत्व को हटाते हैं, तो याद रखें कि विलोपन के समय उसका उत्तराधिकारी और पूर्ववर्ती क्या थाbbk,bk1,...,b1
  • अब बनाए रखने के "मंझला संकेत" और क्यू कि सूची में बिंदु एक ' और ' , क्रमशः। आरंभ पी के मध्य करने के लिए एक ' , और आरंभ क्ष खाली सूची की पूंछ को 'pqabpaqb
  • प्रत्येक के लिए :i

    • हटाएँ सूची में से एक ' (यह हे ( 1 ) समय, लिंक किए गए सूची से हटाना)। की तुलना एक मैं तत्व के साथ द्वारा बताया पी देखने के लिए अगर हम पहले या बाद में नष्ट कर दिया पीaiaO(1)aipp
    • रखो वापस सूची में ' अपनी मूल स्थिति में (यह हे ( 1 ) बार, हम पूर्ववर्ती और उत्तराधिकारी की याद मैं )। तुलना मैं तत्व द्वारा बताया साथ क्ष अगर हम पहले या बाद में तत्व जोड़े को देखने के लिए क्षbibO(1)bibiqq
    • Update pointers p and q so that the median of the joined list ab is either at p or at q. (This is O(1) time, just follow the linked lists one or two steps to fix everything. We will keep track of how many items are before/after p and q in each list, and we will maintain the invariant that both p and q point to elements that are as close to the median as possible.)

The linked lists are just k-element arrays of indexes, so they are lightweight (except that the locality of memory access is poor).


यहाँ एक नमूना कार्यान्वयन और बेंचमार्क है:

यहाँ (के लिए बार चलाने का एक साजिश है ):n2106

  • ब्लू = सॉर्टिंग + पोस्ट-प्रोसेसिंग, O(nlogk)
  • ग्रीन = दो ढेर बनाए रखें, , https://github.com/craffel/median-filter से कार्यान्वयनO(nlogk)
  • लाल = दो खोज पेड़ बनाए रखें, O(nlogk)
  • काला = एक क्रमबद्ध वेक्टर, बनाए रखें ।O(nk)
  • एक्स अक्ष = विंडो का आकार ( k/2).
  • Y axis = running time in seconds.
  • Data = 32-bit integers and random 64-bit integers, from various distributions.

running times


3

Given David's bound it's unlikely you can do better worst case, but there are better output sensitive algorithms. Specifically, if m in the number of medians in the result, we can solve the problem in time O(nlogm+mlogn).

To do this, replace the balanced binary tree with a balanced binary tree consisting of only those elements that were medians in the past, plus two Fibonacci heaps in between each pair of previous medians (one for each direction), plus counts so that we can locate which Fibonacci heap contains a particular element in the order. Don't bother ever deleting elements. When we insert a new element, we can update our data structure in O(logm) time. If the new counts indicate that the median is in one of the Fibonacci heaps, it takes an additional O(logn) to pull the new median out. This O(logn) charge occurs only once per median.

If there was a clean way to delete elements without damaging the nice Fibonacci heap complexity, we'd get down to O(nlogm+mlogk), but I'm not sure if this is possible.


Oops, this doesn't work as written, since if you don't delete elements the counts won't reflect the new window. I'm not sure if it can be fixed, but I will leave the answer in case there is a way.
Geoffrey Irving

So I think this algorithm may in fact take O(nlogm) if you delete nodes from the Fibonacci heaps, since the Fibonacci heap depth increases only when delete-min is called. Does anyone know nice bounds on Fibonacci heap complexity taking the number of delete-min calls into account?
Geoffrey Irving

side note: Question is not clear, underling data structure is not defined, we just know something very vague. how do you want improve something that you don't know what it is? how do you want compare your approach?
Saeed

1
I apologize for the incomplete work. I've asked the concrete question needed to fix this answer here: cstheory.stackexchange.com/questions/21778/…. If you think it's appropriate I can remove this answer until the secondary question is resolved.
Geoffrey Irving
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.