फिबोनाची अनुक्रम कैसे लिखें?


140

मैंने मूल रूप से प्रोग्राम को गलत तरीके से कोड किया था। एक सीमा के बीच फाइबोनैचि संख्याओं को वापस करने के बजाय (जैसे। प्रारंभ 1, एंड नम्बर 20 चाहिए = केवल 1 और 20 के बीच की संख्या), मैंने प्रोग्राम के लिए सभी फाइबोनैचि संख्याओं को एक सीमा के बीच प्रदर्शित करने के लिए लिखा है। प्रदर्शित करता है = पहले 20 फाइबोनैचि संख्या)। मुझे लगा कि मेरे पास एक पक्का फायर कोड है। मैं यह भी नहीं देखता कि ऐसा क्यों हो रहा है।

startNumber = int(raw_input("Enter the start number here "))
endNumber = int(raw_input("Enter the end number here "))

def fib(n):
    if n < 2:
        return n
    return fib(n-2) + fib(n-1)

print map(fib, range(startNumber, endNumber))

किसी ने मेरे भाग II में (जो एक डुप्लिकेट होने के लिए बंद किया गया था - /programming/504193/how-to-write-the-fibnote-fterence-in-python-part-ii- कि मैं थोड़ी देर लूप का उपयोग करके जनरेटर के माध्यम से स्टार्टर और एंडनंबर को पास करने की आवश्यकता है क्या कोई मुझे इस दिशा में बता सकता है कि यह कैसे करना है? किसी भी मदद का स्वागत है।


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

मेरे पास अब तक कोई वास्तविक कोडिंग नहीं है, बल्कि:

  • अनंत तक फ़ाइब अनुक्रम सूत्र लिखें
  • केवल Fib अनुक्रम से अंत करने के लिए startNumber प्रदर्शित करें।

मुझे पता नहीं है कि कहां से शुरू करना है और मैं इसे लिखने के तरीके में विचार या अंतर्दृष्टि के लिए पूछ रहा हूं। मैंने फिब सीक्वेंस फोरमला लिखने की भी कोशिश की है लेकिन मैं उस पर भी हार जाता हूं।

जवाबों:


257

विकिपीडिया पर और वुल्फराम पर फिबोनाची अनुक्रम के बारे में बहुत सारी जानकारी है । आपकी आवश्यकता से बहुत अधिक। वैसे भी यह सीखने के लिए एक अच्छी बात है कि इन संसाधनों का उपयोग कैसे करें (जल्दी से संभव हो तो) आपको क्या चाहिए।

अनंत तक फ़ाइब अनुक्रम सूत्र लिखें

गणित में, यह एक पुनरावर्ती रूप में दिया गया है:

विकिपीडिया से रिटायर

प्रोग्रामिंग में, अनंत मौजूद नहीं है। आप अपनी भाषा में सीधे गणित के रूप में अनुवाद करने वाले एक पुनरावर्ती रूप का उपयोग कर सकते हैं, उदाहरण के लिए पायथन में यह हो जाता है:

def F(n):
    if n == 0: return 0
    elif n == 1: return 1
    else: return F(n-1)+F(n-2)

इसे अपनी पसंदीदा भाषा में आज़माएँ और देखें कि इस रूप को बहुत समय की आवश्यकता है क्योंकि n बड़ा हो जाता है। वास्तव में, यह समय में ओ (2 एन ) है।

उन साइटों पर जाएं जिनसे मैंने आपको जोड़ा है और इसे ( भेड़ियाग्राम पर ) देखेंगे :

फाइबोनैचि समीकरण

यह एक बहुत ही आसान है जिसे लागू करना और बहुत, बहुत तेजी से गणना करना, पायथन में:

from math import sqrt
def F(n):
    return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))

इसे करने का दूसरा तरीका परिभाषा ( विकिपीडिया से ) का अनुसरण कर रहा है :

अनुक्रम की पहली संख्या 0 है, दूसरी संख्या 1 है, और प्रत्येक बाद की संख्या अनुक्रम के पिछले दो संख्याओं के योग के बराबर है, क्रम 0, 1, 1, 2, 3, 5, 8 को पैदावार , आदि।

यदि आपकी भाषा पुनरावृत्तियों का समर्थन करती है तो आप कुछ ऐसा कर सकते हैं:

def F():
    a,b = 0,1
    while True:
        yield a
        a, b = b, a + b

केवल Fib अनुक्रम से अंत करने के लिए startNumber प्रदर्शित करें।

एक बार जब आप जानते हैं कि फाइबोनैचि संख्याओं को कैसे उत्पन्न किया जाता है, तो आपको केवल संख्याओं को चक्रित करना होगा और जांचना होगा कि क्या वे दिए गए शर्तों को सत्यापित करते हैं।

मान लीजिए कि अब आपने एफ (n) लिखा है जो फिबोनाची अनुक्रम का एन-वें शब्द देता है (जैसे कि sqrt (5) के साथ)

अधिकांश भाषाओं में आप कुछ ऐसा कर सकते हैं:

def SubFib(startNumber, endNumber):
    n = 0
    cur = f(n)
    while cur <= endNumber:
        if startNumber <= cur:
            print cur
        n += 1
        cur = f(n)

अजगर में मैं पुनरावृत्त रूप का उपयोग करूंगा और इसके लिए जाऊंगा:

def SubFib(startNumber, endNumber):
    for cur in F():
        if cur > endNumber: return
        if cur >= startNumber:
            yield cur

for i in SubFib(10, 200):
    print i

मेरा संकेत यह पढ़ना सीखना है कि आपको क्या चाहिए। प्रोजेक्ट यूलर (इसके लिए गूगल) आपको ऐसा करने के लिए प्रशिक्षित करेगा: पी गुड लक और मज़े करो!


1
आपको थोड़ी देर लूप का उपयोग करने की आवश्यकता है, न कि नक्शा। अपने दम पर यह पता लगाने की कोशिश करें, अगर आप ऐसा नहीं कर सकते तो कोड के साथ वापस आ जाएं। मैं आलसी नहीं हूं (कोड इस टिप्पणी से छोटा है)। मैं आपके लिए ऐसा कर रहा हूं, इसे "जबकि" संकेत के साथ आज़माएं; यदि आपको उस समस्या के साथ फिर से वापस आना है;)
एंड्रिया अंबू

मैं वापस आ गया हूँ, योग्य। मैं मानचित्र (रेंज) फ़ंक्शन से छुटकारा पा गया और केवल एक रेंज (स्टार्टरन, एंडनंबर) फ़ंक्शन का उपयोग कर रहा हूं। अब मेरे पास समस्या यह है कि मैं कथन का उपयोग कहां करूं। मैं समारोह की शुरुआत में कोशिश करता हूं, लेकिन निश्चित रूप से एक बिलिन त्रुटि की एक पंक्ति है। मुझे इसे कहां रखा जाना चाहिए? Thx
एसडी।

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

1
हमें int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))किसी भी विचार का उपयोग करना चाहिए ? @AndreaAmbu
लॉर्ड63। j

3
@ lord63.j, आपको केवल उस सूत्र का उपयोग करना चाहिए, यदि आप जानते हैं कि यह वास्तविक मूल्य से भटकना शुरू कर देता है जब n70 से ऊपर होता है और OverflowError जब n600 से थोड़ा ऊपर होता है तो उड़ाता है। अन्य दृष्टिकोण n1000 या उससे अधिक को बिना उड़ाए संभाल सकते हैं। सटीक या खोना।
cdlane 20

66

फाइबोनैचि अनुक्रम के कुशल पाइथोनिक जनरेटर

इस क्रम में सबसे कम पायथनिक पीढ़ी प्राप्त करने की कोशिश करते हुए मुझे यह सवाल मिला (बाद में एहसास हुआ कि मैंने पायथन एन्हांसमेंट प्रस्ताव में एक समान देखा था ), और मैंने किसी और को अपने विशिष्ट समाधान के साथ आने पर ध्यान नहीं दिया (हालांकि शीर्ष उत्तर पास हो जाता है, लेकिन अभी भी कम सुरुचिपूर्ण है), इसलिए यहां यह है, पहली पुनरावृत्ति का वर्णन करने वाली टिप्पणियों के साथ, क्योंकि मुझे लगता है कि इससे पाठकों को मदद मिल सकती है:

def fib():
    a, b = 0, 1
    while True:            # First iteration:
        yield a            # yield 0 to start with and then
        a, b = b, a + b    # a will now be 1, and b will also be 1, (0 + 1)

और उपयोग:

for index, fibonacci_number in zip(range(10), fib()):
     print('{i:3}: {f:3}'.format(i=index, f=fibonacci_number))

प्रिंट:

  0:   0
  1:   1
  2:   1
  3:   2
  4:   3
  5:   5
  6:   8
  7:  13
  8:  21
  9:  34
 10:  55

(एट्रिब्यूशन उद्देश्यों के लिए, मैंने हाल ही में मॉड्यूल पर पायथन प्रलेखन में एक समान कार्यान्वयन देखा , यहां तक ​​कि चर का उपयोग करते हुए aऔर b, जिसे अब मुझे यह उत्तर लिखने से पहले देखा गया है। लेकिन मुझे लगता है कि यह उत्तर भाषा के बेहतर उपयोग को प्रदर्शित करता है।)

पुनरावर्ती रूप से परिभाषित कार्यान्वयन

पूर्णांक दृश्यों ऑनलाइन इनसाइक्लोपीडिया ऑफ़ फाइबोनैचि अनुक्रम रिकर्सिवली को परिभाषित करता है के रूप में

एफ (एन) = एफ (एन -1) + एफ (एन -2) के साथ एफ (0) = 0 और एफ (1) 1

पायथन में इस पुनरावर्ती रूप से स्पष्ट रूप से परिभाषित किया जा सकता है:

def rec_fib(n):
    '''inefficient recursive function as defined, returns Fibonacci number'''
    if n > 1:
        return rec_fib(n-1) + rec_fib(n-2)
    return n

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

for i in range(40):
    print(i, rec_fib(i))

दक्षता के लिए पुनरावृत्ति को याद किया

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

def mem_fib(n, _cache={}):
    '''efficiently memoized recursive function, returns a Fibonacci number'''
    if n in _cache:
        return _cache[n]
    elif n > 1:
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

आपको पता चल जाएगा कि संस्मरणित संस्करण बहुत तेज़ है, और इससे पहले कि आप कॉफ़ी के लिए उठने के बारे में सोच सकें उससे पहले आपकी अधिकतम पुनरावृत्ति गहराई से अधिक हो जाएगी। आप देख सकते हैं कि ऐसा करने से नेत्रहीन कितना तेज है:

for i in range(40):
    print(i, mem_fib(i))

(ऐसा लग सकता है कि हम बस नीचे कर सकते हैं, लेकिन यह वास्तव में हमें कैश का लाभ नहीं लेने देता है, क्योंकि यह सेटडेफॉल्ट कहे जाने से पहले खुद को कॉल करता है।)

def mem_fib(n, _cache={}):
    '''don't do this'''
    if n > 1:  
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

पुनरावर्ती रूप से परिभाषित जनरेटर:

जैसा कि मैं हास्केल सीख रहा हूं, मैं हास्केल में इस कार्यान्वयन पर आया हूं:

fib@(0:tfib) = 0:1: zipWith (+) fib tfib

इस समय मुझे लगता है कि मैं पायथन में सबसे करीब आ सकता हूं:

from itertools import tee

def fib():
    yield 0
    yield 1
    # tee required, else with two fib()'s algorithm becomes quadratic
    f, tf = tee(fib()) 
    next(tf)
    for a, b in zip(f, tf):
        yield a + b

यह इसे प्रदर्शित करता है:

[f for _, f in zip(range(999), fib())]

यह केवल पुनरावृत्ति सीमा तक जा सकता है, हालांकि। आमतौर पर, 1000, जबकि हास्केल संस्करण 100 से लाखों तक जा सकता है, हालांकि यह ऐसा करने के लिए मेरे लैपटॉप की सभी 8 जीबी मेमोरी का उपयोग करता है:

> length $ take 100000000 fib 
100000000

एनटीआर नंबर प्राप्त करने के लिए पुनरावृत्ति का उपभोग करना

एक टिप्पणीकार पूछता है:

Fib () फ़ंक्शन के लिए प्रश्न जो पुनरावृत्ति पर आधारित है: क्या होगा यदि आप nth प्राप्त करना चाहते हैं, उदाहरण के लिए 10 वें फ़ाइब नंबर?

Itertools प्रलेखन के लिए एक नुस्खा है:

from itertools import islice

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)

और अब:

>>> nth(fib(), 10)
55

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

@binithb setdefaultकॉल के अंदर की अभिव्यक्ति का मूल्यांकन पहले किया setdefault जाता है।
हारून हॉल


21

फाइबोनैचि अनुक्रम के पीछे का विचार निम्नलिखित पायथन कोड में दिखाया गया है:

def fib(n):
   if n == 1:
      return 1
   elif n == 0:   
      return 0            
   else:                      
      return fib(n-1) + fib(n-2)         

इसका मतलब यह है कि फाइब एक ऐसा फंक्शन है जो तीन में से एक काम कर सकता है। यह फ़ाइब (1) == 1, फ़ाइब (0) == 0 और फ़ाइबर (n) को परिभाषित करता है:

फ़ाइबर (n-1) + फ़ाइबर (n-2)

जहां n एक मनमाना पूर्णांक है। इसका मतलब है कि फ़ाइब (2) उदाहरण के लिए, निम्नलिखित अंकगणित तक फैलता है:

fib(2) = fib(1) + fib(0)
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(2) = 1 + 0
fib(2) = 1

हम नीचे दिखाए गए अंकगणित के साथ फाइब (3) की गणना कर सकते हैं:

fib(3) = fib(2) + fib(1)
fib(2) = fib(1) + fib(0)
fib(2) = 1
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(3) = 1 + 1 + 0

यहाँ महसूस करने के लिए महत्वपूर्ण बात यह है कि फ़ाइब (3) की गणना फ़ाइब (2) की गणना के बिना नहीं की जा सकती है, जिसकी गणना फ़ाइबर (1) और फ़ाइबर (0) की परिभाषाओं को जानकर की जाती है। किसी फंक्शन को कॉल करना, जैसे कि फंक्शन रिट्रोज़ करता है, को रिकर्सन कहते हैं, और यह प्रोग्रामिंग में एक महत्वपूर्ण विषय है।

यह एक होमवर्क असाइनमेंट की तरह लगता है इसलिए मैं आपके लिए शुरुआत / अंत भाग नहीं करने जा रहा हूं। पाइथन हालांकि इसके लिए एक शानदार अभिव्यंजक भाषा है, इसलिए इसका मतलब यह होना चाहिए कि यदि आप गणित को समझते हैं, और उम्मीद है कि आपको पुनरावृत्ति के बारे में सिखाएगा। सौभाग्य!

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


यह एक होमवर्क समस्या नहीं है, लेकिन उत्तर के लिए धन्यवाद वाह! मैं समझता हूं कि मुझे क्या करने की आवश्यकता है लेकिन इसे शुरू करना और लागू करना मैं अब पर अटक गया हूं (विशेषकर उपयोगकर्ता इनपुट मूल्यों को लागू करने के साथ)। क्या आप इसमें कुछ जानकारी दे सकते हैं? मैं 0x0141FAF0> त्रुटि पर एक <फ़ंक्शन फ़ाइब प्राप्त करता रहता हूं।
एस.डी.

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

मै समझता हुँ। क्या कोई अन्य विचार है जो आपको लगता है कि मुझे याद आ रहा है? मैं समझता हूँ कि क्या आप हालांकि मदद नहीं कर सकते। आपके समय के लिए धन्यवाद।
एस.डी.

0x0141FAF0 पर आपका <फ़ंक्शन फ़ाइब> त्रुटि "फ़ाइब" (जो फ़ंक्शन को संदर्भित करता है) के बजाय "फ़ाइब ()" जो फ़ंक्शन को कॉल करेगा, का परिणाम हो सकता है। शुभकामनाएँ।
किव

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

12

समय जटिलता:

कैशिंग विशेषता फिबोनासी श्रृंखला के पुनरावर्ती पेड़ में दोहराव को समाप्त करके ओ (2 ^ n) से ओ (एन) से फाइबोनैचि श्रृंखला की गणना करने के सामान्य तरीके को कम करती है :

यहां छवि विवरण दर्ज करें

कोड:

import sys

table = [0]*1000

def FastFib(n):
    if n<=1:
        return n
    else:
        if(table[n-1]==0):
            table[n-1] = FastFib(n-1)
        if(table[n-2]==0):
            table[n-2] = FastFib(n-2)
        table[n] = table[n-1] + table[n-2]
        return table[n]

def main():
    print('Enter a number : ')
    num = int(sys.stdin.readline())
    print(FastFib(num))

if __name__=='__main__':
    main()

9

यह ओ (लॉग एन) मूल अंकगणितीय संचालन का उपयोग करते हुए काफी कुशल है।

def fib(n):
    return pow(2 << n, n + 1, (4 << 2*n) - (2 << n) - 1) % (2 << n)

यह ओ (1) बुनियादी अंकगणितीय संचालन का उपयोग करता है, लेकिन मध्यवर्ती परिणामों का आकार बड़ा है और इसलिए यह सभी कुशल नहीं है।

def fib(n):
    return (4 << n*(3+n)) // ((4 << 2*n) - (2 << n) - 1) & ((2 << n) - 1)

यह एक बहुपद वलय Z [X] / / (X ^ 2 - X - 1) में एक्स ^ n की गणना करता है। उस गणना का परिणाम बहुपद Fib (n) X + Fib (n-1) है, जिससे nth फाइबोनैचि संख्या को पढ़ा जा सकता है।

फिर, यह O (लॉग एन) अंकगणितीय संचालन का उपयोग करता है और बहुत कुशल है।

def mul(a, b):
        return a[0]*b[1]+a[1]*b[0]+a[0]*b[0], a[0]*b[0]+a[1]*b[1]

def fib(n):
        x, r = (1, 0), (0, 1)
        while n:
                if n & 1: r = mul(r, x)
                x = mul(x, x)
                n >>= 1
        return r[0]

1
पहली और तीसरी तकनीक अच्छी हैं। दूसरी तकनीक 1 से बंद है; इसे प्रभावी n -= 1ढंग से सही ढंग से काम करने की आवश्यकता है, और यह भी काम नहीं करता है n = 0। किसी भी मामले में, यह वास्तव में मेरी मदद करेगा यदि यह समझाने के लिए कि यह कैसे काम कर रहा है, विशेष रूप से पहली तकनीक को जोड़ा गया। मैं देख रहा हूँ कि आपके पास एक पोस्ट है paulhankin.github.io/Fibnote
Acumenus

6

फाइबोनैचि अनुक्रम को मुद्रित करने के लिए कैनोनिकल पायथन कोड:

a,b=1,1
while True:
  print a,
  a,b=b,a+b       # Could also use b=a+b;a=b-a

समस्या के लिए "1000 अंकों से अधिक लंबे पहले फाइबोनैचि संख्या को प्रिंट करें":

a,b=1,1
i=1
while len(str(a))<=1000:
  i=i+1
  a,b=b,a+b

print i,len(str(a)),a

4

हम जानते हैं कि

यहां छवि विवरण दर्ज करें

और उस मैट्रिक्स की n- वीं शक्ति हमें देता है:

यहां छवि विवरण दर्ज करें

तो हम एक फ़ंक्शन को लागू कर सकते हैं जो बस उस मैट्रिक्स की शक्ति को n-वें -1 शक्ति तक गणना करता है।

जैसा कि हम सभी जानते हैं कि बिजली ए ^ एन के बराबर है

यहां छवि विवरण दर्ज करें

तो अंत में रिटायरमेंट फंक्शन O (n) होगा ... वास्तव में एक आसान कार्यान्वयन से अलग कुछ भी नहीं अगर यह इस तथ्य के लिए नहीं था कि हम यह भी जानते हैं कि x^n * x^n = x^2nऔर x^nइसलिए मूल्यांकन ओ जटिलता (लॉग एन) के साथ किया जा सकता है )

यहां स्विफ्ट प्रोग्रामिंग भाषा का उपयोग करते हुए मेरा रिट्रेसमेंट कार्यान्वयन है:

struct Mat {
    var m00: Int
    var m01: Int
    var m10: Int
    var m11: Int
}

func pow(m: Mat, n: Int) -> Mat {
    guard n > 1 else { return m }
    let temp = pow(m: m, n: n/2)

    var result = matMultiply(a: temp, b: temp)
    if n%2 != 0 {
        result = matMultiply(a: result, b: Mat(m00: 1, m01: 1, m10: 1, m11: 0))
    }
    return result
}

func matMultiply(a: Mat, b: Mat) -> Mat {
    let m00 = a.m00 * b.m00 + a.m01 * b.m10
    let m01 = a.m00 * b.m01 + a.m01 * b.m11
    let m10 = a.m10 * b.m00 + a.m11 * b.m10
    let m11 = a.m10 * b.m01 + a.m11 * b.m11

    return Mat(m00: m00, m01: m01, m10: m10, m11: m11)
}

func fibonacciFast(n: Int) -> Int {

    guard n > 0 else { return 0 }
    let m = Mat(m00: 1, m01: 1, m10: 1, m11: 0)

    return pow(m: m, n: n-1).m00
}

इसमें जटिलता ओ (लॉग एन) है। हम घातांक n-1 के साथ Q की o ofpower गणना करते हैं और फिर हम तत्व m00 लेते हैं जो कि Fn + 1 है जो कि पॉवर प्रतिपादक n-1 पर ठीक उसी तरह है जैसे हम चाहते थे।

एक बार जब आपके पास तेजी से रिटायरमेंट फ़ंक्शन होता है, तो आप उस आरंभ संख्या और अंतिम संख्या से पुनरावृत्ति कर सकते हैं, जिसमें आप रुचि रखने वाले फिबोनाची अनुक्रम का हिस्सा प्राप्त कर सकते हैं।

let sequence = (start...end).map(fibonacciFast)

बेशक पहले यह सुनिश्चित करने के लिए कि वे एक वैध सीमा बना सकते हैं, शुरू और अंत में कुछ जांच करें।

मुझे पता है कि प्रश्न 8 साल पुराना है, लेकिन मुझे वैसे भी जवाब देने में मज़ा आया। :)


3

फाइबोनैचि अनुक्रम है: 1, 1, 2, 3, 5, 8, ...

है यही कारण है कि f(1) = 1, f(2) = 1, f(3) = 2, ..., f(n) = f(n-1) + f(n-2)

मेरा पसंदीदा कार्यान्वयन (सबसे सरल और अभी तक अन्य कार्यान्वयन की तुलना में एक हल्की गति प्राप्त करता है) यह है:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(1, n):
        a, b = b, a + b
    return b

परीक्षा

>>> [fibonacci(i) for i in range(1, 10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34]

समय

>>> %%time
>>> fibonacci(100**3)
CPU times: user 9.65 s, sys: 9.44 ms, total: 9.66 s
Wall time: 9.66 s

संपादित करें: इस कार्यान्वयन के लिए एक उदाहरण दृश्य


3

पुनरावर्तन का उपयोग करें:

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
x=input('which fibonnaci do you want?')
print fib(x)

2

इसे करने का दूसरा तरीका:

a,n=[0,1],10
map(lambda i: reduce(lambda x,y: a.append(x+y),a[-2:]),range(n-2))

'ए' को सूची सौंपना, 'एन' मैप को पूर्णांक निर्दिष्ट करना और कम करना अजगर में तीन सबसे शक्तिशाली कार्यों में से 2 हैं। यहां मानचित्र का उपयोग केवल 'n-2' बार पुन: व्यवस्थित करने के लिए किया जाता है। [[-2:] में किसी सरणी के अंतिम दो तत्व मिलेंगे। a.append (x + y) अंतिम दो तत्वों को जोड़ देगा और सरणी में जोड़ देगा


1

ये सभी होने की तुलना में थोड़ा अधिक जटिल लगते हैं। मेरा कोड बहुत सरल और तेज़ है:

def fibonacci(x):

    List = []
    f = 1
    List.append(f)
    List.append(f) #because the fibonacci sequence has two 1's at first
    while f<=x:
        f = List[-1] + List[-2]   #says that f = the sum of the last two f's in the series
        List.append(f)
    else:
        List.remove(List[-1])  #because the code lists the fibonacci number one past x. Not necessary, but defines the code better
        for i in range(0, len(List)):
        print List[i]  #prints it in series form instead of list form. Also not necessary

2
गतिशील प्रोग्रामिंग FTW! फरिश्ते (100000000000000000000000000000000000000000000000000000000000000000) लगभग तुरंत जवाब देते हैं
हंस

6
किसी तरह मुझे शक हुआ।
लनरु

सूची को शुरू करने के बारे में क्या [0, 1] (यानी List.append (0); List.append (1)) के बाद हटाए गए कमांड से बचने के लिए? ... और रिट्रेसमेंट नंबर को बेहतर लिपिबद्ध किया जाना चाहिए क्योंकि फ़ोटोग्राफ़ी (10) 10 से नीचे की रिट्रेसमेंट संख्याओं को लौटाती है, 10-वें वाले को नहीं।
सेफ़

1

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

def fibonacci():
    start = 0 
    i = 1 
    lt = []
    lt.append(start)
    while start < 10000:
        start += i
        lt.append(start)
        i = sum(lt[-2:])
        lt.append(i)
    print "The Fibonaccii series: ", lt

यह दृष्टिकोण भी अच्छा प्रदर्शन करता है। नीचे रन एनालिटिक्स ढूंढें

In [10]: %timeit fibonacci
10000000 loops, best of 3: 26.3 ns per loop

1

यह मैथ्यू हेनरी के जवाब में सुधार है:

def fib(n):
    a = 0
    b = 1
    for i in range(1,n+1):
            c = a + b
            print b
            a = b
            b = c

कोड को मुद्रण c के बजाय b प्रिंट करना चाहिए

आउटपुट: 1,1,2,3,5 ....


1

लूप का उपयोग करना और परिणाम को प्रिंट करना

def fib(n:'upto n number')->int:
    if n==0:
        return 0
    elif n==1:
        return 1
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
    return b

परिणाम

>>>fib(50)
12586269025
>>>>
>>> fib(100)
354224848179261915075
>>> 

listसभी नंबरों को प्रिंट करें

def fib(n:'upto n number')->int:
    l=[0,1]
    if n==0:
        return l[0]
    elif n==1:
        return l
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
        l.append(b)
    return l

परिणाम

>>> fib(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1
import time
start_time = time.time()



#recursive solution
def fib(x, y, upperLimit):
    return [x] + fib(y, (x+y), upperLimit) if x < upperLimit else [x]

#To test :

print(fib(0,1,40000000000000))
print("run time: " + str(time.time() - start_time))

परिणाम

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368 , 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24151517, 39088169, 63245986, 102334155, 16558016, 26798336, 26798336336 , 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 22585143371717, 365435296162, 59128672929879, 956722026041, 1548008755920, 1047778781961, 2047778781761, 2047778172, 203371761

रन टाइम: 0.04298138618469238


1

यह महसूस करने के लिए एक बहुत ही आसान तरीका है!

आप http://www.learnpython.org/ का उपयोग करके इस कोड को स्वतंत्र रूप से ऑनलाइन चला सकते हैं

# Set the variable brian on line 3!

def fib(n):
"""This is documentation string for function. It'll be available by fib.__doc__()
Return a list containing the Fibonacci series up to n."""
result = []
a = 0
b = 1
while a < n:
    result.append(a)  # 0 1 1 2 3 5  8  (13) break
    tmp_var = b       # 1 1 2 3 5 8  13
    b = a + b         # 1 2 3 5 8 13 21
    a = tmp_var       # 1 1 2 3 5 8  13
    # print(a)
return result

print(fib(10))
# result should be this: [0, 1, 1, 2, 3, 5, 8]

किसी भी जटिल पुनरावृत्ति डेटा संरचना के बिना, इटरेटर का उपयोग करके फाइबोनैचि श्रृंखला को महसूस करने का एक आसान तरीका!
xgqfrms

1

यह निम्नलिखित तरीके से किया जा सकता है।

n = 0

संख्या = [0]

मैं सीमा में (0,11):
    प्रिंट एन,
    numbers.append (एन)
    prev = संख्या [-2]
    यदि n == 0:
        एन = 1
    अन्य:
        n = n + प्रबल

1

सिर्फ मनोरंजन के लिए, Python 3.8+ में आप सूची बोध में एक असाइनमेंट एक्सप्रेशन (वालरस ऑपरेटर उर्फ) का उपयोग कर सकते हैं , जैसे:

>>> a, b = 0, 1
>>> [a, b] + [b := a + (a := b) for _ in range(8)]  # first 10 Fibonacci numbers
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

एक असाइनमेंट एक्सप्रेशन आपको किसी वैरिएबल पर वैल्यू असाइन करने और उसी एक्सप्रेशन में वापस करने की अनुमति देता है । इसलिए, अभिव्यक्ति

b := a + (a := b)

निष्पादित करने के बराबर है

a, b = b, a + b

और का मान लौटा रहा है b


0

पाइथन सीखने के दौरान मैंने एक ट्यूटोरियल में 15 मिनट, इसने पाठक को एक प्रोग्राम लिखने के लिए कहा, जो 3 इनपुट नंबरों (पहले फाइबोनैचि संख्या, दूसरा नंबर, और उस क्रम को रोकने के लिए जिस पर) से फाइबोनैचि अनुक्रम की गणना करेगा। ट्यूटोरियल में केवल चरों को कवर किया गया था, यदि / thens, और लूप्स उस बिंदु तक। अभी तक कोई कार्य नहीं। मैं निम्नलिखित कोड के साथ आया:

sum = 0
endingnumber = 1                

print "\n.:Fibonacci sequence:.\n"

firstnumber = input("Enter the first number: ")
secondnumber = input("Enter the second number: ")
endingnumber = input("Enter the number to stop at: ")

if secondnumber < firstnumber:

    print "\nSecond number must be bigger than the first number!!!\n"

else:

while sum <= endingnumber:

    print firstnumber

    if secondnumber > endingnumber:

        break

    else:

        print secondnumber
        sum = firstnumber + secondnumber
        firstnumber = sum
        secondnumber = secondnumber + sum

जैसा कि आप देख सकते हैं, यह वास्तव में अक्षम है, लेकिन यह काम करता है।


0
def fib():
    a,b = 1,1
    num=eval(input("Please input what Fib number you want to be calculated: "))
    num_int=int(num-2)
    for i in range (num_int):
        a,b=b,a+b
    print(b)

3
eval(input())यहाँ जरूरत नहीं है; मुझे लगता int(input())है कि मामले में बेहतर है।
जिंजरप्लस

0

बस http://projecteuler.net/problem=2 के माध्यम से जा रहा है यह इस पर मेरा लेना था

# Even Fibonacci numbers
# Problem 2

def get_fibonacci(size):
    numbers = [1,2]
    while size > len(numbers):
        next_fibonacci = numbers[-1]+numbers[-2]
        numbers.append(next_fibonacci)

    print numbers

get_fibonacci(20)

0
def fib(x, y, n):
    if n < 1: 
        return x, y, n
    else: 
        return fib(y, x + y, n - 1)

print fib(0, 1, 4)
(3, 5, 0)

#
def fib(x, y, n):
    if n > 1:
        for item in fib(y, x + y, n - 1):
            yield item
    yield x, y, n

f = fib(0, 1, 12)
f.next()
(89, 144, 1)
f.next()[0]
55

0

शायद इससे मदद मिलेगी

def fibo(n):
    result = []
    a, b = 0, 1
    while b < n:
            result.append(b)
            a, b = b, b + a
    return result

0

केवल क्लासिक-लाइन अनुक्रम के आधार पर और वन-लाइनर्स के लिए

यदि आपको केवल सूचकांक की संख्या की आवश्यकता है, तो आप कम का उपयोग कर सकते हैं (भले ही कम करें यह इसके लिए सबसे उपयुक्त नहीं है यह एक अच्छा व्यायाम हो सकता है)

def fibonacci(index):
    return reduce(lambda r,v: r.append(r[-1]+r[-2]) or (r.pop(0) and 0) or r , xrange(index), [0, 1])[1]

और पूर्ण सरणी प्राप्त करने के लिए या (r.pop (0) और 0 हटाएं)

reduce(lambda r,v: r.append(r[-1]+r[-2]) or r , xrange(last_index), [0, 1])

0

इसके बारे में क्या खयाल है? मुझे लगता है कि यह अन्य सुझावों के रूप में फैंसी नहीं है क्योंकि यह अपेक्षित परिणाम का उत्पादन करने के लिए पिछले परिणाम के प्रारंभिक विनिर्देश की मांग करता है, लेकिन मुझे लगता है कि यह एक बहुत ही पठनीय विकल्प है, अर्थात, यह सब करने के लिए परिणाम और पिछले परिणाम प्रदान करना है पुनरावृत्ति।

#count the number of recursions
num_rec = 0

def fibonacci(num, prev, num_rec, cycles):

    num_rec = num_rec + 1

    if num == 0 and prev == 0:
        result  = 0;
        num = 1;
    else:
        result = num + prev

    print(result)

    if num_rec == cycles:
        print("done")
    else:
        fibonacci(result, num, num_rec, cycles)

#Run the fibonacci function 10 times
fibonacci(0, 0, num_rec, 10)

यहाँ उत्पादन है:

0
1
1
2
3
5
8
13
21
34
done


0
def fib(lowerbound, upperbound):
    x = 0
    y = 1
    while x <= upperbound:
        if (x >= lowerbound):
            yield x
        x, y = y, x + y

startNumber = 10
endNumber = 100
for fib_sequence in fib(startNumber, endNumber):
    print "And the next number is... %d!" % fib_sequence

0

फाइबोनैचि अनुक्रम के लिए संस्मरण कैसे काम करता है, इसका अधिक विस्तृत विवरण।

# Fibonacci sequence Memoization

fib_cache = {0:0, 1:1}

def fibonacci(n):
    if n < 0:
        return -1
    if fib_cache.has_key(n):
        print "Fibonacci sequence for %d = %d cached" % (n, fib_cache[n])
        return fib_cache[n]
    else:
        fib_cache[n] = fibonacci(n - 1) + fibonacci(n - 2)
    return fib_cache[n]

if __name__ == "__main__":
    print fibonacci(6)
    print fib_cache
    # fibonacci(7) reuses fibonacci(6) and fibonacci(5)
    print fibonacci(7)
    print fib_cache

0

मैं इस समस्या को हल करने के लिए एक पुनरावर्ती कार्य से बचने की कोशिश कर रहा था, इसलिए मैंने एक पुनरावृत्त दृष्टिकोण लिया। मैं मूल रूप से एक पुनरावर्ती कार्य कर रहा था, लेकिन अधिकतम पुनरावर्ती गहराई तक मार करता रहा। मेरे पास सख्त मेमोरी गोल भी थे, इसलिए आप मुझे किसी भी समय सरणी में केवल 2-3 मान रखने वाले लूपिंग प्रक्रिया के दौरान सरणी को छोटा रखने के रूप में देखेंगे।

def fib(n):
    fibs = [1, 1] # my starting array
    for f in range(2, n):
        fibs.append(fibs[-1] + fibs[-2]) # appending the new fib number
        del fibs[0] # removing the oldest number
    return fibs[-1] # returning the newest fib

print(fib(6000000))

मेरी मशीन पर 6 मिलियन फ़ाइटर नंबर प्राप्त करने में लगभग 282 सेकंड लगते हैं जबकि 600k फ़ोटोग्राफ़ी में केवल 2.8 सेकंड लगते हैं। मैं एक पुनरावर्ती फ़ंक्शन के साथ इतने बड़े रिट्रेसमेंट नंबर प्राप्त करने में असमर्थ था, यहां तक ​​कि एक ज्ञापन भी।

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