फास्ट टैग खोज के लिए एल्गोरिदम


16

समस्या निम्नलिखित है।

  • सरल ई का एक सेट है, हर एक टैग टी का एक सेट है। प्रत्येक इकाई में टैग की एक मनमानी संख्या हो सकती है। संस्थाओं की कुल संख्या 100 मिलियन के पास है, और टैग की कुल संख्या लगभग 5000 है।

तो प्रारंभिक डेटा कुछ इस तरह है:

E1 - T1, T2, T3, ... Tn
E2 - T1, T5, T100, ... Tk
..
Ez - T10, T12, ... Tl

यह प्रारंभिक डेटा काफी कम अद्यतन किया गया है।

  • किसी तरह मेरा ऐप इस तरह टैग पर एक तार्किक अभिव्यक्ति उत्पन्न करता है:

    T1 & T2 & T3 | (T5 और! T6)

  • मुझे दी गई अभिव्यक्ति से मेल खाने वाली कई संस्थाओं की गणना करने की आवश्यकता है (ध्यान दें - संस्थाएं नहीं, बल्कि सिर्फ संख्या)। यह एक बिल्कुल सही नहीं हो सकता है, निश्चित रूप से।

अब मुझे जो मिला है वह एक साधारण इन-मेमोरी टेबल लुकअप है, जो मुझे एक ही थ्रेड पर 5-10 सेकंड का निष्पादन समय देता है।

मैं उत्सुक हूं, क्या इस सामान को संभालने का कोई कुशल तरीका है? आप किस दृष्टिकोण की सिफारिश करेंगे? क्या इसके लिए कुछ सामान्य एल्गोरिदम या डेटा संरचनाएं हैं?

अपडेट करें

अनुरोध के अनुसार थोड़ा स्पष्टीकरण।

  1. Tऑब्जेक्ट वास्तव में अपेक्षाकृत कम निरंतर तार हैं। लेकिन यह वास्तव में मायने नहीं रखता है - हम हमेशा कुछ आईडी असाइन कर सकते हैं और पूर्णांक पर काम कर सकते हैं।
  2. हम निश्चित रूप से उन्हें छांट सकते हैं।

1
है T1के लिए एक ही वस्तु संदर्भ E1, E2, आदि?
अभिकर्मक

टैग कैसे तुलनीय हैं? क्या टैग को क्रमबद्ध किया जा सकता है ताकि T2 < T3यह हमेशा सही हो?
अभिकर्मक

क्या टैग बाइनरी हैं? Ie इनपुट के आधार पर या T1तो दिया गया है या नहीं, और परिवर्तनशील नहीं है? (यानी ) या एक चर अभिव्यक्ति की तरह है ? truefalseEModel = "V5"T1Model = <input>
बोबसन

जवाबों:


4

मैं यह सेक्वल में सेल्फ-जॉइनिंग का उपयोग करते हुए रेफ़रेंसिंग इकाई और रेफ़रेंसिंग श्रेणी के EntityCategoryबीच एक लिंक टेबल के साथ करूँगा :eidcid

    select count(ec1.eid)
    from EntityCategory ec1 
    left join EntityCategory ec2 on ec1.eid=ec2.eid 
    left join EntityCategory ec3 on ec1.eid=ec3.eid 
    ...
    where 
      ec1.cid={categoryId1} and 
      ec2.cid={categoryId2} and
      ec3.cid={categoryId3} ...

1
+1, यह क्लासिक डीबी क्षेत्र है। अन्य उत्तर में उचित विचार हो सकता है कि इसे मैन्युअल रूप से कोड कैसे किया जाए, लेकिन यह एक अंतिम उपाय होना चाहिए।
MSalters

मैं इसे हल करने के लिए तकनीक के रूप में sql भी चुनूंगा। अधिकांश डेटाबेस इन एल्गोरिदम के लिए बहुत अनुकूलित हैं :)
winkbrace

3

इस उत्तर को लिखने के बाद, मुझे शायद प्रश्न को "बहुत व्यापक" के रूप में चिह्नित करना चाहिए - हम विभिन्न रणनीतियों के बारे में उम्र के लिए बात कर सकते हैं, अंत में आपके डेटा के साथ एक बेंचमार्क चलाना होगा।

प्रत्येक टैग को पूर्णांक द्वारा कुशलता से दर्शाया जा सकता है। प्रत्येक इकाई में टैग का एक सेट होता है। सही सेट कार्यान्वयन चुनना महत्वपूर्ण है - बी-पेड़ और सॉर्ट किए गए दोनों सरणियां संभव हैं। इस सेट के साथ, हम केवल सदस्यता परीक्षण करेंगे। जैसा कि दोनों संरचनाएं इसमें करती हैं ओ (लॉग टी) ( प्रति यूनिट टी टैग के साथ ) में ऐसा करती हैं, मैं उनके सघन प्रतिनिधित्व के कारण सरणियों को पसंद करूंगा।

अब हम एक ओ (n · लॉग टी · पी) में सभी संस्थाओं के माध्यम से फ़िल्टर कर सकते हैं ऑपरेशन , जहां पी विधेय निर्णय पेड़ में औसत पथ लंबाई है। इस निर्णय वृक्ष को आदेश दिया जा सकता है ताकि किसी निर्णय पर जल्दी पहुंचा जा सके। सांख्यिकीय आंकड़ों के बिना, केवल सामान्य सब-डेप्रिसिएशन को फैक्टर करना संभव है।

जिस क्रम में संस्थाओं की खोज की जाती है वह वास्तव में महत्वपूर्ण नहीं है। दूसरी तरफ इसे छाँटना फायदेमंद हो सकता है, 0ताकि iसभी सूचकांकों में इकाइयाँ एक निश्चित टैग के साथ हों, जबकि बाकी नहीं। इस विशिष्ट टैग की खोज करते समय यह n कम कर देता है (निर्णय ट्री में, यह पहला परीक्षण होना चाहिए)। इसे कई स्तरों पर विस्तारित किया जा सकता है, लेकिन यह चीजों को जटिल बनाता है और O (2) लेता है कश्मीर ) के साथ स्मृति कश्मीरस्तरों। कई स्तरों के साथ, सबसे अधिक लाभ वाले टैग को पहले तय किया जाना चाहिए, जहां लाभ उन संस्थाओं की संख्या है जिन्हें उन्हें त्यागने की संभावना से कई गुना अधिक नहीं देखा जाना चाहिए। लाभ 50:50 अवसरों के लिए अधिकतम हो जाता है या जब 50% संस्थाओं में यह विशिष्ट टैग होता है। यदि आप एक्सेस पैटर्न के बारे में नहीं जानते हैं तो भी यह आपको ऑप्टिमाइज़ करने की अनुमति देगा।

आप उपयोग किए गए प्रत्येक टैग द्वारा इकाइयां सेट करने वाली इकाइयाँ भी बना सकते हैं - T1अगले के लिए सभी संस्थाओं के साथ एक सेट T2। एक स्पष्ट (स्थान और समय) अनुकूलन को रोकना है जब एक सेट में सभी तत्वों में से आधे से अधिक होता है, और उन तत्वों को सहेजने के लिए जिनके पास यह टैग नहीं है - इस तरह, सभी टैग के लिए सूचक बनाना ½ · n · tअंतरिक्ष से कम लगेगा (साथ टी कुल में टैग)। ध्यान दें कि पूरक सेट को बचाने से अन्य अनुकूलन अधिक कठिन हो सकते हैं। फिर से, मैं सेट के लिए (सॉर्ट किए गए) एरेज़ दूंगा।

यदि आप एक पूर्णांक सीमा के माध्यम से अपनी संस्थाओं का प्रतिनिधित्व करते हैं, तो आप केवल एक निरंतर सीमा के प्रारंभ और समाप्ति सदस्य को संग्रहीत करके सूचकांक सेट के लिए उपयोग किए जाने वाले स्थान को संपीड़ित कर सकते हैं। कार्यान्वयन-वार यह संभवतः यह इंगित करने के लिए एक उच्च सीमा के साथ किया जाएगा कि क्या कोई प्रविष्टि एक सीमाबद्ध या नियमित प्रविष्टि है।

यदि हमारे पास अब इंडेक्स सेट (और इस प्रकार टैग पर आँकड़े) हैं, तो हम अपनी विधेयकों को अनुकूलित कर सकते हैं ताकि पहले संभावित गुणों का परीक्षण न हो (विफल-तेज रणनीति)। इसका मतलब यह है कि यदि T1आम है और T2दुर्लभ है, तो T1 & T2सभी T2सूचकांक सेट प्रविष्टियों के माध्यम से पुनरावृत्ति करके और इसके तत्व के लिए परीक्षण करके विधेय का मूल्यांकन किया जाना चाहिए T1

यदि हम अनुक्रम सेट को लागू करने के लिए सॉर्ट किए गए सरणियों का उपयोग करते हैं, तो विलय के संचालन के रूप में कई मूल्यांकन चरणों को लागू किया जा सकता है। T1 & T2इसका मतलब है कि हम T1और T2सूचियों को लेते हैं , एक लक्ष्य सरणी को बड़े इनपुट के आकार को आवंटित करते हैं और निम्नलिखित एल्गोरिथ्म को तब तक निष्पादित करते हैं जब तक कि दोनों इनपुट खाली न हों: यदि T1[0] < T2[0], तब T1++(सिर को त्यागें)। अगर है T1[0] > T2[0]तो T2++। दोनों सिरों पर बराबर हैं, तो लक्ष्य सरणी के लिए खत्म हो उस नंबर की प्रतिलिपि बनाएँ, और सभी तीन संकेत (बढ़ा देते T1, T2, लक्ष्य)। यदि विधेय है T1 | T2, तो कोई भी तत्व खारिज नहीं किया जाता है , लेकिन छोटे की नकल की जाती है। फॉर्म की एक विधेय को T1 & ¬T2एक विलय की रणनीति का उपयोग करके भी लागू किया जा सकता है, लेकिन ¬T1या T1 | ¬T2नहीं।

विधेय निर्णय वृक्ष को आदेश देते समय इस पर विचार किया जाना चाहिए: पूर्णताएं या तो आरएचएस पर होनी चाहिए &, या अंत में, जब अंतिम गणना निर्धारित की जा रही है और वास्तविक तत्वों को देखने की जरूरत नहीं है।

इंडेक्स सेट का उपयोग किए बिना, प्रत्येक थ्रेड संस्थाओं के अपने हिस्से के माध्यम से फ़िल्टर कर सकता है और उन तत्वों की गिनती को लौटा सकता है जो कि विधेय से मेल खाते हैं, जिन्हें अभिव्यक्त किया जा सकता है। इंडेक्स सेट का उपयोग करते समय, फिर प्रत्येक धागे को निर्णय के पेड़ में एक नोड सौंपा जाएगा। यह दो इनपुट स्ट्रीम लेता है जो ऑर्डर किए गए सेट के अनुरूप होता है, और एक मर्ज किए गए स्ट्रीम को वापस करता है। ध्यान दें कि निर्णय वृक्ष में प्रत्येक नोड में एक समान सेट होता है जो सभी संस्थाओं का प्रतिनिधित्व करता है जो उस उप-अभिव्यक्ति को पूरा करते हैं, और यह कि सेट के आदेश के कारण, उन्हें विलय करने के लिए पूरे सेट को एक बार में जानना आवश्यक नहीं है। ।

अनुक्रमित सेटों को मर्ज करने या संस्थाओं की एक सूची के माध्यम से फ़िल्टर करने जैसी विभिन्न रणनीतियों को एक निश्चित डिग्री तक जोड़ा जा सकता है। फ़िल्टरिंग में बहुत ही पूर्वानुमानित प्रदर्शन होता है। यदि कोई क्वेरी बहुत विशिष्ट है ताकि इंडेक्स सेट का उपयोग खोज स्थान को काफी कम कर दे, तो मर्ज संचालन बेहतर हो सकता है। यह ध्यान रखना महत्वपूर्ण है कि कई बड़े इनपुट सेट को मर्ज करने से ब्रूट-बल खोज की तुलना में बहुत खराब प्रदर्शन हो सकता है। एक बहुत ही अनुकूलित एल्गोरिथ्म इनपुट आकार, क्वेरी संरचना और सांख्यिकीय संकेतकों के आधार पर एक उपयुक्त रणनीति चुनेगा।

एक तरफ के रूप में, आंशिक परिणामों को कैशिंग करना फायदेमंद हो सकता है यदि यह उम्मीद की जाती है कि भविष्य में भी इसी तरह के प्रश्न चलेंगे, भले ही वे इनबिल्ट रन को गति न दें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.