Przed przeczytaniem „Sztuki programowania komputerowego” (TAOCP) nie zastanawiałem się głęboko nad tymi pytaniami. Używałbym pseudokodu do opisywania algorytmów, rozumienia ich i szacowania czasu działania tylko o rzędach wzrostu. TAOCP gruntownie zmienia zdanie.
TAOCP używa angielskiego mieszanego z krokami i goto do opisywania algorytmu, i wykorzystuje schematy blokowe do łatwiejszego zobrazowania algorytmu. Wygląda na niski poziom, ale uważam, że są pewne zalety, szczególnie w przypadku schematu blokowego, który bardzo często ignorowałem. Każdą ze strzałek możemy oznaczyć twierdzeniem o aktualnym stanie rzeczy w chwili, gdy obliczenia przechodzą przez tę strzałkę, i wykonać indukcyjny dowód na algorytm. Autor mówi:
Twierdzeniem autora jest to, że naprawdę rozumiemy, dlaczego algorytm jest ważny tylko wtedy, gdy osiągniemy punkt, w którym nasze umysły pośrednio wypełniły wszystkie twierdzenia, jak to pokazano na ryc. 4.
Nie doświadczyłem takich rzeczy. Kolejną zaletą jest to, że możemy policzyć, ile razy każdy krok jest wykonywany. Łatwo jest sprawdzić pierwsze prawo Kirchhoffa. Nie analizowałem dokładnie czasu działania, więc niektóre mogło zostać pominięte, gdy szacowałem czas działania.
Analiza rzędów wzrostu jest czasami bezużyteczna. Na przykład nie możemy odróżnić quicksort od heapsort, ponieważ wszystkie są , gdzie E X jest oczekiwaną liczbą zmiennych losowych X , dlatego powinniśmy przeanalizować stałą, powiedzmy E ( T 1 ( n ) ) = A 1 n lg n + B 1 n + O ( log n )i , dzięki czemu możemy lepiej porównać i . A także czasami powinniśmy porównywać inne wielkości, takie jak wariancje. Tylko zgrubna analiza rzędów wzrostu czasu pracy nie wystarczy. Jako TAOCP tłumaczy algorytmy na język asemblerowy i oblicza czas działania, To dla mnie zbyt trudne, więc chcę poznać niektóre techniki bardziej szczegółowej analizy czasu działania, co jest również przydatne, w przypadku języków wyższego poziomu, takich jak C, C ++ lub pseudokody.
I chcę wiedzieć, jaki styl opisu jest używany głównie w pracach badawczych i jak leczyć te problemy.
źródło
Odpowiedzi:
Istnieje ogromna różnorodność wykonalnych podejść. To, co najlepiej pasuje, zależy od
Jeśli algorytm jest powszechnie znany, którego używasz jako podprogramu, często pozostajesz na wyższym poziomie. Jeśli algorytm jest głównym przedmiotem badań, prawdopodobnie chcesz być bardziej szczegółowy. To samo można powiedzieć o analizach: jeśli potrzebujesz z grubsza górnej granicy czasu wykonywania, postępujesz inaczej niż wtedy, gdy chcesz precyzyjnej liczby instrukcji.
Podam trzy przykłady dobrze znanego algorytmu Mergesort, które, mam nadzieję, ilustrują to.
Wysoki poziom
Algorytm Mergesort pobiera listę, dzieli ją na dwie (mniej więcej) jednakowo długie części, powtarza się na tych listach częściowych i łączy (posortowane) wyniki, aby posortować wynik końcowy. W przypadku pojedynczych lub pustych list zwraca dane wejściowe.
Średni poziom
Algorytm Mergesort podaje następujący pseudo-kod:
mergesort
left
right
while
result
result
left
right
while
reverse
while
reverse
mergesort
Ultra niski poziom
Rozważ to (ogólne) wdrożenie Mergesort w Isabelle / HOL :
Obejmuje to już dowody dobrego zdefiniowania i rozwiązania umowy. Znajdź (prawie) kompletny dowód poprawności tutaj .
W przypadku „środowiska wykonawczego”, czyli liczby porównań, można ustawić powtarzalność podobną do tej z poprzedniej sekcji. Zamiast korzystać z twierdzenia Master i zapominając o stałych, można również je przeanalizować, aby uzyskać przybliżenie, które jest asymptotycznie równe prawdziwej wielkości. Pełną analizę można znaleźć w [1]; Oto ogólny zarys (niekoniecznie pasuje do kodu Isabelle / HOL):
Jak wyżej, powtarzalność liczby porównań jest
do czego prowadzi nas formuła Perrona
Ocena zależy od tego, który przypadek jest analizowany. Poza tym możemy - po pewnym oszustwie - zastosować twierdzenie o pozostałościach, aby uzyskać⊟(s)
gdzie jest funkcją okresową o wartościach w .A [−1,−0.9]
źródło
„Dyscyplina programowania” Dijkstry polega na analizowaniu i sprawdzaniu algorytmów oraz projektowaniu pod kątem niezawodności. W przedmowie do tej książki Dijkstra wyjaśnia, w jaki sposób bardzo prosty skonstruowany mini-język, odpowiednio zaprojektowany do analizy, wystarcza do formalnego wyjaśnienia wielu algorytmów:
Później wyjaśnia, jak mały zdołał zdobyć swój mini-język.
źródło