Wróć do informacji o e-podręczniku Wydrukuj Pobierz materiał do PDF Pobierz materiał do EPUB Pobierz materiał do MOBI Zaloguj się, aby dodać do ulubionych Zaloguj się, aby skopiować i edytować materiał Zaloguj się, aby udostępnić materiał Zaloguj się, aby dodać całą stronę do teczki

Opis problemu

Schemat Hornera jest sposobem obliczania wartości wielomianu dla podanego argumentu. Dzięki tej metodzie ograniczamy liczbę mnożeń, którą musimy wykonać w celu rozwiązania problemu. Sprawdźmy, ile operacji mnożenia musielibyśmy wykonać dla przedstawionego wielomianu:

2x3+3x2-4x-8

Na początek rozwiążmy ten problem metodą tradycyjną:

2·x·x·x+3·x·x-4·x-8

Obliczając wartość wielomianu, musieliśmy wykonać sześć mnożeń. W celu zastosowania schematu Hornera, wyłączymy przed nawias x w następujący sposób:

x·2x2+3x-4-8

Następnie ponownie wyłączamy x przed nawias. Będziemy powtarzać tę operację do momentu, gdy nasz wielomian będzie wyglądał tak:

x·x·x·2+3-4-8

Teraz musimy wykonać tylko trzy mnożenia, zatem znacząco zredukowaliśmy liczbę tych operacji.

Oto dwie metody implementacji algorytmu schematu Hornera – iteracyjną oraz rekurencyjną – które są zgodne z następującą specyfikacją:

Specyfikacja:

Dane:

  • x – liczba rzeczywista, wartość argumentu

  • stopien – liczba całkowita >=0, stopień wielomianu

  • wsp[ ] – stopień +1–elementowa tablica liczb rzeczywistych, współczynniki wielomianu

Wynik:

  • wynik – liczba rzeczywista, wartość wielomianu dla argumentu x

Implementacja algorytmu iteracyjnego

Na podstawie analizy przeprowadzonej na początku tego e‑materiału możemy zdefiniować następujący wzór iteracyjny algorytmu:

wynik=wsp0wynik=x×wynik+wspidla i=1,2,3..., stopien

Rozpoczniemy od zaimplementowania schematu Hornera w języku Java przy użyciu iteracjiiteracjaiteracji. W tym celu zadeklarujemy funkcję o nazwie horner, której przyjmowanymi parametrami wyjściowymi będą:

  • wsp[] – tablica współczynników wielomianu rozpoczynająca się od stojącego przy najwyższej potędze x, a kończąca na wyrazie wolnym,

  • stopien – stopień wielomianu, czyli jego najwyższy wykładnik x,

  • x – argument, dla którego chcemy obliczyć wartość wielomianu.

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. zamknij nawias klamrowy. Linia 6. zamknij nawias klamrowy.

Następnie do zmiennej wynik zapisujemy wartość pierwszego współczynnika. W już rozwiązywanym przykładzie znajdowała się ona w wewnętrznym nawiasie. Dla wielomianu:

2x3+3x2-4x-8

jest to po prostu:

2
Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. int wynik znak równości wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 5. zamknij nawias klamrowy. Linia 6. zamknij nawias klamrowy.

Teraz możemy stworzyć pętlę, która będzie mnożyła nasz wynik razy x i dodawała kolejny współczynnik, aż osiągnie wartość stopien. Zatem po pierwszej iteracji nasze działanie będzie wyglądało tak:

x·2+3

a po ostatniej iteracji tak:

x·x·x·2+3-4-8
Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. int wynik znak równości wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopien średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. wynik znak równości x asterysk wynik plus wsp otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy. Linia 9. zamknij nawias klamrowy. Linia 10. zamknij nawias klamrowy.

Na koniec zwracamy otrzymaną wartość wielomianu, zapisaną w zmiennej wynik:

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. int wynik znak równości wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopien średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. wynik znak równości x asterysk wynik plus wsp otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy. Linia 9. return wynik średnik. Linia 10. zamknij nawias klamrowy. Linia 11. zamknij nawias klamrowy.

Teraz w głównej części programu wystarczy wywołać naszą funkcję z odpowiednimi współczynnikami, stopniem i argumentem, dla którego chcemy obliczyć wartość wielomianu.

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. int wynik znak równości wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopien średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. wynik znak równości x asterysk wynik plus wsp otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy. Linia 9. return wynik średnik. Linia 10. zamknij nawias klamrowy. Linia 12. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 14. int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 2 przecinek 3 przecinek minus 4 przecinek minus 8 zamknij nawias klamrowy średnik. Linia 15. int stopien znak równości 3 średnik. Linia 16. int x znak równości 2 średnik. Linia 17. System kropka out kropka println otwórz nawias okrągły horner otwórz nawias okrągły wsp przecinek stopien przecinek x zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 19. zamknij nawias klamrowy. Linia 20. zamknij nawias klamrowy.

Implementacja algorytmu rekurencyjnego

Wiemy już, jak stosować rekurencjęrekurencjarekurencję w programach. Pamiętajmy, że schemat Hornera również możemy zaimplementować tę techniką programowania. Wzór rekurencyjny algorytmu jest następujący:

wynikstopien=wsp0dla stopien=0x×wynikstopien-1+wspstopiendla stopien>1

Rozpoczynamy nasz program podobnie jak w sposobie iteracyjnym. Funkcja będzie miała nazwę horner, a przyjmowanymi parametrami wyjściowymi będą: tablica współczynników, stopień wielomianu oraz argument, dla którego chcemy obliczyć wartość wielomianu.

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. zamknij nawias klamrowy. Linia 6. zamknij nawias klamrowy.

W następnym kroku będziemy wykorzystywać rekurencję. Zgodnie ze schematem Hornera będziemy mnożyć nasz argument przez wartość otrzymaną z rekurencyjnego wywołania funkcji dla stopnia mniejszego o 1, a następnie dodawać do tego ostatni wyraz wolny. Np. w przypadku wywołania pierwszej funkcji horner dla wielomianu:

2x3+3x2-4x-8

zostanie zwrócona następująca wartość:

R181iqxclboTR

Funkcja horner będzie wywoływana rekurencyjnie aż do przypadku podstawowegoprzypadek podstawowyprzypadku podstawowego – sytuacji, w której stopień wielomianu będzie równy 0. Zostanie wtedy zwrócony pierwszy element naszej tablicy, czyli współczynnik leżący przy najwyższej potędze zmiennej x.

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. if otwórz nawias okrągły stopien znak równości znak równości 0 zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. return wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. zamknij nawias klamrowy. Linia 7. return x asterysk horner otwórz nawias okrągły wsp przecinek stopien minus 1 przecinek x zamknij nawias okrągły plus wsp otwórz nawias kwadratowy stopien zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy. Linia 9. zamknij nawias klamrowy.

Teraz w głównej funkcji programu wystarczy wywołać funkcję horner z odpowiednimi współczynnikami, stopniem i wybranym argumentem dla danego wielomianu. Obliczmy wartość tego samego wielomianu i argumentu, co w przypadku iteracyjnym.

Linia 1. public class Horner otwórz nawias klamrowy. Linia 3. static int horner otwórz nawias okrągły int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopien przecinek int x zamknij nawias okrągły otwórz nawias klamrowy. Linia 4. if otwórz nawias okrągły stopien znak równości znak równości 0 zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. return wsp otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. zamknij nawias klamrowy. Linia 7. return x asterysk horner otwórz nawias okrągły wsp przecinek stopien minus 1 przecinek x zamknij nawias okrągły plus wsp otwórz nawias kwadratowy stopien zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy. Linia 10. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 12. int wsp otwórz nawias kwadratowy zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 2 przecinek 3 przecinek minus 4 przecinek minus 8 zamknij nawias klamrowy średnik. Linia 13. int stopien znak równości 3 średnik. Linia 14. int x znak równości 2 średnik. Linia 15. System kropka out kropka println otwórz nawias okrągły horner otwórz nawias okrągły wsp przecinek stopien przecinek x zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 17. zamknij nawias klamrowy. Linia 18. zamknij nawias klamrowy.

Tak samo jak w implementacji metodą iteracyjną, teraz również dla argumentu 2 otrzymaliśmy wartość wielomianu równą 12.

Słownik

algorytm
algorytm

przepis postępowania prowadzący do rozwiązania ustalonego problemu, określający ciąg czynności elementarnych, które należy w tym celu wykonać

iteracja
iteracja

technika programowania polegająca na powtarzaniu tych samych operacji w pętli określoną liczbę razy lub do momentu, aż zostanie spełniony zadany warunek

przypadek podstawowy
przypadek podstawowy

przypadek, dla którego funkcja rekurencyjna nie wywołuje samej siebie, a zamiast tego zwraca z góry określoną wartość

rekurencja
rekurencja

technika programowania polegająca na odwoływaniu się procedur lub funkcji do samych siebie, aż do momentu spełnienia warunku podstawowego

stopień wielomianu
stopień wielomianu

najwyższa potęga przy zmiennej, która nie jest równa zero

wielomian
wielomian

wyrażenie algebraiczne będące sumą jednomianów, czyli wyrażeń postaci anxn

William George Horner
William George Horner

brytyjski matematyk żyjący w latach 17861837; w wieku 14 lat został asystentem nauczyciela w szkole w Bristolu, a w 1809 roku założył własną szkołę w Bath; podał sposób wyznaczania wartości wielomianu z wykorzystaniem minimalnej liczby operacji możenia

wykonanie elementarne w rekurencji
wykonanie elementarne w rekurencji

moment, gdy funkcja rekurencyjna zwraca konkretną wartość zamiast kolejnego wywołania rekurencyjnego