Technikum Klasa I 45 minut PP: II.1 + I.2d | s. 342-343

Lekcja 26: Implementacja ciagu Fibonacciego i innych ciagow

Ciagi liczbowe, rekurencja vs iteracja, ciag Fibonacciego w Pythonie

📋 Podstawa programowa: II.1+I.2d
FibonacciPythonciagciagiimplementacjapetle
00:00
Wprowadzenie
5 min
00:05
Teoria
15 min
00:20
Cwiczenia
20 min
00:40
Podsumowanie
5 min
📚

Teoria

Ciag Fibonacciego

Ciag Fibonacciego to jeden z najslynniejszych ciagow w matematyce. Kazdy wyraz (poczawszy od trzeciego) jest suma dwoch poprzednich:

F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2)

Poczatkowe wyrazy: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

Fibonacci w przyrodzie: Ciag Fibonacciego pojawia sie w spiralach muszli slimakow, ukladzie nasion slonecznika, platkach kwiatow, a stosunek kolejnych wyrazow zbliza sie do zlotego podzialu (ok. 1.618).

Wersja iteracyjna (zalecana)

def fibonacci_iteracyjnie(n):
    """Zwraca n-ty wyraz ciagu Fibonacciego (iteracyjnie)."""
    if n <= 0:
        return 0
    if n == 1:
        return 1

    a, b = 0, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    return b

# Wyswietl pierwsze 15 wyrazow
for i in range(15):
    print(fibonacci_iteracyjnie(i), end=" ")
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Wersja rekurencyjna

Rekurencja = funkcja wywoluje sama siebie. Elegancka, ale nieefektywna dla duzych n:

def fibonacci_rekurencyjnie(n):
    """Zwraca n-ty wyraz ciagu Fibonacciego (rekurencyjnie)."""
    if n <= 0:
        return 0
    if n == 1:
        return 1
    return fibonacci_rekurencyjnie(n - 1) + fibonacci_rekurencyjnie(n - 2)

# UWAGA: Dla n > 35 bedzie BARDZO wolno!
print(fibonacci_rekurencyjnie(10))  # 55
Dlaczego rekurencja jest wolna? Dla fibonacci_rekurencyjnie(5) funkcja wywoluje sie 15 razy, a dla fibonacci_rekurencyjnie(40) - ponad miliard razy! Wersja iteracyjna wykonuje tylko n krokow.

Inne popularne ciagi liczbowe

# Ciag arytmetyczny: a(n) = a(0) + n * r
def ciag_arytmetyczny(a0, r, n):
    return [a0 + i * r for i in range(n)]

print(ciag_arytmetyczny(2, 3, 8))  # [2, 5, 8, 11, 14, 17, 20, 23]

# Ciag geometryczny: a(n) = a(0) * q^n
def ciag_geometryczny(a0, q, n):
    return [a0 * q**i for i in range(n)]

print(ciag_geometryczny(1, 2, 8))  # [1, 2, 4, 8, 16, 32, 64, 128]

# Silnia: n! = 1 * 2 * 3 * ... * n
def silnia(n):
    wynik = 1
    for i in range(1, n + 1):
        wynik *= i
    return wynik

# Ciag: 1!, 2!, 3!, ..., 10!
for i in range(1, 11):
    print(f"{i}! = {silnia(i)}")

Ciag Collatza

def collatz(n):
    """Generuje ciag Collatza zaczynajacy od n."""
    ciag = [n]
    while n != 1:
        if n % 2 == 0:
            n = n // 2
        else:
            n = 3 * n + 1
        ciag.append(n)
    return ciag

print(collatz(27))  # [27, 82, 41, 124, 62, 31, ...]
✏️

Zadania

Latwe

Zadanie 1: Fibonacci do n

Napisz program, ktory wyswietla wszystkie wyrazy ciagu Fibonacciego mniejsze od podanej liczby n. Uzyj wersji iteracyjnej.

Pokaz przykladowe rozwiazanie
n = int(input("Podaj granice: "))

a, b = 0, 1
print("Wyrazy ciagu Fibonacciego mniejsze od", n, ":")
while a < n:
    print(a, end=" ")
    a, b = b, a + b
Latwe

Zadanie 2: Ciag arytmetyczny i geometryczny

Napisz program, ktory generuje: a) ciag arytmetyczny o podanym a0, roznicy r i n wyrazach, b) ciag geometryczny o podanym a0, ilorazie q i n wyrazach. Oblicz sume kazdego ciagu.

Pokaz przykladowe rozwiazanie
print("=== Ciag arytmetyczny ===")
a0 = float(input("Podaj a0: "))
r = float(input("Podaj roznice r: "))
n = int(input("Ile wyrazow? "))

ciag_a = [a0 + i * r for i in range(n)]
print(f"Ciag: {ciag_a}")
print(f"Suma: {sum(ciag_a)}")

print("\n=== Ciag geometryczny ===")
a0 = float(input("Podaj a0: "))
q = float(input("Podaj iloraz q: "))
n = int(input("Ile wyrazow? "))

ciag_g = [a0 * q**i for i in range(n)]
print(f"Ciag: {ciag_g}")
print(f"Suma: {sum(ciag_g)}")
Srednie

Zadanie 3: Zloty podzial

Napisz program, ktory oblicza stosunek kolejnych wyrazow Fibonacciego (F(n)/F(n-1)) dla n od 2 do 20. Pokaz, ze stosunek ten zbliza sie do zlotego podzialu (ok. 1.6180339...).

Pokaz przykladowe rozwiazanie
def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

zloty = (1 + 5**0.5) / 2
print(f"Zloty podzial = {zloty:.10f}\n")

print(f"{'n':>4} | {'F(n)':>10} | {'F(n)/F(n-1)':>14} | {'Roznica':>12}")
print("-" * 48)

for n in range(2, 21):
    stosunek = fib(n) / fib(n - 1)
    roznica = abs(stosunek - zloty)
    print(f"{n:>4} | {fib(n):>10} | {stosunek:>14.10f} | {roznica:>12.10f}")
Trudne

Zadanie 4: Porownanie rekurencji i iteracji

Zaimplementuj Fibonacciego iteracyjnie i rekurencyjnie. Zmierz czas wykonania obu wersji dla n = 10, 20, 30, 35. Wyswietl wyniki w tabeli i wyciagnij wnioski.

Pokaz przykladowe rozwiazanie
import time

def fib_iter(n):
    if n <= 1: return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

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

print(f"{'n':>4} | {'Wynik':>12} | {'Iteracja':>12} | {'Rekurencja':>12}")
print("-" * 50)

for n in [10, 20, 30, 35]:
    start = time.time()
    wynik_i = fib_iter(n)
    czas_i = time.time() - start

    start = time.time()
    wynik_r = fib_rek(n)
    czas_r = time.time() - start

    print(f"{n:>4} | {wynik_i:>12} | {czas_i:>10.6f}s | {czas_r:>10.6f}s")

print("\nWniosek: Rekurencja jest wykladniczo wolniejsza!")
🎥

Materialy wideo

Programowanie C++ Zad.31 - Wypisanie ciągu Fibonacciego do n tego elementu
Pikademia
Recursion in 10 Minutes - Full Course (Python, Memoization, Fibonacci) 🔄
CodeBucket
🎧

Podcasty

✔️

Quiz - sprawdz sie!

📜

Podstawa programowa

← Lekcja 25: Algorytmy sortowania Lekcja 27: Testowanie poprawnosci programow →