Testowanie złożoności obliczeniowej 2 algorytmów w Pythonie

Testowanie złożoności obliczeniowej 2 algorytmów w Pythonie

Postanowiłam sprawdzić w praktyce, jak się mają teoretyczne wyliczenia złożoności obliczeniowej algorytmów do rzeczywistych wyników uzyskiwanych w kompilatorze.

Do testów wybrałam język Python oraz kompilator Eclipse.

Problem:

Znaleźć minimalny i maksymalny element w tablicy n-elementowej.

Można to zrobić na 2 sposoby:

1) przechodząc po kolei po każdym elemencie tablicy zadecydować, czy przypisać go do min lub max. Złożoność tego algorytmu to ok. 2n

2) porównywać ze sobą dwa kolejne elementy i zadecydować który przypisać do min a który do max. Złożoność tego algorytmu to ok. 3*n/2 = 1,5n

Jak wynika ze wstępnych założeń, algorytm drugi powinien być o ok. 25% szybszy niż pierwszy.

Zapis w Pythonie:

Algorytm 1:

   def algorytm1(tab):

        min = 0
        max = 0
        t1 = time.clock()

        for i in range(0,ilosc,1):
            if (tab[i] > max):
                max = tab[i]
            if (tab[i] < min):
                min = tab[i]
        t2 = time.clock()

        return t2-t1

Algorytm 2:

   def algorytm2(tab):

        min = 0
        max = 0
        t1 = time.clock()

        for i in range(0,ilosc,2):
            if(tab[i] > tab[i+1]):
                if (tab[i] > max):
                    max = tab[i]
                if (tab[i+1] < min):
                    min = tab[i+1]
            else:
                if (tab[i+1] > max):
                    max = tab[i+1]
                if (tab[i] < min):
                    min = tab[i]
        t2 = time.clock()

        return t2-t1

Obie funkcje zwracają różnicę czasu pomiędzy momentem swojego startu i zakończenia.

Tablice testową program tworzy z losowo wybranych liczb typu całkowitego z przedziału od 1 do 1000. Wielkość tablicy przekazywana jest jako parametr tej funkcji.

   def genTab(ilo):

        tablica = []

        for i in range(ilo):
            tablica.append(round(random.random() * 1000))

        return tablica
 

Program zwraca procentową różnicę czasu działania między algorytmem drugim a pierwszym. Jest to średnia z x prób (ostatnia pętla).

Wyniki zaprezentowane są na wykresie:

procentowy_wzrost_predkosci_algorytmu_drugiego_do_pierwszego_w_zaleznosci_od_wielkosci_tablicy_testowej

Jak widać, różnica w szybkości działania obu algorytmów jest tym bardziej widoczna, im większy jest rozmiar danych, (n-> nieskończoności).

Jeszcze wykres średniej procentowej wzrostu:

sredni_procentowy_wzrost_szybkosci_dzialania_alg_2_do_alg_1

A gdyby nieco zoptymalizować kod algorytmu numer 2?

Dopisałam w nim 2 linijki kodu

   zm1 = tab[i]
            zm2 = tab[i+1]

po to, aby nie odwoływać się za każdym razem do samej tablicy (która może być stosunkowo duża), zamiast tego zrobić to raz, na samym początku.

Wyniki są ciekawe:
wzrost_szybkosci_algorytmu_drugiego_po_optymalizacji

Dla dużych wartości n szybkość działania algorytmu drugiego względem pierwszego wzrosła z ok 20% do ok. 27,5% 🙂

Comments are closed, but trackbacks and pingbacks are open.