Złożoność obliczeniowa. Trudne zadania. wer. 8 Wojciech Myszka, Maciej Panek styczeń 2015r.
Złożoność algorytmów Złożoność algorytmów odnosi się do ilości zasobów niezbędnych do rozwiązania problemu. Przez zasoby rozumie się zazwyczaj: czas (złożoność czasowa), pamięć (złożoność pamięciowa).
Złożoność algorytmów Rodzaje Złożoność pamięciowa określa ilość pamięci wykorzystywanej podczas pracy algorytmu. Zależy w dużej mierze od wielkości danych wejściowych i wyjściowych, ale także od ilości wyników pośrednich. Złożoność czasowa ilość czasu niezbędnego do rozwiązania problemu w zależności od liczby danych wejściowych. Zależy od ilości wykonywanych operacji niezbędnych do otrzymania rozwiązania problemu (zazwyczaj w odniesieniu do operacji dominujących).
Część I Złożoność obliczeniowa
Raz jeszcze min/max z liczb... Danych jest n elementów X[1], X[2],..., X[n]; szukamy takich m i j, że m = X[j] = max 1 i n X[i] i j jest największym indeksem spełniającym ten warunek. Algorytm wyglądać będzie tak: 1. Inicjowanie Niech j n, k n 1, m X[n] 2. Czy wszystkie? Jeśli k = 0 to koniec 3. Porównanie Jeśli X[k] m to przejdź do 5 4. Zmiana m j k, m X[k] 5. Zmniejsz k k k 1; przejdź do 2 Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec
Raz jeszcze min/max z liczb... Danych jest n elementów X[1], X[2],..., X[n]; szukamy takich m i j, że m = X[j] = max 1 i n X[i] i j jest największym indeksem spełniającym ten warunek. Algorytm wyglądać będzie tak: 1. Inicjowanie Niech j n, k n 1, m X[n] 2. Czy wszystkie? Jeśli k = 0 to koniec 3. Porównanie Jeśli X[k] m to przejdź do 5 4. Zmiana m j k, m X[k] 5. Zmniejsz k k k 1; przejdź do 2 Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec
Raz jeszcze min/max z liczb... Danych jest n elementów X[1], X[2],..., X[n]; szukamy takich m i j, że m = X[j] = max 1 i n X[i] i j jest największym indeksem spełniającym ten warunek. Algorytm wyglądać będzie tak: 1. Inicjowanie Niech j n, k n 1, m X[n] 2. Czy wszystkie? Jeśli k = 0 to koniec 3. Porównanie Jeśli X[k] m to przejdź do 5 4. Zmiana m j k, m X[k] 5. Zmniejsz k k k 1; przejdź do 2 Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec
Raz jeszcze min/max z liczb... Danych jest n elementów X[1], X[2],..., X[n]; szukamy takich m i j, że m = X[j] = max 1 i n X[i] i j jest największym indeksem spełniającym ten warunek. Algorytm wyglądać będzie tak: 1. Inicjowanie Niech j n, k n 1, m X[n] 2. Czy wszystkie? Jeśli k = 0 to koniec 3. Porównanie Jeśli X[k] m to przejdź do 5 4. Zmiana m j k, m X[k] 5. Zmniejsz k k k 1; przejdź do 2 Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec
Raz jeszcze min/max z liczb... Danych jest n elementów X[1], X[2],..., X[n]; szukamy takich m i j, że m = X[j] = max 1 i n X[i] i j jest największym indeksem spełniającym ten warunek. Algorytm wyglądać będzie tak: 1. Inicjowanie Niech j n, k n 1, m X[n] 2. Czy wszystkie? Jeśli k = 0 to koniec 3. Porównanie Jeśli X[k] m to przejdź do 5 4. Zmiana m j k, m X[k] 5. Zmniejsz k k k 1; przejdź do 2 Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec
Analiza algorytmu Zajętość pamięci. W tym przypadku nic ciekawego zapotrzebowanie na pamięć jest proporcjonalne do liczby danych.
Analiza algorytmu Zajętość pamięci. W tym przypadku nic ciekawego zapotrzebowanie na pamięć jest proporcjonalne do liczby danych. Dokładność. Praktycznie nie są wykonywane żadne operacje matematyczne zatem nie dotyczy.
Analiza algorytmu Zajętość pamięci. W tym przypadku nic ciekawego zapotrzebowanie na pamięć jest proporcjonalne do liczby danych. Dokładność. Praktycznie nie są wykonywane żadne operacje matematyczne zatem nie dotyczy. Czas obliczeń. To może być ciekawe.
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz.
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz. Krok drugi n razy.
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz. Krok drugi n razy. Krok 3 n 1 razy.
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz. Krok drugi n razy. Krok 3 n 1 razy. Krok 4 A razy (jego wykonanie zależy od tego jakie są dane).
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz. Krok drugi n razy. Krok 3 n 1 razy. Krok 4 A razy (jego wykonanie zależy od tego jakie są dane). Krok 5 n 1 razy.
Czas obliczeń Start Czy 1 1 n 1 A inicjowanie wszystkie? Porównanie zmiana m A Zmniejszenie k tak nie n 1 A koniec Krok 1 wykonany będzie 1 raz. Krok drugi n razy. Krok 3 n 1 razy. Krok 4 A razy (jego wykonanie zależy od tego jakie są dane). Krok 5 n 1 razy. Zatem zajmiemy się liczbą wykonań kroku 4.
Krok 4 Średnia liczba wykonań Gdy dane wejściowe uporządkowane są w kolejności malejącej A = n 1
Krok 4 Średnia liczba wykonań Gdy dane wejściowe uporządkowane są w kolejności malejącej A = n 1 Gdy dane wejściowe uporządkowane są w kolejności rosnącej A = 0
Krok 4 Średnia liczba wykonań Gdy dane wejściowe uporządkowane są w kolejności malejącej A = n 1 Gdy dane wejściowe uporządkowane są w kolejności rosnącej A = 0 A jaka będzie średnia?
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1 X[2] < X[1] < X[3] 0
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1 X[2] < X[1] < X[3] 0 X[2] < X[3] < X[1] 1
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1 X[2] < X[1] < X[3] 0 X[2] < X[3] < X[1] 1 X[3] < X[1] < X[2] 1
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1 X[2] < X[1] < X[3] 0 X[2] < X[3] < X[1] 1 X[3] < X[1] < X[2] 1 X[3] < X[2] < X[1] 2
Przykład Niech n = 3; załóżmy również, że wszystkie liczby są różne. Wypiszmy wszystkie możliwe układy liczb X[1], X[2], X[3]: Układ Wartość A X[1] < X[2] < X[3] 0 X[1] < X[3] < X[2] 1 X[2] < X[1] < X[3] 0 X[2] < X[3] < X[1] 1 X[3] < X[1] < X[2] 1 X[3] < X[2] < X[1] 2 Jeżeli teraz założymy, że każdy z układów liczb X[1], X[2], X[3] jest jednakowo prawdopodobne, to średnia wartość A wyniesie (dla n = 3) (0 + 1 + 0 + 1 + 1 + 2)/6 = 5/6.
Analiza... Bez starty ogólności, możemy przyjąć, że liczby X[1], X[2],..., X[n] to liczby 1, 2,..., n w pewnej kolejności. Dodatkowo założymy, że każda z n! permutacji jest jednakowo prawdopodobna. Tu wycinamy bardzo wiele rachunków... Z analizy rachunków wynika, że w przypadku gdy n = 12 średnia dla zmiennej losowej A wynosi około 2,1, a wariancja około 1,54.
Analiza algorytmu min/max... Algorytm jest bardzo prosty. Jedyne operacje wykonywane to porównanie (krok 2) i zamiana (krok 4). W zależności od liczby danych (n) liczba porównań jest stała n 1, a liczba zamian jest jakimś ułamkiem n. W takim przypadku piszemy że liczba zamian jest proporcjonalna do n, co zapisujemy czasami jako n. W teorii algorytmów częściej mówi się że złożoność czasowa algorytmu jest O(n) (co można czytać duże-o od n ). Nie jest ważny współczynnik proporcjonalności, ważne jest jedynie to, że w raz ze wzrostem n rośnie tak samo szybko czas obliczeń.
O(n) Mamy dwa (hipotetyczne) problemy: 1. Pierwszy wykonuje się w czasie proporcjonalnym do n 2. Drugi w czasie proporcjonalnym do 1 2 n Drugie zadanie wykonuje się dwa razy szybciej! Oba zadania wykonują się w czasie O(n)! Jest to zatem dosyć grube spojrzenie na czas obliczeń.
Liniowe wyszukiwanie Mamy książkę telefoniczną czyli listę <nazwisko, numer_telefonu>. Zadanie polega na znalezieniu numeru telefonicznego osoby o zadanym nazwisku. Najprostszy algorytm jest taki 1. i 1 2. Czy poszukiwane_nazwisko = nazwisko(i) 3. Jeżeli tak Koniec 4. W przeciwnym razie i i + 1 5. Jeżeli i > n Koniec: nie znaleziono! 6. W przeciwnym razie przejdź do kroku 2 Im dłuższa lista nazwisk tym dłużej pracuje algorytm.
Liniowe wyszukiwanie c. d. W najlepszym razie pętla wykonana będzie tylko jeden raz. W najgorszym razie n razy. Średnio? To zależy jaki jest rozkład prawdopodobieństwa zapytań...
Liniowe wyszukiwanie lepszy algorytm Jeżeli uwzględnić fakt, że dane w książce telefonicznej są posortowane algorytm można istotnie ulepszyć. Pierwsze porównanie należy wykonać nie z pierwszym (czy ostatnim) nazwiskiem, tylko ze środkowym (znajdującym się dokładnie na środku listy). Jeżeli szukane nazwisko jest większe nie należy zajmować się pierwszą połową listy... Takie podejście w jednym kroku redukuje rozmiar zadania o połowę! Każdy kolejny krok jest podobny zatem wielkość zadania zmniejsza się za każdym razem. W przypadku książki telefonicznej o N nazwiskach potrzeba (w najgorszym razie) log 2 (N) kroków.
Liniowe wyszukiwanie schemat blokowy
Jak bardzo O(log(N)) jest lepsze od O(N)? N log 2 (N) 10 4 100 7 1000 10 milion 20 miliard 30 miliard miliardów 60
Pętle zagnieżdżone 1. wykonaj co następuje N 1 razy... 1.1 wykonaj co następuje N 1 razy... Pętla wewnętrzna wykonywana jest N 1 razy dla każdego z N 1 wykonań pętli zewnętrznej. Koszt czasowy dwu pętli jest zatem (N 1)(N 1) czyli N 2 2N + 1. Dla dużych N składniki 1 2N są nieistotne. Zatem koszt czasowy takiej pętli jest O(N 2 ).
Koszt czasowy rekurencji Rekurencyjny algorytm wyszukiwania minimum i maksimum w L (znajdź-min-i-max-w L): 1. jeśli L składa się z jednego elementu to nadaj MIN i MAX właśnie jego wartość; jeśli L składa się z dwu elementów, to nadaj MIN wartość mniejszego z nich, a MAX większego; 2. w przeciwnym razie wykonaj co następuje: 2.1 podziel L na połowy L 1 i L 2 ; 2.2 wywołaj znajdź-min-i-max-w L 1, umieszczając otrzymane wartości w MIN 1 i MAX 1 ; 2.3 wywołaj znajdź-min-i-max-w L 2, umieszczając otrzymane wartości w MIN 2 i MAX 2 ; 2.4 nadaj MIN mniejszą wartość z MIN 1 i MIN 2 ; 2.5 nadaj MAX większą wartość z MAX 1 i MAX 2 ; 3. wróć z wartościami MIN i MAX
Minimum i maksimum wersja klasyczna (naiwna) 1. MIN L(1); MAX L(1) 2. i 1 3. jeżeli L(i) > MAX to MAX L(i) 4. jeżeli L(i) < MIN to MIN L(i) 5. jeżeli i < N to i i + 1, przejdź do 3 6. KONIEC W tym algorytmie główna operacja to porównania; algorytm potrzebuje 2N porównań.
Analiza algorytmu rekurencyjnego I 1. jeśli N = 1 lub N = 2, wykonuje się dokładnie jedno porównanie punkt 1 procedury. 2. jeśli N > 2, to porównania, które się wykonuje, stanowią dokładnie dwa zbiory porównań dla list o długości N/2 i dwa dodatkowe porównania (wiersze 2.4 i 2.5)
Analiza algorytmu rekurencyjnego II Zatem (C(N) oznacza liczbę porównań dla listy N elementowej) (czemu jest to +2?) Można rozwiązać to równanie. C(1) = C(2) = 1 (1) C(N) = 2C(N/2) + 2 (2) C(N) = 3N/2 2 = 3 N 2< 2N (3) 2
Wieże Hanoi Złożoność czasowa podawanego algorytmu wynosi 2 N 1 (gdzie N to liczba krążków). Zatem algorytm jest O(2 N )
Wieże Hanoi Alternatywny algorytm (Zakładamy, że nasze trzy kołki są ustawione w kółko i że na początku wszystkie N krążków spoczywa na jednym z nich.) 1. powtarzaj wykonywanie tego, co następuje, dopóty, dopóki, w chwili poprzedzającej podjęcie kroku 1.1 wszystkie krążki nie będą poprawnie ułożone na jakimś innym kołku: 1.1 przenieś najmniejszy krążek z kołka, na którym właśnie spoczywa, na kołek następny w kierunku zgodnym z ruchem wskazówek zegara; 1.2 wykonaj jedyne możliwe przeniesienie nie dotyczące najmniejszego krążka. A jaka jest złożoność tego algorytmu?
Małpia układanka Prosta gra, w której do dyspozycji gracza jest kilka (9?) kwadratowych kart, na bokach których wydrukowane są górna i dolne połowy kolorowych małp. Zadanie polega na ułożeniu kart w postaci kwadratu (3 3), aby na zetknięciach się krawędzi połowy małp pasowały do siebie, a kolory były identyczne...
Zatem złożoność tego algorytmu jest rzędu O(N!) Małpia układanka cd Najbardziej elementarny komputerowy algorytm rozwiązywania tej układanki sprowadzi się najprawdopodobniej, do przeglądu wszystkich możliwych układów kart. Wybieramy jedną z kart, układamy ją na pierwszym miejscu (odpowiednio wszystkie miejsca ponumerowaliśmy); na drugim miejscu mamy N 1 kart do wyboru, na kolejnym N 2, itd... Następnie sprawdzamy czy spełnione są warunki. Zatem liczba możliwych do rozpatrzenia kombinacji wynosi: N (N 1) (N 2) 2 1 = N! (4)
Rozsądny i nierozsądny czas działania Funkcja / N 10 50 100 300 1000 5N 50 250 500 1500 5000 N log 2 (N) 33 282 665 2469 9966 N 2 100 2500 10000 90000 1 milion (7 cyfr) N 3 1000 125000 1 milion (7 cyfr) 2 N 1024 liczba 16-cyfrowa N! 3,6 miliona (7 cyfr) N N 10 miliardów (11 cyfr) liczba 65-cyfrowa liczba 85-cyfrowa liczba 31-cyfrowa liczba 161-cyfrowa liczba 201-cyfrowa 27 milionów (8 cyfr) liczba 91-cyfrowa liczba 623-cyfrowa liczba 744-cyfrowa 1 miliard (10 cyfr) liczba 302-cyfrowa niewyobrażalnie duża niewyobrażalnie duża
Wykresy różnych funkcji
Tabelka...
Zadania łatwe i trudne I Jak widać z wykresów i tabelek zawsze można znaleźć zadanie którego nie da się rozwiązać w rozsądnym czasie. Przyjęto dzielić zadania na łatwe jeżeli funkcja opisująca czas ich wykonania jest ograniczona jakąś funkcją wielomianową. Zadania trudne to zadania o czasie wykonania ponadwielomianowym lub wykładniczym.
Zadania łatwe i trudne II Podsumowanie Problemy trudno rozwiązywalne wymagają niepraktycznie dużo czasu nawet dla względnie małych danych wejściowych. Problemy łatwo rozwiązywalne mają algorytmy, które są praktyczne dla zadań o rozsądnych wymiarach.
Wątpliwości 1. Komputery stają się coraz szybsze (ostatnio, w ciągu roku szybkość komputerów wzrastało dziesięciokrotnie). Być może za czas jakiś pojawi się komputer wystarczająco szybki by rozwiązywać trudne zadania?
Wątpliwości 1. Komputery stają się coraz szybsze (ostatnio, w ciągu roku szybkość komputerów wzrastało dziesięciokrotnie). Być może za czas jakiś pojawi się komputer wystarczająco szybki by rozwiązywać trudne zadania? 2. Czy fakt, że nie znaleźliśmy lepszego algorytmu nie wskazuje na naszą niekompetencję? Może warto zwiększyć wysiłek aby polepszyć sytuację?
Wątpliwości 1. Komputery stają się coraz szybsze (ostatnio, w ciągu roku szybkość komputerów wzrastało dziesięciokrotnie). Być może za czas jakiś pojawi się komputer wystarczająco szybki by rozwiązywać trudne zadania? 2. Czy fakt, że nie znaleźliśmy lepszego algorytmu nie wskazuje na naszą niekompetencję? Może warto zwiększyć wysiłek aby polepszyć sytuację? 3. Być może uda się znaleźć jakiś dowód, że problem nie ma rozsądnego algorytmu?
Wątpliwości 1. Komputery stają się coraz szybsze (ostatnio, w ciągu roku szybkość komputerów wzrastało dziesięciokrotnie). Być może za czas jakiś pojawi się komputer wystarczająco szybki by rozwiązywać trudne zadania? 2. Czy fakt, że nie znaleźliśmy lepszego algorytmu nie wskazuje na naszą niekompetencję? Może warto zwiększyć wysiłek aby polepszyć sytuację? 3. Być może uda się znaleźć jakiś dowód, że problem nie ma rozsądnego algorytmu? 4. Czy trudny problem (małpiej układanki) nie jest przypadkiem jedynym takim zadaniem? Jest ono ciekawe, ale jakie ma praktyczne zastosowanie?
Szybszy komputer Maksymalna liczba kart rozwiązywanych w ciągu godziny O(?) na dzisiejszym na komputerze na komputerze komputerze 100 razy szybszym 1000 razy szybszym N A 100 A 1000 A N 2 B 10 B 31,6 B 2 N C C + 6,64 C + 9,97
Wymyślony algorytm (o małpiej układance) Niestety nie. Znaleziono bardzo wiele (około 1000) problemów, które sprowadzają się do przeglądu zupełnego wszystkich możliwych wariantów (ustawień danych). Można zaproponować algorytmy nierozsądne nie udało się pokazać że może istnieć dokładny algorytm lepszy... Źródłem trudnych zadań są takie dziedziny jak kombinatoryka, badania operacyjne, ekonomia, teoria grafów i logika.
Jak sobie radzimy z trudnymi zadaniami? Zrównoleglenie (zadanie dzielone jest na mniejsze kawałki i wysyłane na wiele komputerów).
Jak sobie radzimy z trudnymi zadaniami? Zrównoleglenie (zadanie dzielone jest na mniejsze kawałki i wysyłane na wiele komputerów). Randomizacja. Zamiast przeglądać wszystkie możliwe rozwiązania w sposób losowy wybiera się niektóre z nich. Pozostają te, które w najlepszy sposób spełniają nasze oczekiwania.
Jak sobie radzimy z trudnymi zadaniami? Zrównoleglenie (zadanie dzielone jest na mniejsze kawałki i wysyłane na wiele komputerów). Randomizacja. Zamiast przeglądać wszystkie możliwe rozwiązania w sposób losowy wybiera się niektóre z nich. Pozostają te, które w najlepszy sposób spełniają nasze oczekiwania. Komputery kwantowe.???
Jak sobie radzimy z trudnymi zadaniami? Zrównoleglenie (zadanie dzielone jest na mniejsze kawałki i wysyłane na wiele komputerów). Randomizacja. Zamiast przeglądać wszystkie możliwe rozwiązania w sposób losowy wybiera się niektóre z nich. Pozostają te, które w najlepszy sposób spełniają nasze oczekiwania. Komputery kwantowe.??? Obliczenia molekularne.???
Do czego może nadać się komputer kwantowy? Jeżeli mamy zadanie spełniające następujące warunki: 1. Jedyna znana metoda rozwiązania go to zgadnięcie i sprawdzenie. 2. Do sprawdzenia mamy n możliwych odpowiedzi. 3. Każde sprawdzenie zajmuje tyle samo czasu. 4. Nie ma żadnych wskazówek na temat kolejności sprawdzania (każda, nawet losowa, kolejność jest dobra). Czas rozwiązania takich zadań przez komputer kwantowy będzie proporcjonalny do pierwiastka kwadratowego z n.
Komputer kwantowy?
Część II Poprawność algorytmów
Błędy Każdy program ma błędy. Tak długo, jak używany jest jedynie do zabawy nie odgrywa to większej roli. Programy komercyjne...
Licencja Gwarancja. Produkt jest zaprojektowany i oferowany jako produkt ogólnego zastosowania, a nie dla określonego celu jakiegokolwiek użytkownika. Licencjobiorca uznaje, ze Produkty mogą być wadliwe. W związku z powyższym zdecydowanie zaleca się Licencjobiorcy systematyczną archiwizację plików.[...] Produkt będzie działał zasadniczo zgodnie z załączonymi do Produktu materiałami drukowanymi, oraz (b) usługi pomocy technicznej świadczone przez firmę XXX będą zasadniczo zgodne z opisem zamieszczonym w odpowiednich materiałach drukowanych dostarczonych Licencjobiorcy przez firmę XXX, a pracownicy pomocy technicznej firmy XXX podejmą uzasadnione działania i wysiłki w celu rozwiązania ewentualnych problemów.[...] Ograniczenie Odpowiedzialności. W maksymalnym zakresie dozwolonym przez prawo właściwe i z wyjątkiem postanowień gwarancji firmy XXX, firma XXX oraz jej dostawcy nie będą ponosić odpowiedzialności za żadne szkody[...] W każdym przypadku, całkowita odpowiedzialność firmy XXX na podstawie niniejszej Umowy jest ograniczona do kwoty rzeczywiście zapłaconej przez Licencjobiorcę za Produkt. [...]
Bug Błędy, w żargonie informatyków zwykło się nazywać pluskwami (czy może, raczej robalami?). Po angielsku bug. Anegdota mówi, że w 1945 roku Grace Murray Hopper (autorka Cobola) korzystała z prymitywnego kalkulatora (działającego na przekaźnikach). Pojawiły się problemy z pracą kalkulatora. Po badaniach, okazało się, że jakiś robaczek latający wpadł między styki przekaźnika. Sporządzono raport, który zachował się do dziś...
Czy są programy wolne od błędów? Dobre pytanie.
Czy są programy wolne od błędów? Dobre pytanie. Właściwie nie ma...
Czy są programy wolne od błędów? Dobre pytanie. Właściwie nie ma...... ale
Czy są programy wolne od błędów? Dobre pytanie. Właściwie nie ma...... ale
Donald Knuth i T E X Więcej na temat tego w jaki sposób efekt ten osiągnął Donald Knuth poczytać można na stronach Wikipedii: http://en.wikipedia.org/wiki/knuth_reward_check, a przyklady czeków wystawionych przez Knutha polskim użytkownikom T E Xa na stronach GUST: http://www.gust.org.pl/dek-checks/index_html
Uruchamianie programów i badanie ich poprawności Szacuje się, że ponad 70% nakładów na opracowanie złożonych systemów oprogramowania pochłania usuwanie błędów. Komputery zasadniczo są nieomylne. Psują się, ale przypadki, że generują błędne obliczenia są tak rzadkie, że spokojnie mówimy iż są nieomylne... Mylą się ludzie: na etapie opracowania algorytmu na etapie jego programowania podczas obsługi programu
O nieomylności komputerów I Czerwiec 1994: Testerzy firmy Intel zauważyli, że procesor źle liczy (błąd w instrukcji dzielenia). Kierownictwo uznało, że problem nie dotknie zbyt wielu użytkowników. 19 października: Jeden z użytkowników zauważa błąd i nabiera pewności, że to procesor (Pentium). 4195835.0/3145727.0 = 1.333 820 449 136 241 002 (Correct value) 4195835.0/3145727.0 = 1.333 739 068 902 037 589 (Flawed Pentium) 24 października: zgłasza błąd do Intela, osoba odpowiedzialna za kontakt z klientem potwierdza błąd (odtwarza go), i mowi, że nikt jeszcze go nie zgłosił.
O nieomylności komputerów II 30 pażdziernika odkrywca sprawę upublicznia (kilku swoim znajomym). 3 listopada informacja o błędzie pojawia się na grupie dyskusyjnej. 7 listopada Intel przyznaje się publicznie do błędu i ogłasza, że kolejne wydania procesora były już od niego wolne. 23 listopada pierwszy z producentów oprogramowania matematycznego (Mathworks) wypuszcza wersję Matlaba z modyfikacjami niwelujacymi błąd. 24 listopada okazuje się, że Intel ciągle sprzedaje błędne procesory.
O nieomylności komputerów III 30 listopada Intel przedstawia dokładny raport opisujący problem (i potencjalne jego konsekwencje) [?]. Za późno! 12 grudnia IBM publikuje swój własny raport oceniający znacznie poważniej konsekwencje błędu i ogłasza, że wstrzymuje sprzedaż komputerów PC z procesorem Intela. 16 grudnia akcje Intela sadają o 3,25$ (ok. 5%) 20 grudnia: Intel przeprasza i obiecuje bezpłatnie wymienić wadliwe procesory na żądanie. (Na podstawie [?])
Przyczyny problemów Intela I 1. Niecheć Intela do poinformowania o problemie swoich najważniejszych klientów. 2. Niepoinformowanie swojej pomocy technicznej, co uniemożliwiło traktowanie zgłaszających bład w sposób specjalny. 3. Pierwsze informacje Intela na temat problemu były odbierane przez wszystkich (poza firmą) jako nizadawalające i zdawkowe. 4. Nowy procesor Intela (Pentium) był przedmiotem bardzo intensywnej kampanii reklamowej.
Przyczyny problemów Intela II 5. Błąd dotyczył bardzo podstawowej operacji, którą łatwo było zademonstrować niefachowcom. 6. Błąd został wykryty na bardzo późnym etapie testowania procesora (po tym jak bardzo wiele procesorów zostało już sprzedanych). 7. Internet i sposób jego funkcjonowania. 8. Poważny konkurent firmy (IBM) zdecydował się na opublikowanie własnych analiz przedstawiających w innym świetle problem.
Znaczenie błędu
Znaczenie błędu Na podstawie [?]
Jeszcze jedna definicja algorytmu Zadanie algorytmiczne można scharakteryzować zwięźle jako złożone z: 1. zbioru I dopuszczalnych danych wejściowych 2. zależności R między danymi a żądanymi wynikami O R : I O
Poprawność częściowa i całkowita Algorytm A jest częściowo poprawny względem I i R, gdy dla każdego zestawu danych X z I, jeżeli A uruchomiony dla X zatrzyma się, to relacja R między X a otrzymanym zestawem wyników jest spełniona. Częściowo poprawny algorytm sortowania mógłby zatrzymywać się nie dla wszystkich list dopuszczalnych, ale zatrzymując się, zawsze da w wyniku listę uporządkowaną poprawnie. Algorytm całkowicie poprawny poprawnie rozwiązuje zadanie dla każdego zestawu danych X z I
Poprawność częściowa i całkowita
Czy trzeba udowadniać poprawność algorytmów? Systemy bankowe... Systemy sterowania rakietami (balistycznymi) Pojazdy kosmiczne Systemy nadzoru chorych System ABS... A praktyka jest taka (wedle powiedzonek): oprogramowanie udostępnia się użytkownikom nie wtedy, kiedy jego poprawność staje się pewna, ale wtedy, gdy szybkość odkrywania nowych błędów spada do poziomu, który może być zaakceptowany...
Jak to się robi? Ba!
Jak to się robi? Ba! Dla każdego poprawnego algorytmu można ściśle wykazać, że jest on poprawny.
Jak to się robi? Ba! Dla każdego poprawnego algorytmu można ściśle wykazać, że jest on poprawny. Inna sprawa, czy to łatwo zrobić...
Jak to się robi? cd Obowiązują ogólne zasady: Z tego, że program działa poprawnie dla każdego zestawu danych, który wypróbowaliśmy nie wynika wcale, że działa dobrze dla innych zestawów.
Jak to się robi? cd Obowiązują ogólne zasady: Z tego, że program działa poprawnie dla każdego zestawu danych, który wypróbowaliśmy nie wynika wcale, że działa dobrze dla innych zestawów. Jeżeli uda się nam znaleźć jeden jedyny dopuszczalny zestaw danych, dla którego program działa źle to jest zły.
Jak to się robi? cd Obowiązują ogólne zasady: Z tego, że program działa poprawnie dla każdego zestawu danych, który wypróbowaliśmy nie wynika wcale, że działa dobrze dla innych zestawów. Jeżeli uda się nam znaleźć jeden jedyny dopuszczalny zestaw danych, dla którego program działa źle to jest zły. Idealna sytuacja dla osób, które potrafią być tylko destrukcyjne!
Jak to się robi? cdcd Zazwyczaj zależy nam, żeby algorytm kiedyś się zatrzymał.
Jak to się robi? cdcd Zazwyczaj zależy nam, żeby algorytm kiedyś się zatrzymał. Aby wykazać, że algorytm kiedyś się zatrzyma można wybrać jakąś wielkość zależną od zmiennych i struktur danych algorytmu i wykazać, że wielkość ta jest zbieżna.
Jak to się robi? cdcd Zazwyczaj zależy nam, żeby algorytm kiedyś się zatrzymał. Aby wykazać, że algorytm kiedyś się zatrzyma można wybrać jakąś wielkość zależną od zmiennych i struktur danych algorytmu i wykazać, że wielkość ta jest zbieżna. Jest mi bardzo przykro, że przypomina to Analizę Matematyczną...
Prosty przykład Odwracanie napisu Mamy pewien napis S zbudowany z ciągu symboli (na przykład zdanie języka naturalnego). Zadanie polega na stworzeniu procedury odwrócone(s) zwracającej symbole w kolejności odwrotnej. odwrócone("ala ma kota") "atok am ala"
Odwracanie napisu Schemat blokowy
Odwracanie napisu Schemat blokowy
Odwracanie napisu Schemat blokowy λ to pusty napis
Odwracanie napisu Schemat blokowy λ to pusty napis głowa(x) to funkcja zwracająca pierwszy symbol z napisu X; głowa("ala ma kota")="a"
Odwracanie napisu Schemat blokowy λ to pusty napis głowa(x) to funkcja zwracająca pierwszy symbol z napisu X; głowa("ala ma kota")="a" to operator konkatenacji (łączenia napisów); "Ala " "ma kota"="ala ma kota"
Odwracanie napisu Schemat blokowy λ to pusty napis głowa(x) to funkcja zwracająca pierwszy symbol z napisu X; głowa("ala ma kota")="a" to operator konkatenacji (łączenia napisów); "Ala " "ma kota"="ala ma kota" ogon(x) to funkcja zwracająca napis X bez głowy ; ogon("ala ma kota")="la ma kota"
Odwracanie napisu Algorytm działa w kółko, kolejno odrywając symbole z końca S i dołączając je na początku nowo tworzonego napisu Y. Początkowo napis rozpoczyna jako pusty. Procedura kończy się, kiedy nic już nic nie zostanie do oderwania z S. Odrywania dokonuje się używając zmiennej X, której początkowo nadaje się wartość S, tak aby nie niszczyć oryginalnej wartości S.
Badanie poprawności Idea postępowania: Tworzymy punkty kontrolne (asercje). Pierwsza z nich kontroluje dane wejściowe (czy zgodne z założeniami). Ostatnia sprawdza wynik. Najistotniejsza jest jednak druga. Nadzoruje ona sytuację przed podjęciem decyzji czy potrzebne jest jest jeszcze jedno wykonanie pętli czy należy już kończyć. Stwierdza ona, że w punkcie kontrolnym (2) połączone wartości X i Y tworzą początkowy napis (przy czym Y jest odwrócony!) Pokazać powinniśmy, że wszystkie asercje są niezmiennikami, to znaczy, że podczas każdego wykonania algorytmu są prawdziwe (dla danych dopuszczalnych!)
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego.
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego.
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego. W przypadku tego algorytmu możliwe są trzy drogi: z (1) do (2), z (2) do (3) i z (2) do (2)
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego. W przypadku tego algorytmu możliwe są trzy drogi: z (1) do (2), z (2) do (3) i z (2) do (2) Pierwsza z nich przechodzona jest tylko jeden raz na samym początku
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego. W przypadku tego algorytmu możliwe są trzy drogi: z (1) do (2), z (2) do (3) i z (2) do (2) Pierwsza z nich przechodzona jest tylko jeden raz na samym początku Druga z nich co najwyżej jeden raz gdy algorytm się zatrzymuje.
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego. W przypadku tego algorytmu możliwe są trzy drogi: z (1) do (2), z (2) do (3) i z (2) do (2) Pierwsza z nich przechodzona jest tylko jeden raz na samym początku Druga z nich co najwyżej jeden raz gdy algorytm się zatrzymuje. Trzecia przechodzona będzie wiele razy (ile?)
Badanie poprawności, cd Sztuczka polega na tym, że rozpatruje się wszystkie możliwe drogi podążania procesora z jednego punktu kontrolnego do następnego. W przypadku tego algorytmu możliwe są trzy drogi: z (1) do (2), z (2) do (3) i z (2) do (2) Pierwsza z nich przechodzona jest tylko jeden raz na samym początku Druga z nich co najwyżej jeden raz gdy algorytm się zatrzymuje. Trzecia przechodzona będzie wiele razy (ile?) Zauważmy, że w żadnym odcinku nie występują już pętle. Instrukcje są dosyć proste... Idea postępowania polega na pokazaniu, że jeśli asercja na początku odcinka jest prawdziwa i rzeczywiście przejdziemy ten odcinek to asercja na końcu odcinka również będzie prawdziwa kiedy do niej dotrzemy.
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi.
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi. Jeżeli dla każdego odcinka z prawdziwości asercji początkowej wynika prawdziwość asercji końcowej...
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi. Jeżeli dla każdego odcinka z prawdziwości asercji początkowej wynika prawdziwość asercji końcowej... I jeśli pierwsza asercja w całym ciągu odpowiada poprawności danych wejściowych (z góry jest przyjęta za prawdziwą)...
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi. Jeżeli dla każdego odcinka z prawdziwości asercji początkowej wynika prawdziwość asercji końcowej... I jeśli pierwsza asercja w całym ciągu odpowiada poprawności danych wejściowych (z góry jest przyjęta za prawdziwą)... To prawdziwość asercji propaguje się wzdłuż całego ciągu...
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi. Jeżeli dla każdego odcinka z prawdziwości asercji początkowej wynika prawdziwość asercji końcowej... I jeśli pierwsza asercja w całym ciągu odpowiada poprawności danych wejściowych (z góry jest przyjęta za prawdziwą)... To prawdziwość asercji propaguje się wzdłuż całego ciągu... Zatem prawdziwa będzie i asercja końcowa...
Asercje... Przebieg algorytmu składa się z odcinków oddzielonych punktami kontrolnymi. Jeżeli dla każdego odcinka z prawdziwości asercji początkowej wynika prawdziwość asercji końcowej... I jeśli pierwsza asercja w całym ciągu odpowiada poprawności danych wejściowych (z góry jest przyjęta za prawdziwą)... To prawdziwość asercji propaguje się wzdłuż całego ciągu... Zatem prawdziwa będzie i asercja końcowa... Co gwarantuje częściową poprawność algorytmu.
Co teraz trzeba zrobić? Udowodnić należy trzy twierdzenia: (1 2) Dla każdego napisu S po wykonaniu dwóch instrukcji X S; Y λ będzie spełniona równość S = odwrócone(y) X
Co teraz trzeba zrobić? Udowodnić należy trzy twierdzenia: (1 2) Dla każdego napisu S po wykonaniu dwóch instrukcji X S; Y λ będzie spełniona równość S = odwrócone(y) X (2 3) Jeśli S = odwrócone(y) X i X = λ to Y = odwrócone(s)
Co teraz trzeba zrobić? Udowodnić należy trzy twierdzenia: (1 2) Dla każdego napisu S po wykonaniu dwóch instrukcji X S; Y λ będzie spełniona równość S = odwrócone(y) X (2 3) Jeśli S = odwrócone(y) X i X = λ to Y = odwrócone(s) (2 2) Jeśli S = odwrócone(y) X i X λ to po wykonaniu instrukcji Y głowa(x) Y; X ogon(x) zachodzi równość S = odwrócone(y) X dla nowych wartości X i Y.
Dowód Zacznijmy od (1 2). Po wykonaniu X S zmienna X ma wartość S, a po wykonaniu jeszcze Y λ zmienna Y zawiera napis pusty. Czyli odwrócone(y) = odwrócone(λ), zatem odwrócone(y) X = λ X = X. Równością, która miała zachodzić po wykonaniu tych dwu instrukcji jest więc po prostu S = X. Co kończy dowód. W analogiczny sposób można pokazać (2 3).
Dowód cd Pokażemy teraz, że (2 2), czyli jeśli spełniona jest asercja 2 i pętla będzie wykonana jeden raz to asercja zostanie spełniona i po tym wykonaniu. Załóżmy, że X λ (czyli w szczególności, że X ma i głową i ogon puste napisy ich nie mają) i że napis S jest dokładnie taki sam jak odwrócone(y) X. Wykonujemy teraz działania: zatem Y głowa(x) Y i X ogon(x) odwrócone(y) X = odwrócone(głowa(x) Y) ogon(x) = odwrócone(y) głowa(x) ogon(x) = odwrócone(y) X
Wnioski Pokazaliśmy, że wszystkie asercje są spełnione. Zatem algorytm jest częściowo poprawny (czyli jeżeli się zatrzyma to daje poprawne wyniki. Jak pokazać, że zatrzyma się dla każdych poprawnych danych? Jedynie miejsce gdzie algorytm może się zapętlić to ścieżka (2 2). Ale na tej ścieżce za każdym razem dokonywana jest operacja odcinania głowy od X co powoduje, że za każdym razem X jest krótszy. Gdy X będzie napisem jednoliterowym odcięcie głowy stworzy pusty ciąg znaków. Zatem algorytm jest poprawny!
I po co to wszystko? 1. Algorytm był prosty, a dowód zagmatwany (i mocno matematyczny). 2. Jego istota polega na odpowiednim doborze punktów kontrolnych (początek i koniec algorytmu, oraz kilka takich innych miejsc między innymi tak dobranych aby likwidować pętle. 3. Ważną sprawą jest dobór niezmienników (asercji). 4. Na koniec należy dobrać warunek stopu czyli taki parametr o którym można powiedzieć że w trakcie wykonywania algorytmu będzie zmierzał do jakiejś wartości (będzie zbieżny). Niestety, nie da się skonstruować automatu, który będzie służył do dowodzenia poprawności algorytmów...
(Za https://plus.google.com/u/0/111221966647232053570/posts/cg1ra6arkqk)
Bibliografia