2010-03-05 17 views
18

Co to jest złożoność Big-O dla szeroko rozpowszechnionych algorytmów podstawowych działań arytmetycznych, takich jak mnożenie, pierwiastek kwadratowy, logarytm, iloczyn skalarny i macierzowy?Duża złożoność O podstawowych operacji arytmetycznych

Czy istnieją egzotyczne algorytmy, które są bardziej wydajne pod względem złożoności Big-O, ale nie są zbyt rozpowszechnione w praktycznych rozwiązaniach (np. Nie są implementowane w popularnych bibliotekach oprogramowania)?

+2

+1 Interesujące pytanie. Dla wyjaśnienia, prawdopodobnie oznacza on złożoność wraz ze wzrostem liczby bitów. – Tronic

+0

@Tronic: jak myślisz bitów? Matrix prawdopodobnie byłby pod względem wielkości matrycy prawdopodobnie ... – Skilldrick

+0

Społeczność Wiki? –

Odpowiedz

19

Patrz http://en.wikipedia.org/wiki/Computational_complexity_of_mathematical_operations


matrycy produktów matryc kwadratowych:

Istnieje także O (N 2,38) Coppersmith–Winograd algorithm ale nie sądzę, że to szeroko rozpowszechnione ze względu na ogromny ukryty stały.

Big Int mnożenie:

Istnieje również n dziennik n & middot; 2 Algorytm O (log * n) opublikowany w 2008 roku, ale był zbyt nowy, by być powszechnym.


Zazwyczaj metoda naiwna jest wystarczająco dobra dla normalnej wielkości wejścia.

+0

To ciekawe, jak szybsze jest O (N 2.38) niż O (N³). – psihodelia

+1

Niestety, odpowiedź na to pytanie brzmi "to zależy". Jak wspomniano w artykule wikipedia, algorytm nie jest powszechnie stosowany, ponieważ tylko w rzeczywistości powoduje zmniejszenie czasu wykonywania niepraktycznie ogromnych danych wejściowych. –

+1

W praktyce algorytm O (N^2.38) wcale nie jest szybszy, ponieważ szybkość jest większa niż złożoności algorytmicznej. – Pillsy

5

Operacje nie mają złożoności, działają algorytmy. Na przykład istnieją różne algorytmy pierwiastków kwadratowych i będą one miały różną złożoność.

+2

Mnożenie jest algorytmem między dwiema tablicami bitów. O złożoności O (n²), jeśli się nie mylę. – Tronic

+2

@Sililldrick: OP mówi o najczęściej używanych algorytmach, więc w pewnym sensie ta odpowiedź jest nieistotna. –

+0

@Moron: Myślę, że pytanie zostało nieco zmienione, ponieważ odpowiedziałem. – Skilldrick

5

Najprościej będzie traktować najprostsze operacje jako O (1), ponieważ zazwyczaj rozmiar wejściowy jest stały (tzn. 32- lub 64-bitowy).

W normalnych warunkach platforma wykona dokładnie tę samą operację dla mnożenia, pierwiastka kwadratowego, logarytmu itp. Niezależnie od "rozmiaru" danych wejściowych (tj. Int a = 0; int b = Int32.MaxValue są obie 32-bitowe liczby całkowite).

To staje się interesujące, gdy zaczniesz patrzeć na matryce lub reprezentować dowolnie precyzyjne liczby, ale ktoś już podłączył podsumowanie wikipedii, więc nie będę się w to zagłębiał.

Po prostu nie używaj Schönhage–Strassen do pomnażania "normalnych" małych liczb. To mnie rozpłacze. Tylko dlatego, że algorytm jest O (n ) nie znaczy, że jest złe - szczególnie gdy n jest prawie zawsze 2 lub 2 .

+0

To bardzo dobry punkt na operacjach na 32-bitowych wzorcach. – Skilldrick

+0

W praktyce masz rację co do prostych operacji. Jednakże, jako teoretyk, chcę powiedzieć, że nadal można mówić o złożoności pod względem liczby bitów w liczbie. Ten sam algorytm może być w porządku dla 32b, ale jest powolny dla 64b, lub kiedy ostatecznie osiągamy 1024b lub coś ... Znowu, realistycznie masz rację, ale wciąż jest to interesujące pytanie. –

+0

* Nods *, to absolutnie interesujące pytanie, gdy tylko wyjdziesz z bezpiecznego świata wejść o stałej długości. –

1

Pierwiastek kwadratowy i logarytm mogą być realizowane na różne sposoby, co znacznie wpływa na złożoność (ocenianą wymaganą precyzją).

Jeśli są zaimplementowane z tablicami odnośników (i pewną interpolacją), wymaganie pamięci naprawdę eksploduje, ponieważ wymagana jest większa precyzja, ale złożoność polega na sprawdzeniu wartości w tablicy i ewentualnym zastosowaniu interpolacji.

Bardziej popularne wydają się być realizowane przez ich definicje serii. Powtarzaj lub powtarzaj stwierdzenie przez kilka rund, aż osiągniesz wymaganą dokładność. Tutaj liczba rund może być bardzo wysoka, ponieważ potrzebna jest większa precyzja, a także na same obliczenia wpływa zwiększona precyzja.

+0

+1 Interesujące. Czy to oznacza, że ​​N staje się dokładnością? – Skilldrick

+0

@skilldrick można zdecydowanie zrobić to w ten sposób. Istnieją algorytmy, które są mierzone w rozmiarze ich WYJŚCIA zamiast ich wejścia. Mają nazwę, ale jest piątek, więc nie mogę się tym przejmować B-) –

0

Jest to rodzaj algorytmu Fouriera że robi całkowitą mnożenia jak również (Schonhage-Strassen)

myślałem, że nie było to wersja algorytmu Strassena że robi nieco lepsze niż normalne całkowitą mnożenia, ale teraz, kiedy o tym myślę, to kończy się być tym samym, co proste ...

Dodawanie i odejmowanie to właściwie tylko dodawanie i odejmowanie. Podział i pierwiastek kwadratowy są prawdopodobnie interesujące ...

RÓWNIEŻ: Zwróć uwagę, że do tej pory wszyscy mówili o Arytmetyce INTEGER. Gdy przejdziesz do floats/doubles, wszystkie zakłady są wyłączone. Następnie dostajesz się do świata numerical analysis, a to jest całe pole jego własnego ...

1

Spójrz na BigInteger, na liczbach całkowitych dowolnej długości. Wszystko ma teraz koszt pod względem wielkości wejścia, który jest liczbą bitów (zwykle O(log K) bitów dla numeru K). Będę używał N dla liczby bitów poniżej. Na przykład dodawanie i odejmowanie to teraz O(N). Mnożenie jest albo O(N^2) (naiwny) lub O(n (log n)^(2+epsilon) ) z FFT.

Inne algorytmy obejmują funkcję "zasilania", która przyjmuje mnożenie O(N). (z wyjątkiem tego, że teraz każde mnożenie ma koszt!)

Istnieją również dodatkowe komplikacje dla BigDecimals, który jest dziesiętnym odpowiednikiem długości, a poza niektórymi bardziej podstawowymi operacjami, niektóre rzeczy są również bardziej interesujące (zwłaszcza jeśli chcesz dowiedzieć się, ile chcesz precyzji). Możesz rzucić okiem na implementację Javy.

+0

Naiwna implementacja funkcji mocy wymaga multiplikacji O (n), ale inteligentne implementacje to O (log n): http://en.wikipedia.org/wiki/Exponentiation_by_squaring – Juliet

+0

Jak już wspomniałem, 'N' to liczba bitów. Zasilanie jest w rzeczywistości 'O (log K)' dla pewnej liczby 'K' chociaż. – Larry

0

Podział i pierwiastki kwadratowe dla ogromnej liczby bitów nie są dużo bardziej złożone niż mnożenie. W przypadku obu operacji zwykłą iterację Newtona można ułożyć w taki sposób, że iteracja Newtona ma jedynie multiplikacje. Ponieważ liczba poprawnych cyfr jest podwojona w każdym kroku, możemy po prostu podwajać dokładność obliczeń na każdym etapie.