Drzewo wywołań funkcji: Różnice pomiędzy wersjami
[wersja nieprzejrzana] | [wersja przejrzana] |
Przykład. |
|||
(Nie pokazano 11 wersji utworzonych przez 10 użytkowników) | |||
Linia 1: | Linia 1: | ||
{{dopracować|źródła=2017-06}} |
|||
'''Drzewo wywołań funkcji''' (ang. ''call tree'') |
'''Drzewo wywołań funkcji''' (ang. ''call tree'') – [[drzewo (matematyka)|drzewo]] przedstawiające proces obliczania wartości [[wyrażenie arytmetyczne|wyrażenia]]. Liście drzewa wywołań zawierają niepodzielne części wyrażenia, czyli [[stała|stałe]] i [[zmienna (informatyka)|zmienne]]. Węzły wewnętrzne i korzeń odpowiadają wywołaniu [[podprogram|funkcji]] (lub operatorów) z [[argument]]ami obliczonymi przez ich poddrzewa. |
||
Drzewa wywołań rozpatruje się przede wszystkim w konstrukcji [[kompilator |
Drzewa wywołań rozpatruje się przede wszystkim w konstrukcji [[kompilator]]ów [[język programowania|języków programowania]], ale także w [[analiza programów|analizie programów]] (ang. [[w:Computer program analysis|''program analysis'']]), oraz w konstrukcji i analizie [[algorytm]]ów. Najczęściej używa się takich drzew dla wyrażeń, które zawierają wywołania funkcji, lub drzewa dla obliczania wartości funkcji rekurencyjnych. |
||
W typowych językach programowania |
W typowych językach programowania wyrażenia mogą generować [[skutek uboczny (informatyka)|skutki uboczne]]. Zazwyczaj drzewo wywołań nie uwzględnia tego faktu i obrazuje jedynie strukturę obliczania. Szczególnie interesujące są drzewa wywołań dla funkcji rekurencyjnych nieposiadających skutków ubocznych. Drzewa takie można przekształcić zwykłymi metodami matematycznymi (''zob. np. [[programowanie dynamiczne]]'') w [[Skierowany graf acykliczny|skierowany graf acykliczny (DAG)]], |
||
co umożliwia optymalizację. |
co umożliwia optymalizację. |
||
==Przykład== |
== Przykład == |
||
[[ |
[[Plik:Call Tree for Fibonacci Number F6.svg|thumb|300px|Drzewo wywołań dla obliczania F(6)]] |
||
Jako przykład rozważmy drzewo wywołań dla funkcji <math>F</math> obliczającej wartość n-tego wyrazu [[ciąg Fibonacciego|ciągu Fibonacciego]]: |
Jako przykład rozważmy drzewo wywołań dla funkcji <math>F</math> obliczającej wartość n-tego wyrazu [[ciąg Fibonacciego|ciągu Fibonacciego]]: |
||
Linia 14: | Linia 15: | ||
else F (n-1) + F (n-2) |
else F (n-1) + F (n-2) |
||
Diagram po prawej stronie prezentuje drzewo wywołań dla wyrażenia <math>F(6)</math> |
Diagram po prawej stronie prezentuje drzewo wywołań dla wyrażenia <math>F(6).</math> Dla uproszczenia pominięto tu wartości wyrażeń pośrednich, pokazując jedynie wywołania funkcji. Łatwo zauważyć, że drzewo to zawiera wiele zbędnych obliczeń, na przykład <math>F(2)</math> jest obliczane pięciokrotnie a <math>F(3)</math> trzykrotnie, pomimo tego, że wartość funkcji dla zadanych parametrów jest zawsze taka sama. |
||
[[ |
[[Plik:Fibonacci-dag-svg.svg|thumb|220px|Zredukowane drzewo wywołań (skierowany graf acykliczny) dla obliczania F(6)]] |
||
Kolejny diagram pokazuje jak powyższe drzewo może zostać zredukowane do grafu skierowanego za pomocą technik typu programowanie dynamiczne lub [[memoizacja]]. |
|||
[[Kategoria:Algorytmika]] |
Aktualna wersja na dzień 01:07, 16 cze 2020
Drzewo wywołań funkcji (ang. call tree) – drzewo przedstawiające proces obliczania wartości wyrażenia. Liście drzewa wywołań zawierają niepodzielne części wyrażenia, czyli stałe i zmienne. Węzły wewnętrzne i korzeń odpowiadają wywołaniu funkcji (lub operatorów) z argumentami obliczonymi przez ich poddrzewa.
Drzewa wywołań rozpatruje się przede wszystkim w konstrukcji kompilatorów języków programowania, ale także w analizie programów (ang. program analysis), oraz w konstrukcji i analizie algorytmów. Najczęściej używa się takich drzew dla wyrażeń, które zawierają wywołania funkcji, lub drzewa dla obliczania wartości funkcji rekurencyjnych.
W typowych językach programowania wyrażenia mogą generować skutki uboczne. Zazwyczaj drzewo wywołań nie uwzględnia tego faktu i obrazuje jedynie strukturę obliczania. Szczególnie interesujące są drzewa wywołań dla funkcji rekurencyjnych nieposiadających skutków ubocznych. Drzewa takie można przekształcić zwykłymi metodami matematycznymi (zob. np. programowanie dynamiczne) w skierowany graf acykliczny (DAG), co umożliwia optymalizację.
Przykład
[edytuj | edytuj kod]Jako przykład rozważmy drzewo wywołań dla funkcji obliczającej wartość n-tego wyrazu ciągu Fibonacciego:
fun F (n :int) :int = if n=1 or n=2 then 1 else F (n-1) + F (n-2)
Diagram po prawej stronie prezentuje drzewo wywołań dla wyrażenia Dla uproszczenia pominięto tu wartości wyrażeń pośrednich, pokazując jedynie wywołania funkcji. Łatwo zauważyć, że drzewo to zawiera wiele zbędnych obliczeń, na przykład jest obliczane pięciokrotnie a trzykrotnie, pomimo tego, że wartość funkcji dla zadanych parametrów jest zawsze taka sama.
Kolejny diagram pokazuje jak powyższe drzewo może zostać zredukowane do grafu skierowanego za pomocą technik typu programowanie dynamiczne lub memoizacja.