समूह इकाइयों का सबसे तेज़ तरीका जो एक दूसरे को देख सकते हैं?


12

मैं जिस 2 डी गेम के साथ काम कर रहा हूं, गेम इंजन मुझे देने में सक्षम है, प्रत्येक इकाई के लिए, अन्य इकाइयों की सूची जो इसके व्यू रेंज में हैं।

मैं जानना चाहूंगा कि क्या समूहों में इकाइयों को क्रमबद्ध करने के लिए एक स्थापित एल्गोरिथ्म है , जहां प्रत्येक समूह को उन सभी इकाइयों द्वारा परिभाषित किया जाएगा जो एक दूसरे से "जुड़े हुए हैं" (यहां तक ​​कि दूसरों के माध्यम से भी)।

एक उदाहरण प्रश्न को बेहतर ढंग से समझने में मदद कर सकता है (ई = शत्रु, ओ = स्वयं की इकाई)। पहला डेटा जो मुझे गेम इंजन से मिलेगा:

E1 can see E2, E3, O5
E2 can see E1
E3 can see E1
E4 can see O5
E5 can see O2
E6 can see E7, O9, O1
E7 can see E6
O1 can see E6
O2 can see O5, E5
O5 can see E1, E4, O2
O9 can see E6

फिर मुझे समूहों का अनुसरण इस प्रकार करना चाहिए:

G1 = E1, E2, E3, E4, E5, O2, O5
G2 = O1, O9, E6, E7

यह सुरक्षित रूप से माना जा सकता है कि देखने के क्षेत्र के लिए एक सराहनीय संपत्ति है: [यदि ए बी देखता है, तो बी ए देखता है]।

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

आपकी मदद के लिए अग्रिम धन्यवाद!


1
मुझे लगता है कि यह सवाल काफी सामान्य है कि स्टैकओवरफ्लो में बेहतर जवाब मिल सकता है, या शायद गणित (सेट सिद्धांत?) भी। यह खेल विकास विशिष्ट नहीं है मेरी बात है।
तोर वलामो

1
@Tor - शायद सच है, लेकिन यह तथ्य कि हम जानते हैं कि यह एक खेल के लिए है, लोगों को ऐसे जवाब देने की अनुमति दे सकता है जो समस्या के लिए अधिक विशिष्ट हों।
राबर्ट फ्रेजर

मुझे लगता है कि आप स्थानिक हैशिंग और दृश्यता मानचित्र पर स्पिन के साथ कुछ चतुर चीजें कर सकते हैं - मुझे इसके बारे में सोचने की जरूरत है।
जोनाथन डिकिंसन

जवाबों:


7

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

while ungrouped units remain:
    let u = arbitrary ungrouped unit
    let g = new group
    let s = temporary stack
    assign u to g
    push u onto s
    while s is not empty:
        let v = topmost unit in s
        remove v from s
        for each unit w that v can see:
            if w is ungrouped:
                assign w to g
                push w onto s
            end if
        end for
    end while
 end while

(एक कतार या कोई अन्य संग्रह जो कुशलता से संचालन को लागू करता है "नया तत्व जोड़ें" और "कुछ तत्व को हटाने और वापस करने" का उपयोग sऊपर के ढेर के स्थान पर किया जा सकता है।)

यदि आपका "देख सकता है" संबंध सममित नहीं है, तो आपको यह तय करने की आवश्यकता है कि क्या आप चाहते हैं कि आपके समूह दृढ़ता से या कमजोर रूप से जुड़े हुए घटक हों। कमजोर रूप से जुड़े घटकों के लिए, ऊपर एल्गोरिथ्म काम करेगा, सिवाय इसके कि लाइन for each unit w that v can seeको प्रतिस्थापित किया जाना चाहिए for each unit w that can see v, or that v can see। के लिए सशक्त रूप से जुड़े घटकों , आप एल्गोरिदम में से एक (उपयोग कर सकते हैं Kosaraju की , Tarjan के या Gabow के ) से जुड़ा हुआ विकिपीडिया पृष्ठ पर उल्लेख किया।

गैर-सममित संबंधों के लिए, आप संबंध के परिवर्तनशील समापन या इसके दृढ़ता से जुड़े घटकों की गणना करना चाह सकते हैं । इसके लिए, आप फ्लोयड-वारशॉ एल्गोरिथ्म का उपयोग कर सकते हैं ; देख इतने पर इस उत्तर (थोड़ा) अधिक जानकारी के लिए।


Ps। जैसा कि विकिपीडिया लेख मैं उपरोक्त नोटों से जुड़ा था, यह दृश्यता संबंधी परिवर्तन के रूप में समूहों को गतिशील रूप से अपडेट करने के लिए अधिक कुशल हो सकता है। मैं विकिपीडिया पर उल्लिखित उन्नत (?) एल्गोरिदम से परिचित नहीं हूं, लेकिन हर बार खरोंच से समूहों को फिर से विभाजित करने के लिए कम से कम धड़कता है कि एक साथ कुछ करना मुश्किल नहीं होना चाहिए।

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

  • यदि एक इकाई केवल एक अन्य इकाई देख सकती है, और उस पर दृष्टि खो सकती है, तो बस उसे अपने पिछले समूह से हटा दें और उसे एक नए समूह को सौंप दें।
  • अन्यथा, आप प्रभावित इकाइयों में से एक पर शुरू कर सकते हैं और अन्य इकाई के लिए दृश्यता ग्राफ (उदाहरण के लिए सीधी रेखा के रूप में दूरी) का उपयोग करके ए * खोज को चला सकते हैं । यदि आप इसे पाते हैं, तो समूह टूट नहीं गया; यदि आप नहीं करते हैं, तो इकाइयों का समूह जो खोजा गया है वह नया समूह बनाता है।
  • आप यह अनुमान लगाने की कोशिश कर सकते हैं कि दो में से कौन सी इकाई समूह के छोटे आधे हिस्से से संबंधित है, अगर यह विभाजित होता है, और उस इकाई से खोज शुरू करें। एक संभावना हमेशा उस इकाई से शुरू होगी जो सीधे कम अन्य इकाइयों को देख सकती है।

4

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

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

लेकिन सामान्य तौर पर, आपको हर फ्रेम की दृश्यता को पुन: प्राप्त करना होगा। ऑड्स, दृश्यता समूहों को खोजने के लिए ग्राफ ट्रैवर्सल की तुलना में धीमी होने वाली हैं।


3
बस तकनीकी शब्द जोड़ने के लिए: आप जो खोजने की कोशिश कर रहे हैं वह ग्राफ के जुड़े हुए घटक हैं, और मानक एल्गोरिथ्म है: (1) सभी नोड्स को एक सूची में रखें, (2) एक नोड चुनें, (3) BFS / DFS का उपयोग करके सभी जुड़े नोड्स, (4) सूची से आपके द्वारा पाए गए सभी नोड्स को हटाते हैं, (5) तब तक दोहराते हैं जब तक कि अधिक नोड्स शेष न हों।
नाथन रीड

3

एक मानक ग्राफ कनेक्टिविटी समस्या की तरह लगता है। इसके लिए कुछ प्रकार के एल्गोरिदम हो सकते हैं, और यह निम्नलिखित की तरह लग सकता है:

remaining units = all units
for each unit in remaining units:
    current group = create a new group
    add this unit to current group
    for each unit visible to this unit:
        if unit is in a group already:
            merge current group into that existing group
            set current group as that existing group
        else:
            remove that unit from remaining units
            add that unit to current group

मुझे उम्मीद है कि यह पेड़ के माध्यम से इसे लागू करना संभव है, जैसे कि पदानुक्रमित क्लस्टरिंग, लेकिन मुझे संदेह है कि जल्दी काम करेगा - पेड़ ओ (लॉग एन) होते हैं जबकि मैं ऊपर दिए गए अधिकांश चेक ओ (1) के रूप में लागू किया जा सकता है। ।


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

यह वही है जिसे मैंने अपने ओपी में भोले-भाले कार्यान्वयन के रूप में संदर्भित किया है । यह जानकर अच्छा लगा कि यह उतना बुरा नहीं होगा जितना मैंने सोचा था! :)
मैक

जिस तरह से आप इसे एक पेड़ के रूप में करते हैं वह पथ संपीड़न के साथ एक संघ सेट का उपयोग करना है । यह बहुत अच्छा नहीं है, और वास्तव में इष्टतम है।
पीटर टेलर

2

मैं उन सभी लोगों से सहमत हूं जिन्होंने इस संबंध में एक ग्राफ कनेक्टिविटी समस्या के रूप में जवाब दिया, हालांकि मुझे यह बताने की आवश्यकता है कि आपके सभी प्रासंगिक इकाइयों से उत्पन्न Delaunay त्रिभुज ग्राफ़ क्या है । यह क्या करता है यह सुनिश्चित करता है कि केवल एक दूसरे के सबसे करीब इकाइयां आपके द्वारा उत्पन्न ग्राफ में जुड़ी रहेंगी। आपको इसे किसी भी अन्य तरीके से करना बहुत चुनौतीपूर्ण लगेगा, क्योंकि ग्राफ़ क्रॉसिंग (गैर-प्लैनरिटी) इकाइयों को एक दूसरे से बहुत दूर तक ग्राफ़ के भीतर गलत तरीके से जुड़े होने का कारण होगा।

उपरोक्त केवल तभी लागू होता है यदि आप एक निरंतर स्थान का उपयोग कर रहे हैं (जैसा कि अधिकांश मुक्त-आंदोलन एफपीएस में); हालाँकि, यदि आपके पास पहले से ही एक अंतर्निहित ग्रिड (एक प्लैनर ग्राफ) है, जिस पर आपकी इकाइयाँ चलती हैं, तो आप इसका उपयोग केवल कनेक्टिविटी के मूल्यांकन के लिए कर सकते हैं।

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