Przeczytaj
Zadanie 1. Liczby Fibonacciego
Liczby Fibonacciego są definiowane w następujący sposób:
FIndeks dolny 11 = 1, FIndeks dolny 22 = 1,
FIndeks dolny nn = FIndeks dolny n - 1 Indeks dolny koniecn - 1 + FIndeks dolny n - 2 Indeks dolny koniecn - 2
dla = 3, 4, …
Rekurencyjny algorytm, który służy do obliczania wartości dla dowolnego n >= 1
, można zapisać następująco:
Zadanie zostało opracowane przez CKE i pojawiło się na I części egzaminu maturalnego z informatyki w czerwcu 2018 roku (poziom rozszerzony, egzamin w tzw. starej formule). Cały arkusz można znaleźć na stronie internetowej CKE.
Zadanie 1.1
Zapisz w wybranej przez siebie notacji (w języku programowania lub w pseudokodzie) algorytm iteracyjny, który służy do obliczania wartości liczby dla dowolnego ≥ 1. Algorytm nie może używać tablic.
Rozwiązanie przedstawimy przy użyciu pseudokodu ze względu na fakt, że zadania maturalne dotyczące programowania można rozwiązać w wybranym języku programowania: C++, Java lub Python.
Zaimplementuj przedstawione rozwiązanie w wybranym języku programowania: C++, Java, Python.
Przykładowe rozwiązanie:
Mamy przedstawić algorytm, który będzie obliczać wartość elementu ciągu Fibonacciego o podanym indeksie. Posłużymy się techniką iteracyjną (czyli wykonamy określoną liczbę powtórzeń pewnych czynności).
Definiujemy zmienną
indeks
, która będzie przechowywać indeks wyliczanego elementu ciągu:
Piszemy instrukcję warunkową umożliwiającą obliczenie wartości pierwszego lub drugiego elementu ciągu Fibonacciego. W obu przypadkach podajemy wówczas wartość 1:
Aby obliczyć wartość elementu o indeksie numer 3 lub wyższym, stosujemy iteracjęiterację. Tworzymy najpierw trzy zmienne:
aktualna
– przechowuje wartość wyliczoną dla obecnego indeksu,poprzednia
– przechowuje wartość elementu o indeksie niższym o 1,bPoprzednia
– przechowuje wartość elementu o indeksie niższym o 2.
Tworzymy pętlę
dla
, w której będą obliczane wartości kolejnych elementów ciągu Fibonacciego (licznik pętli inicjujemy wartością 3, ponieważ dwa pierwsze elementy ciągu już znamy):
Wewnątrz pętli wykonane zostaną trzy działania:
obliczenie wartości elementu ciągu o aktualnym indeksie (suma dwóch poprzednich elementów);
wartość o indeksie niższym o 1 na potrzeby następnego cyklu pętli stanie się wartością o indeksie niższym o 2;
wartość aktualna na potrzeby następnego cyklu pętli stanie się wartością o indeksie niższym o 1.
Schemat oceniania:
2 p. – za poprawny algorytm (w tym za prawidłowe zapisanie warunków początkowych i iteracji 1 p.).
1 p. – za zapamiętanie tylko dwóch poprzednich wyrazów ciągu.
0 p. – za podanie odpowiedzi błędnej albo brak odpowiedzi.
Za przedstawione rozwiązanie zadania otrzymalibyśmy 2 punkty, ponieważ prawidłowo zapisane zostały warunki początkowe (dla indeksów 1 i 2) oraz pętla iteracyjna.
Zadanie 1.2
Aby obliczyć , wywołano najpierw funkcję iteracyjną, a potem – rekurencyjną. Okazało się, że czas trwania obliczeń realizowanych przez funkcję rekurencyjną był długi, podczas gdy funkcja iteracyjna prawie natychmiast podała wynik. Uzasadnij długi czas działania funkcji rekurencyjnej.
Przykładowe rozwiązanie:
Jedną z lepszych wizualizacji rekurencji jest zapisanie jej w postaci drzewa, w którym poszczególne wywołania funkcji uruchamiają kolejne jej wywołania (aż do napotkania przypadku podstawowego). Wielokrotne wywoływanie powoduje wielokrotne obliczanie tych samych wartości. Poszczególne elementy ciągu Fibonacciego wyliczane są zatem bez brania pod uwagę wyrazów już znanych. Za każdym razem funkcja rekurencyjna dochodzi do przypadku podstawowego. Ponadto im dalszy wyraz ciągu Fibonacciego ma zostać obliczony, tym więcej powtórzeń jest wykonywanych. Z tego powodu taka technika okazuje się wolniejsza od metody iteracyjnej i daje złożoność wykładniczą od n.
Schemat oceniania:
1 p. – za poprawną odpowiedź.
0 p. – za podanie odpowiedzi błędnej albo brak odpowiedzi.
Nasza odpowiedź jest trochę obszerniejsza niż ta przedstawiona w arkuszu sporządzonym przez CKE, ale wyjaśnia powód wolniejszego działania algorytmu rekurencyjnego. W rezultacie na egzaminie otrzymalibyśmy 1 punkt.
Słownik
technika programowania polegająca na wielokrotnym powtarzaniu zapisanego ciągu instrukcji aż do spełnienia określonego warunku
technika programowania, w której funkcja wywołuje samą siebie aż do napotkania przypadku podstawowego, czyli takiego, którego nie da się rozłożyć na mniejsze problemy; przykład przypadku podstawowego dla obliczania piątego wyrazu ciągu Fibonacciego:
wartość, dla której funkcja rekurencyjna zwraca określony wynik