2016-12-10 13 views
5

गहराई-प्रथम पेड़ ट्रेवर्सल का एक उदाहरण:उपज का उपयोग करके पेड़ के ट्रैवर्सल की समय जटिलता क्या है?

class Node: 
    def __init__(self, value): 
     self._value = value 
     self._children = [] 

    def add_child(self, child): 
     self._children.append(child) 

    def __iter__(self): 
     return iter(self._children) 

    def depth_first(self): 
     yield self 
     for c in self: 
      yield from c.depth_first() 

मैं समझता हूँ कि yield from जनरेटर का उपभोग नहीं करता है अभी, लेकिन इसके बजाय अपने फोन करने वाले को ऊपर की ओर yield गुजरती हैं।

लेकिन गुजर की इस प्रक्रिया को अभी भी मौजूद है, और इस तरह yield नीचे से ऊपर तक उसकी जड़ के लिए हर नोड से पारित हो जाएगा, और हम (पुनरावृत्ति से चल रहा है समय का वर्णन कर सकते यह सादगी के लिए एक द्विआधारी पेड़ है मान , लेकिन यह विचार एक ही है):

टी (एन) = 2 * टी (एन/2) + Θ (एन)

Θ(n) मौजूद है क्योंकि इस नोड सभी yield पारित करने के लिए है अपने संतानों से अपने माता-पिता को पास कर दिया। और समय जटिलता उपरोक्त सूत्र से प्राप्त होता है:

ओ (nlogn)

हालांकि, पेड़ ट्रेवर्सल के समय जटिलता केवल O(n) है अगर मैं yield या yield from बिल्कुल प्रयोग नहीं करते।

मुझे आश्चर्य है कि क्या मुझे गलत लगता है कि yield काम करता है या इस तरह एक पुनरावर्ती जनरेटर लिखना संभव नहीं है।

+0

आपके फॉर्मूला में Θ (एन) नहीं होना चाहिए Θ (1)? एक संतुलित पेड़ स्थिर में एक नोड की संतान की संख्या नहीं है? – DyZ

+0

@DYZ मुझे लगता है कि यह Θ (एन) होना चाहिए। यह संतानों की संख्या को पारित नहीं करता है, लेकिन अपने सभी संतानों से 'उपज' बयान पास करता है। –

+0

क्या 'इसके सभी संतान' में संतान की संतान शामिल है, आदि? (मुझे लगता है कि यह नहीं करता है।) यदि नहीं, तो यह अभी भी स्थिर है। – DyZ

उत्तर

1
yield from के लिए

आधिकारिक पायथन 3.3 रिलीज से: https://www.python.org/dev/peps/pep-0380/

एक विशेष वाक्य रचना का उपयोग अनुकूलन के लिए संभावनाओं को खोलता है जब वहाँ जनरेटर की एक लंबी श्रृंखला है। उदाहरण के लिए, इस तरह की श्रृंखलाएं उत्पन्न हो सकती हैं, जब एक पेड़ संरचना को दोबारा घुमाते हैं। उत्तीर्ण () कॉल को नीचे और ऊपर मूल्यों को ऊपर और ऊपर लाए गए मूल्यों को ओ (एन) ऑपरेशन होना चाहिए, सबसे खराब केस, ओ (एन ** 2) में हो सकता है।

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

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

ऐसा लगता है कि yield from अभी भी पेड़ को पार करने की आवश्यकता है। लेकिन वह ट्रैवर्सिंग पाइथन में बजाय सी में दुभाषिया द्वारा किया जाता है।तो तकनीकी रूप से यह अभी भी एक ओ (एन) ओवरहेड है, लेकिन यह उतना बुरा नहीं है जितना लगता है।

+0

क्या यह एक हल मुद्दा है, या वे अभी भी इस पर काम कर रहे हैं? –

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