Wyszukiwanie binarne

Podobne dokumenty
Programowanie dynamiczne

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Algorytm selekcji Hoare a. Łukasz Miemus

Wstęp do programowania

Wyszukiwanie. Wyszukiwanie binarne

KONSPEKT FUNKCJE cz. 1.

CIĄGI wiadomości podstawowe

Znaleźć wzór ogólny i zbadać istnienie granicy ciągu określonego rekurencyjnie:

8. Neuron z ciągłą funkcją aktywacji.

Scenariusz zajęć. Moduł VI. Projekt Gra logiczna zgadywanie liczby

Schematy blokowe I. 1. Dostępne bloki: 2. Prosty program drukujący tekst.

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Strategia "dziel i zwyciężaj"

Wykład 2. Poprawność algorytmów

Wstęp do programowania

1. Napisz program, który wyświetli Twoje dane jako napis Witaj, Imię Nazwisko. 2. Napisz program, który wyświetli wizytówkę postaci:

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Szukanie rozwiązań funkcji uwikłanych (równań nieliniowych)

Indukcja matematyczna

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

Wstęp do programowania

Liczby pierwsze. Kacper Żurek, uczeń w Gimnazjum nr 1 im. Jana Pawła II w Giżycku.

Struktury Danych i Złożoność Obliczeniowa

Algorytmy przeszukiwania wzorca

Otrzymaliśmy w ten sposób ograniczenie na wartości parametru m.

Podstawą w systemie dwójkowym jest liczba 2 a w systemie dziesiętnym liczba 10.

Wokół Problemu Steinhausa z teorii liczb

Programowanie w Baltie klasa VII

Ćwiczenie 3 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

Algorytmy sortujące i wyszukujące

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

13. Równania różniczkowe - portrety fazowe

Akademia Górniczo-Hutnicza im. Stanisława Staszica w Krakowie Olimpiada O Diamentowy Indeks AGH 2017/18. Informatyka Etap III

EGZAMIN MATURALNY W ROKU SZKOLNYM 2014/2015

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Zadanie 3 Oblicz jeżeli wiadomo, że liczby 8 2,, 1, , tworzą ciąg arytmetyczny. Wyznacz różnicę ciągu. Rozwiązanie:

Lista 2 logika i zbiory. Zad 1. Dane są zbiory A i B. Sprawdź, czy zachodzi któraś z relacji:. Wyznacz.

INFORMATYKA SORTOWANIE DANYCH.

Zaawansowane algorytmy i struktury danych

EGZAMIN MATURALNY W ROKU SZKOLNYM 2014/2015

for (inicjacja_warunkow_poczatkowych; wyrazenie_warunkowe; wyrazenie_zwiekszajace) { blok instrukcji; }

1. A 2. A 3. B 4. B 5. C 6. B 7. B 8. D 9. A 10. D 11. C 12. D 13. B 14. D 15. C 16. C 17. C 18. B 19. D 20. C 21. C 22. D 23. D 24. A 25.

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych.

Lista 0. Kamil Matuszewski 1 marca 2016

Karta pracy do doświadczeń

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Uwaga: Funkcja zamień(a[j],a[j+s]) zamienia miejscami wartości A[j] oraz A[j+s].

EGZAMIN MATURALNY W ROKU SZKOLNYM 2017/2018 INFORMATYKA

Liczby losowe i pętla while w języku Python

Zasady analizy algorytmów

Logarytmy. Funkcje logarytmiczna i wykładnicza. Równania i nierówności wykładnicze i logarytmiczne.

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

ZADANIE 1. Ważenie (14 pkt)

1 Układy równań liniowych

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Matematyka A kolokwium 26 kwietnia 2017 r., godz. 18:05 20:00. i = = i. +i sin ) = 1024(cos 5π+i sin 5π) =

Ciągi komplementarne. Autor: Krzysztof Zamarski. Opiekun pracy: dr Jacek Dymel

BŁĘDY OBLICZEŃ NUMERYCZNYCH

17. Naprzemienne odejmowanie

1 Podstawy c++ w pigułce.

Funkcje - monotoniczność, różnowartościowość, funkcje parzyste, nieparzyste, okresowe. Funkcja liniowa.

Zadanie 1. Doskonała inaczej (6 pkt) Poniższy algorytm wyznacza wszystkie dzielniki liczby naturalnej n 1, mniejsze od n.

Kompletna dokumentacja kontenera C++ vector w -

Funkcje wymierne. Funkcja homograficzna. Równania i nierówności wymierne.

Jarosław Wróblewski Analiza Matematyczna 1A, zima 2012/13

Matematyka dyskretna - 7.Drzewa

Ciąg monotoniczny. Autorzy: Katarzyna Korbel

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

Jak zawsze wyjdziemy od terminologii. While oznacza dopóki, podczas gdy. Pętla while jest

Skrypt 31. Powtórzenie do matury Liczby rzeczywiste

Elementy modelowania matematycznego

Indukcja matematyczna. Zasada minimum. Zastosowania.

znalezienia elementu w zbiorze, gdy w nim jest; dołączenia nowego elementu w odpowiednie miejsce, aby zbiór pozostał nadal uporządkowany.

1. Informatyka - dyscyplina naukowa i techniczna zajmująca się przetwarzaniem informacji.

Szanowni Państwo, Nauczyciele poprawiający prace uczniowskie z badania diagnostycznego z matematyki

1. Liczby naturalne, podzielność, silnie, reszty z dzielenia

ROZWIĄZYWANIE UKŁADÓW RÓWNAŃ NIELINIOWYCH PRZY POMOCY DODATKU SOLVER PROGRAMU MICROSOFT EXCEL. sin x2 (1)

Wstęp do programowania

XV WOJEWÓDZKI KONKURS Z MATEMATYKI

Dwa równania kwadratowe z częścią całkowitą

PętlaforwOctave. Roman Putanowicz 13 kwietnia 2008

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to

Wstęp do metod numerycznych 9. Minimalizacja: funkcje jednej zmiennej. P. F. Góra

EGZAMIN - Wersja A. ALGORYTMY I STRUKTURY DANYCH Lisek89 opracowanie kartki od Pani dr E. Koszelew

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Zaprojektować i zaimplementować algorytm realizujący następujące zadanie.

Sortowanie przez scalanie

Obóz Naukowy Olimpiady Matematycznej Gimnazjalistów

1 Moduł Modbus ASCII/RTU 3

Jarosław Wróblewski Matematyka Elementarna, lato 2014/15

TEORETYCZNE PODSTAWY INFORMATYKI

SCHEMAT ROZWIĄZANIA ZADANIA OPTYMALIZACJI PRZY POMOCY ALGORYTMU GENETYCZNEGO

Wprowadzenie do algorytmiki

Maciej Piotr Jankowski

Kodowanie i kompresja Tomasz Jurdziński Studia Wieczorowe Wykład Kody liniowe - kodowanie w oparciu o macierz parzystości

Teoretyczne podstawy informatyki

WHILE (wyrażenie) instrukcja;

Programowanie strukturalne i obiektowe. Funkcje

1 Powtórzenie wiadomości

Transkrypt:

Wyszukiwanie binarne Wyszukiwanie binarne to technika pozwalająca na przeszukanie jakiegoś posortowanego zbioru danych w czasie logarytmicznie zależnym od jego wielkości (co to dokładnie znaczy dowiecie się prawdopodobnie na najbliższym kółku). Jak mieliście się okazję przekonać na zajęciach jest to też dobra strategia w grze, w której ktoś wymyśla liczbę np. z przedziału od 1 do 1000, a my staramy się ją zgadnąć. Wyszukiwanie w posortowanej tablicy Jest to jedno z najczęstszych i najprostszych zastosowań wyszukiwania binarnego. Mając daną posortowaną niemalejąco tablicę T o n elementach (indeksowanych od 0) chcemy w niej znaleźć pierwszy element, którego wartość jest równa x. Zdefiniujmy sobie teraz przedział poszukiwania jako ten, w którym znajduje się poszukiwany element, jeżeli jest w tablicy T. Indeks odpowiadający początkowi tego przedziału będziemy oznaczali przez p, a koniec przez k. Oczywiście początkowo prawdziwe jest, że p=0 i k=n-1 czyli, że przedział poszukiwania jest równy całej tablicy. W kolejnych krokach wyszukiwania binarnego będziemy porównywali medianę (czyli element o indeksie m=[ p k 2 ], gdzie przez [a] oznaczam część całkowitą z a) z x. Jeżeli mediana jest mniejsza niż x to z pewnością pierwszy element o wartości równej x nie może się pojawić w przedziale od p do m, zatem możemy przypisać p wartość m+1. Podobnie gdy mediana jest większa bądź równa x to szukany element nie wystąpi w przedziale od m+1 do k, więc k przyjmie wartość m. Algorytm kończy się, gdy przedział poszukiwania zawiera jeden element, czyli p=k. W każdy krok przedział poszukiwania jest zawężany o połowę, a więc wykonamy mniej więcej log 2 n kroków. Np. dla n = 1000 wykonamy 10 kroków, a dla n = 1000 000 jedynie 20. Widać więc, że algorytm będzie działał szybko. Przyjrzyjmy się teraz działaniu tego algorytmu na przykładowej tablicy. W tabeli w kolejnych krokach wypisano tylko elementy z przedziału poszukiwania, a mediany są zaznaczone żółtym kolorem. krok 1 1 1 2 3 3 4 5 6 8 8 8 9 9 10 krok 2 6 8 8 8 9 9 10

krok 3 6 8 8 8 krok 4 6 8 wynik 8 Oto zapis tego algorytmu w języku C++. Odpowiedni argument funkcji Oczywiście wyszukiwanie binarne można używać nie tylko na elementach tablicy. Znając pewną funkcję możemy skorzystać z tej metody do znalezienia przykładowo pierwszego argumentu większego niż dana wartość w pewnym przedziale jej dziedziny. Musimy być jednak pewni, że funkcja jest w tym przedziale monotoniczna. Warto dodać, że może być to funkcja określona zarówno dla argumentów całkowitych, jak i rzeczywistych, jednak w drugim przypadku będziemy musieli tolerować niedokładność otrzymanego wyniku. Załóżmy, że mamy do rozwiązania problem znalezienia największej możliwej liczby g (wśród liczb rzeczywistych nieujemnych), która spełnia pewien warunek. Wiadomo, że jeżeli ten warunek jest spełniony dla jakiejś wartości to jest też spełniony dla wartości od niej mniejszych i jeżeli warunek nie jest spełniony dla jakiejś wartości to nie jest spełniony dla wartości większych. Innymi słowami możemy zdefiniować funkcję F : R + {0} {0,1} przyjmującą wartości odpowiednio 1 i 0, w zależności od tego, czy argument spełnia podany warunek, czy nie. Wiemy zatem, że funkcja ta jest nierosnąca dla liczb rzeczywistych nieujemnych, a naszym zadaniem jest znaleźć największe takie g, że F(g)=1.

W takim przypadku wyszukiwanie binarne będzie wyglądało trochę inaczej niż do tej pory. Przedział poszukiwania będziemy także reprezentować przy użyciu dwóch zmiennych p (równej początkowo 0) i k, której przypiszemy odpowiednio dużą wartość, taką by F(k)=0. Najistotniejszą różnicą pomiędzy wyszukiwaniem binarnym w funkcjach określonych dla liczb całkowitych (przykładem może być po prostu tablica), a tych na liczbach rzeczywistych jest warunek przerywający wyszukiwanie. W pierwszym przypadku kolejne kroki są wykonywane dopóki p k. Gdy jednak wyszukujemy wśród liczb rzeczywistych taki warunek mógłby doprowadzić do niekończącej się pętli, ze względu na niedokładność obliczeń zmiennoprzecinkowych. Aby pozbyć się tego problemu najlepiej zawczasu obliczyć potrzebną nam dokładność i ustalić liczbę iteracji algorytmu. Przykładowo, gdy nasz przedział poszukiwania jest wielkości 10 18 to po wykonaniu 100 kroków otrzymany błąd będzie mniejszy niż 10-12. Taka dokładność powinna w zupełności wystarczyć. Pozostaje już tylko zaimplementować ten algorytm: Wyszukiwanie po wyniku Kolejną metodę związaną z wyszukiwaniem binarnym przedstawię na przykładzie następującego zadania pochodzącego z półfinałów konkursu ACM, który odbył się w Sankt Petersburgu w 2001 roku: Mamy n desek o długościach d 1, d 2, d 3,...,d n. Chcemy je pociąć w ten sposób, żeby otrzymać co najmniej z (z>0) sztachet o jednakowej długości g.

Pociętych fragmentów nie możemy w żaden sposób ze sobą łączyć. Jakie najdłuższe sztachety możemy otrzymać? Zadanie to przypomina przed chwilą rozważany problem odpowiedniego argumentu funkcji. W łatwy sposób możemy stwierdzić, czy dla danej długości g da się otrzymać z sztachet. Wystarczy sprawdzić ile można ich otrzymać z każdej z n desek (a jest to oczywiście [ d i g ] ), otrzymane wartości zsumować i przyrównać do z. Możemy zatem ponownie zdefiniować funkcję F, która zwracać będzie 1 gdy suma jest nie mniejsza niż z i 0 w przeciwnym przypadku. Łatwo zauważyć, że funkcja F będzie niemalejąca. W dalszej części przyjmiemy dodatkowe założenie, że występujące dane zadania i jego wynik mają być liczbami całkowitymi. Pozwoli nam to przyjrzeć się trochę innej implementacji wyszukiwania binarnego, a także zwrócić uwagę na bardzo często pojawiające się błędy. Na początek przedstawiam implementację funkcji F, która mając dane wartości n i z oraz długości d 1, d 2, d 3,...,d n w tablicy d, stwierdza, czy możliwe jest otrzymanie z sztachet długości g: Funkcja jest oczywiście bardzo prosta. Na uwagę zasługuje jedynie rozpatrzenie przypadku szczególnego, gdy g jest równe 0. Wszak zawsze da się otrzymać z sztachet o długości 0, a dzięki temu nie musimy się martwić o wykonywalność późniejszego dzielenia przez g. Zajmijmy się teraz już samym wyszukiwaniem binarnym. Po pierwsze musimy odpowiednio dobrać początkową wartość dla zmiennej k. Zgodnie ze wcześniejszymi spostrzeżeniami powinna ona być taka, że F(k)=0. Nie trudno zauważyć, że ten warunek spełnia chociażby długość największej z desek powiększona o 1. Po drugie tym razem nie wyszukujemy w funkcji określonej na liczbach całkowitych pierwszego miejsca spełniające dany warunek, lecz ostatnie, które

spełnia. W związku z tym jeżeli dla mediany m F(m)=1, to nową wartość p będzie m. Natomiast gdy F(m)=0 to możemy przyjąć k=m-1. Aby taki algorytm się kończył musimy za medianę uznać [ p k 1 2 ], a nie [ p k z rozpatrzenia skrajnego przypadku, gdy p+1=k i F(p)=1, lecz F(k)=0. 2 ]. Wynika to Po trzecie wartości p i k mogą być na tyle duże, że ich suma przekroczy zakres używanego typu zmiennych całkowitych. Aby ominąć ten problem formułę należy zastąpić równoważną. Po ominięciu tych pułapek uzyskujemy poprawnie działający program: Algorytm ten wykonuje liczbę kroków proporcjonalną do logarytmu zakresu danych wejściowych, każdy zaś z kroków w czasie proporcjonalnym do n. Jeżeli najdłuższa z desek będzie miała długość max to wykona on mniej więcej nlog 2 max kroków. Niniejszy artykuł jest pierwszym z serii materiałów pomocniczych przygotowywanych do kółek Mazowieckie talenty. Mam nadzieję, że pozwoli nie tylko lepiej zrozumieć metody krótko omawiane na zajęciach, ale także poznać szerokie możliwości jakie daje wyszukiwanie binarne. Będę bardzo wdzięczny za wszelkie uwagi i komentarze do tego tekstu. Można o nich pisać na forum na stronie: http://mtalenty.wikidot.com lub też na e-mail: mtalenty@gmail.com. Błażej Osiński