2015-08-25 6 views
6

मैं (घ) आयाम का एक ग्रिड, सभी आयामों डेल्टा का उपयोग कर = 0.25, अंक की एक ग्रिड सर्च कर रहे हैं प्रत्येक बिंदु पर जाकर एक बार केवल

इस ग्रिड का एक उदाहरण यह आंकड़ा है विभाजित हैं (यहाँ d 2 है, और प्रत्येक आयाम सामान्यीकृत 0-1 है):

enter image description here

प्रत्येक चौराहे को दर्शाता है 1 अंक, उदाहरण के लिए, बीच में बिंदु के रूप में प्रस्तुत किया जाता है:

double[] A={0.5, 0.5}; 

मेरा प्रश्न है: मैं इनपुट ग्रिड ए और उसके पड़ोसियों से शुरू होने से इस ग्रिड को खोजना चाहता हूं। फिर ऐसा करना जारी रखें। एक शर्त के साथ: प्रत्येक बिंदु केवल एक बार दौरा किया जाता है।

अधिक स्पष्ट करने के लिए, इस उदाहरण पर विचार करें: प्रारंभिक बिंदु है:

double[] A={0.5, 0.5}; 

तो, एक चेक किया गया है पहले, तो अपने पड़ोसियों को उत्पन्न किया और (कतार एक के आधार पर क्रमबद्ध किया जाता है एक पंक्ति में डाला जाता है समारोह एफ)।

enter image description here

यहाँ बिंदु एक अंधेरे चक्र है। इसके पड़ोसियों हरे रंग की सर्कल हैं:

{0.25, 0.25} 
{0.25, 0.5} 
{0.25, 0.75} 
.. 
.. 
.. 
{0.75, 0.75} 

अब, कतार खाली होने तक एल्गोरिदम लूप हो जाता है। लूप में, शीर्ष बिंदु हटा दिया जाता है (पॉप()), फिर चेक किया गया, उसके बाद पड़ोसियों कतार में जोड़े गए हैं।

enter image description here

उदाहरण के लिए, पहली पाश में, नीले वृत्त कतार में शीर्ष बिंदु हुआ। इसे कतार से हटा दिया गया है, फिर चेक किया गया है, उसके पड़ोसियों (लाल मंडल) उत्पन्न होते हैं और कतार में जोड़े जाते हैं।

समस्या यह है कि, मेरा कोड जो पड़ोसियों के अंक उत्पन्न करता है, यह नहीं जानता कि पिछले बिंदु का दौरा किया गया है या नहीं।

और मैं पहले देखे गए बिंदुओं की एक सूची नहीं रख सकता, और प्रत्येक बार जब कोई नया बिंदु उत्पन्न होता है (उच्च आयाम और उच्च रिज़ॉल्यूशन उदाहरण के साथ, डी = 8 और डेल्टा = 0.03125, यह हमेशा के लिए ले जाएगा!)

इस खोज एल्गोरिथ्म है:

public void search(int d, double delta, double[] inpoint) 
{ 
    Queue queue = new Queue(); 
    queue.push(inpoint); 

    while(!queue.isEmpty()) 
    { 
     // remove top point from Queue 
     double[] a = queue.pop(); 

     // Check point a and do some calculations 
     // ;;;;;;;;;;;;;;;; 

     // Generate neighbours of current point: 
     ArrayList<double[]> neighbors = new ArrayList<double[]>(); 
     nextMoves(a, new double[d], delta, d, neighbors); 

     // For each point in neighbors, push to Queue: 
     for(int i=0 ; i < neighbors.size(), i++) 
      queue.push(neighbors.get(i)); 
    } 
} 

और यह पड़ोसियों पैदा करने के लिए एल्गोरिथ्म है, यह पुनरावर्ती एल्गोरिदम है।

public static void nextMoves(double[] inatt, double[] outatt, double delta, int d, ArrayList<double[]> neighbors) 
{ 
    if(d == inatt.length) 
    { 
     if(!outOfBound(outatt,d)) 
     { 
      moves.add(outatt); 
     } 
    } 
    else 
    { 
     // first case: add delta: 
     outatt[d] = inatt[d]+delta; 
     nextMoves(inatt, outatt, delta, d+1, moves); 

     // second case: subtract delta: 
     outatt[d] = inatt[d]-delta; 
     nextMoves(inatt, outatt, delta, d+1, moves); 

     // third case: no change: 
     outatt[d] = inatt[d]; 
     nextMoves(inatt, outatt, delta, d+1, moves); 
    } 
} 

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

शायद मुझे इस सूची को स्थानिक सूचकांक में व्यवस्थित करना चाहिए? मुझे नहीं पता ... मैं आपके इनपुट की सराहना करता हूं।

+0

क्या आप हमें बता सकते हैं कि आप प्रत्येक बिंदु पर कौन सा ऑपरेशन करना चाहते हैं? मुझे संदेह है कि कोई असली दुनिया की समस्या है जहां आप वहां कुछ भी किए बिना प्रत्येक बिंदु पर "यात्रा" करने की योजना बना रहे हैं। –

+0

'और इस सूची को प्रत्येक बार एक बिंदु बनाया गया है, तो रैखिक रूप से खोजना होगा' ... नहीं, आपको डुप्लिकेट पॉइंट की जांच करने के लिए पूरी सूची को खोजना नहीं होगा यदि आप बस बिंदु का उपयोग करके सरणी को _access_ कर सकते हैं सवाल। –

+1

क्या आपकी कतार कक्षा फीफो (पहली बार में पहली बार) है? और क्या यह जांचने की अनुमति देता है कि क्या कतार में तत्व पहले से मौजूद है या नहीं? –

उत्तर

0

संभावित शॉर्टकट के एक जोड़े आप विचार कर सकते हैं कर रहे हैं:

  1. आप अपने 'पहले देखी' की सूची में एक बार सभी आसपास के अंक जोड़ दिया गया है से अंक को दूर कर सकता है। तर्क सरल है: उन्हें केवल आसपास के बिंदुओं से जोड़ा जा सकता है। इसका मतलब है कि विज़िट किए गए वॉल्यूम की सतह केवल सूची में होना चाहिए। उच्च आयामों पर यह एक बड़ी बचत होगी।

  2. अधिक जटिल अंक के बजाय वॉल्यूम के आकार को स्टोर करना अधिक जटिल होगा। इसका अर्थ यह होगा कि वॉल्यूम की सतह पर प्रत्येक इन्फ्लिक्शन पॉइंट रिकॉर्ड करना और परीक्षण करना है कि प्रत्येक सतह पर उस बिंदु पर है।

पहला आसान है लेकिन कुशल नहीं है। मैं इसके साथ शुरू करने का सुझाव दूंगा और देख रहा हूं कि यह पर्याप्त है या नहीं।

0

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

आप क्लस्टरिंग के साथ भी शुरू कर सकते हैं। क्लस्टर लेआउट बनाएं और उपरोक्त सर्कल विधि के साथ इस क्लस्टर में खोजना शुरू करें।

0

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

+0

समस्या बहुआयामी और पूर्ण जुड़ा हुआ ग्राफ है। Djikstra एक अच्छा समाधान नहीं है क्योंकि यह 2 डी के लिए ठीक काम करता है और यदि आपके पास 8 डी नहीं है। आपको चींटी-एल्गोरिदम या कण स्वार अनुकूलन लेना होगा। लेकिन ये मेटाहेरिस्टिक्स हैं जो स्टोकैस्टिक तत्वों के साथ हैं और आपको हर रन के साथ इष्टतम समाधान नहीं दिया है। – MrT

संबंधित मुद्दे