Czasami łatwo jest określić złożoność czasową algorytmu, dokładnie go badając. Algorytmy z dwiema zagnieżdżonymi pętlami są oczywiście . Algorytmy zbadania wszystkich możliwych kombinacji grup dwie wartości są oczywiście . N 2 N.
Nie wiem jednak, jak „rozpoznać” algorytm o złożoności . Przykładem jest rekurencyjna implementacja scalania. Jakie są wspólne cechy algorytmów scalesort lub innych algorytmów , które dałyby mi wskazówkę, gdybym je analizował?
Jestem pewien, że istnieje więcej niż jeden sposób złożoności algorytmu , więc każda odpowiedź jest doceniana. BTW Szukam ogólnych cech i wskazówek, a nie rygorystycznych dowodów.
algorithm-analysis
time-complexity
intuition
Barry Fruitman
źródło
źródło
Odpowiedzi:
Twój archetypiczny jest algorytmem „ dziel i rządź” , który dzieli (i rekombinuje) pracę w czasie liniowym i powraca nad kawałkami. Sortowanie z sortowaniem działa w ten sposób: poświęć czas O ( n ) na podzielenie danych wejściowych na dwa mniej więcej równe kawałki, rekurencyjnie posortuj każdy kawałek i poświęć Θ ( n ) czas na połączenie dwóch posortowanych połówek.Θ ( n logn ) O ( n ) Θ ( n )
Intuicyjnie, kontynuując ideę dziel i zwyciężaj, każdy etap podziału zajmuje w sumie czas liniowy, ponieważ wzrost liczby kawałków do podziału dokładnie odpowiada zmniejszeniu wielkości kawałków, ponieważ czas dzielenia jest liniowy. Całkowity czas pracy jest iloczynem całkowitego kosztu etapu podziału pomnożonego przez liczbę etapów podziału. Ponieważ wielkość kawałków jest za każdym razem zmniejszana o połowę, istnieją etapy podziału , więc całkowity czas pracy wynosi n ⋅ log ( n ) . (Do stałej multiplikatywnej podstawa logarytmu nie ma znaczenia).log2)( n ) n ⋅ log( n )
Umieszczając go w równaniach (), jednym ze sposobów oszacowania czasu działania takiego algorytmu jest wyrażenie go rekurencyjnie: T ( n ) = 2 T ( n / 2 ) + Θ ( n ) . Oczywiste jest, że ten algorytm zajmuje więcej niż czas liniowy i możemy zobaczyć, o ile więcej, dzieląc przez n : T ( n )T.( n ) T.( n ) = 2 T.( n / 2 ) + Θ ( n ) n
Gdynpodwaja się,T(n)/nwzrasta o stałą wartość:T(n)/nwzrasta logarytmicznie, lub innymi słowy,T(n)=Θ(nlogn).
Jest to przykład bardziej ogólnego wzorca: twierdzenie główne . Dla każdego algorytm rekursywnego że dzieli dane wejściowe wielkości w a kawałki o rozmiarach n / b i ma czasową f ( n ) w celu wykonania podział i rekombinacji spełnia bieżącego czasu , T ( n ) = a ⋅ T ( n / b ) + f ( n ) . Prowadzi to do zamkniętej formy, która zależy od wartości i B oraz kształtun za n / b fa( n ) T.( n ) = a ⋅ T( n / b ) + f( n ) za b . Jeśli = b i f ( n ) = Θ ( n ) , stany Master twierdzenie, że T ( n ) = Θ ( n log n ) .fa a = b f(n)=Θ(n) T(n)=Θ(nlogn)
źródło
Dwie inne kategorie algorytmów, które zajmują czasu:Θ(nlogn)
Algorytmy, w których każdy element jest przetwarzany kolejno, a przetwarzanie każdego elementu zajmuje czas logarytmiczny (np. HeapSort lub wiele algorytmów obliczeniowej geometrii płaszczyzny).
Algorytmy, w których czas wykonywania jest zdominowany przez etap wstępnego przetwarzania sortowania. (Na przykład, w algorytmie Kruskala dla minimalnego drzewa opinającego, możemy posortować krawędzie według wagi jako pierwszy krok).
źródło
Inna kategoria: Algorytmy, w których dane wyjściowe mają rozmiar , a zatem czas pracy Θ ( n log n ) jest liniowy w wielkości wyjściowej .Θ(nlogn) Θ(nlogn)
Chociaż szczegóły takich algorytmów często wykorzystują techniki dziel i zwyciężaj, niekoniecznie muszą. Czas działania zasadniczo wynika z zadanego pytania, dlatego uważam, że warto wspomnieć o nim osobno.
Pojawia się to w strukturach danych opartych na rozszerzonym drzewie wyszukiwania binarnego, w którym każdy węzeł przechowuje strukturę danych o rozmiarze liniowym do przeszukiwania liści w poddrzewie tego węzła. Takie struktury danych często pojawiają się podczas wyszukiwania zakresu geometrycznego i często są oparte na schemacie rozkładu . Zobacz ankietę Agarwal .
źródło
źródło
Są to zazwyczaj algorytmy odmiany „dziel i rządź”, w których koszt podziału i łączenia subolutions nie jest „zbyt duży”. Przejrzyj to FAQ, aby zobaczyć, jakie rodzaje nawrotów powodują takie zachowanie.
źródło
Zazwyczaj algorytmy dzielenia i zdobywania zapewniają złożoność O (N log N).
źródło
Nie mogę podać konkretnego przykładu algorytmu wykorzystującego tę pętlę, ale często pojawia się podczas kodowania niestandardowych algorytmów.
źródło