2014-05-08 11 views
7

मैं यह पता लगाने की कोशिश कर रहा हूं कि एल्गोरिदम कैसे डिज़ाइन किया जाए जो ओ ((एन + एस) लॉग एन) जटिलता के साथ इस कार्य को पूरा कर सके। चौराहे की मात्रा होने के नाते। मैंने इंटरनेट पर खोज करने की कोशिश की है, फिर भी वास्तव में कुछ नहीं मिल सका।ओ ((एन + एस) लॉग एन में कंप्यूटिंग सर्कल चौराहे)

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

मुझे पहले अपना सेटअप समझाएं।

मेरे पास शेड्यूलर है। यह प्राथमिकता है क्योंकि मेरी मंडलियों ने अपने सबसे बाएं समन्वय के आधार पर आदेश दिया (आरोही)। scheduler.next() मूल रूप से प्राथमिकता क्यूयू का चुनाव करता है, जो अगले सबसे बाएं सर्कल को लौटता है।

public Circle next() 
{ return this.pq.poll(); } 

मेरे यहां 4 एन ईवेंट पॉइंट्स के साथ एक सरणी भी है। प्रत्येक सर्कल को अनुदान में 2 इवेंट पॉइंट होते हैं: अधिकांश बाएं एक्स और सबसे दाएं एक्स। अगली घटना बिंदु प्राप्त करने के लिए शेड्यूलर में एक विधि स्वीपलाइन() है।

public Double sweepline() 
{ return this.schedule[pointer++]; } 

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

मैंने स्थिति को TreeMap<Double, Circle> के साथ लागू किया। circle.getMostLeftCoord().

यह वृक्ष मानचित्र डालने/निकालने/खोजने के लिए ओ (लॉग एन) की गारंटी देता है।

एल्गोरिथ्म ही इसलिए की तरह कार्यान्वित किया जाता है:

Double sweepLine = scheduler.sweepline(); 
Circle c = null; 
while (notDone){ 
    while((!scheduler.isEmpty()) && (c = scheduler.next()).getMostLeftCoord() >= sweepLine) 
     status.add(c); 


    /* 
    * Delete the oldest circles that the sweepline has left behind 
    */ 
    while(status.oldestCircle().getMostRightCoord() < sweepLine) 
     status.deleteOldest(); 

    Circle otherCircle; 
    for(Map.Entry<Double, Circle> entry: status.keys()){ 
     otherCircle = entry.getValue(); 
     if(!c.equals(otherCircle)){ 
      Intersection[] is = Solver.findIntersection(c, otherCircle); 
      if(is != null) 
       for(Intersection intersection: is) 
        intersections.add(intersection); 
     } 
    } 

    sweepLine = scheduler.sweepline(); 
} 

संपादित करें: Solver.findIntersection(c, otherCircle); रिटर्न अधिकतम 2 चौराहे अंक। ओवरलैपिंग सर्कल को कोई चौराहे नहीं माना जाता है।

SweepLineStatus

public class BetterSweepLineStatus { 

TreeMap<Double, Circle> status = new TreeMap<Double, Circle>(); 

public void add(Circle c) 
{ this.status.put(c.getMostLeftCoord(), c);  } 

public void deleteOldest() 
{ this.status.remove(status.firstKey()); } 

public TreeMap<Double, Circle> circles() 
{ return this.status;  } 

public Set<Entry<Double, Circle>> keys() 
{ return this.status.entrySet(); } 

public Circle oldestCircle() 
{ return this.status.get(this.status.firstKey()); } 

मैं अपने कार्यक्रम का परीक्षण किया की कोड, और मैं स्पष्ट रूप से हे था (एन^2) जटिलता। मुझे यहां क्या याद आ रही है? कोई भी इनपुट जो आप लोग प्रदान करने में सक्षम हो सकते हैं, स्वागत से अधिक है।

अग्रिम धन्यवाद!

+0

"और मुझे स्पष्ट रूप से ओ (एन^2) जटिलता थी" - प्रोग्राम चलाने से बताना असंभव है, क्योंकि अन्यथा आप रोक समस्या को हल कर सकते हैं। –

+0

आप ओ ओ (एन लॉग एन) 'समय में विमान में' एन' सर्कल के सभी चौराहे बिंदु चाहते हैं, है ना? सर्कल पर कोई बाधा नहीं है? –

+0

यह सबूत नहीं है। यह सिर्फ प्रयोगात्मक डेटा है। –

उत्तर

6

आप नहीं O(n log n) समय में विमान में n हलकों के सभी चौराहे अंक प्राप्त कर सकते हैं हलकों की प्रत्येक जोड़ी के दो अलग-अलग चौराहे अंक तक हो सकती हैं और इसलिए n हलकों अप करने के लिए n² - n अलग चौराहे अंक हो सकता है और इसलिए वे नहीं कर सकते क्योंकि O(n log n) समय में गणना की जानी चाहिए।

एक तरह से n² - n चौराहे बिंदुओं की अधिकतम संख्या प्राप्त करने के लिए लंबाई l < 2r की एक पंक्ति का पारस्परिक रूप से विभिन्न बिंदुओं पर बराबर त्रिज्या r की n हलकों के केन्द्रों जगह है।

Intersecting circles

+0

मंडलियों की व्यवस्था करने के तरीके पर अंतर्ज्ञान के लिए mcdowella का उत्तर देखें। –

+3

प्रश्न अभी भी मान्य है, लेकिन शल्ड फिर से तैयार किया गया है: ओ (nlogn + k) में सर्कल-चौराहे की गणना, जहां n मंडलियों की संख्या है, और के चौराहे की संख्या है। –

4

उसी केंद्र और त्रिज्या के साथ एन सर्किलों में एन (एन -1)/2 जोड़े को घेरने वाले सर्कल होंगे, जबकि बड़ी पर्याप्त सर्कल का उपयोग करके उनकी सीमाएं लगभग सीधी रेखाएं हैं, आप एन/2 के साथ ग्रिड खींच सकते हैं लाइनें एन/2 लाइनों में से प्रत्येक को छेड़छाड़ करती हैं, जो फिर से एन^2 है। जब आप एक नया सर्कल जोड़ते हैं तो मैं देखता हूं और देखता हूं कि आपके मानचित्र में कितनी प्रविष्टियां आम तौर पर मौजूद होती हैं।

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

+1

मुझे लगता है कि मंडलियों की व्यवस्था सर्किल के त्रिज्या पर किसी भी प्रतिबंध के लिए की जा सकती है क्योंकि सुझाई गई स्थिति को "स्केल" करना चाहिए। –

+0

@GBach - मुझे लगता है कि आप सही हैं। आकार और रिश्तेदार पदों के संयोजन के रूप में यह वास्तव में मंडलियों के आकार का सवाल नहीं है। मुझे बस एक सर्कल के बगल में खड़े होने के बारे में सोचने के लिए सुविधाजनक लगता है, जो कि मेरी तुलना में इतना बड़ा था कि मैं देख सकता था कि मैं सीधे सीधी रेखा की तरह दिखता हूं। – mcdowella

0

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

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