BigO

I computer verdenen bliver man nød til at undersøge hvor lang tid en algoritme tager til at løse et problem, fordi tager denne for lang tid, kan den ikke bruges i praksis.

 

Eksempel 1

 

Her har vi et array med 7 tal. Arrayet er ikke sorteret. Hvis vi har en algoritme som skal finde et bestemt tal, bliver vi nød til at undersøge hele arrayet i værste tilfælde (worst case). Her prøver vi at finde 4 i arrayet, og hvis vi har en loop som undersøger alle elementer og starter fra position 0, så skal vi lave 7 sammenligninger før vi finder 4 værdien. Hvis værdien ikke var med i arrayet, vil vi også hver gang skulle undersøge hele arrayet.

Arrayets længde er 7. Vi kalder denne mængde for n. Og vi skal undersøge alle n. Derfor bliver BigO til O(n).

 H

 

 

 

 

 

 

 

 

Eksempel 2

 

Nu er Arrayet sorteret. Vi kan nu lave en algoritme som går ind og søger på n/2, altså halvere arrayet. Og hvis værdien i arrayet er mindre end den vi søger så skal vi til højre, ellers skal vi til venstre. Og så halverer vi den resterende del af arrayet igen osv. Altså vi kan halvere arrayet for hver undersøgelse. Dette gælder også for et Binært søgetræ.

 

Hvis vi har 10 elementer i listen/træet og det tager f.eks. 4 operationer. Så tager

20 elementer 5 operationer og

40 elementer 6 opereation osv.

 

Hvergang vi fordobler n så kan vi indsætte flere og flere, men det koster kun én operation mere. Sagt på en anden måde: jo mere vi putter i arrayet/træet jo mere effektiv bliver algoritmen. Den bliver således bedre og bedre set i forhold til n.

 

Det giver os en O(log n).

 

H

 

 

 

 

 

 

 

Eksempel 3

 

Bobbel sort algoritmen er ret u-effektiv, men ret nem at forstå. Hvis du undersøger koden nedenfor, ser du at den har 6 elementer, n=6.

Og den bruger 30 operationer. Se udskrift.

 

Hvis du undersøger den nærmere ser du at den kører (n * n) – n eller (n * n – 1).

 

I BigO verdenen er man kun interesseret i de vigtige tendenser. Altså konstanter har ingen betydning.  

 

(n * n) – n. Her kan vi fjerne –n fordi n*n er en meget større tendens en –n. Tendensen for algoritmen ligger således i n*n = n2.

 

(n * n – 1). Er oplagt, fordi 1 er en konstant, så den fjerner vi bare og tilbage er n*n = n2.

 

Begge siger altså: O (n2).

 

 

 

Bubble Sort kode

using System;

using System.Collections.Generic;

using System.Text;

 

 

namespace sorteringAfObjekter

{

    class Program

    {

        static void Main(string[] args)

        {

            Sorter s = new Sorter();

        }

    }

    class Sorter

    {

        Bil[] biler = new Bil[6];

        public Sorter()

        {

            biler[0] = new Bil(6, "Karl");

            biler[1] = new Bil(5, "Peter");

            biler[2] = new Bil(4, "Jens");

            biler[3] = new Bil(3, "Allan");

            biler[4] = new Bil(2, "Hans");

            biler[5] = new Bil(1, "Ole");

 

            udskriv(biler);     

            viSorterer(biler);

            udskriv(biler);

         

        }

 

        public void viSorterer(Bil[] arr)

        {

            Console.WriteLine();

            Console.WriteLine("--------Bobbel Sort start--------------");

            Boolean found = false;

            int operations = 0;

            for (int i = 0; i < arr.Length - 1; i++)

            {

                operations++;

                if (arr[i].tal > arr[i + 1].tal)

                {

                    Bil tmp = arr[i];

                    arr[i] = arr[i + 1];

                    arr[i + 1] = tmp;

                    found = true;

                }

                if (i == arr.Length - 2 && found == true)

                {

                    found = false;

                    i = -1;

                }

 

            }

            Console.WriteLine(" Antal iterationer: " + operations);

            Console.WriteLine("--------Bobbel Sort slut--------------");

            Console.WriteLine();

        }

        public void udskriv(Bil[] biler)

        {

            Console.WriteLine("------Udskriv start------");

            for (int i = 0; i < biler.Length; i++)

            {

                Console.WriteLine(biler[i].tal + " " + biler[i].navn);

            }

            Console.WriteLine("------Udskriv slut------");

        }

    }

    class Bil

    {

        public int tal;

        public string navn;

        public Bil(int t, String n)

        {

            tal = t;

            navn = n;

        }

    }

}

UDSKRIFT

 

H

 

 

 

 

 

 

 

 

 

Fagudtryk(BigO)

Big(O) eksempler.

3 algoritmer som løser samme problem med forskellig effektivitet.

Algoritme A: O(n)
Algoritme B: O(n²)
Algortime C: O(1)

Vigtigt:Når vi bruger Big(O), tager vi kun den Største tendens i effektiviteten. Dvs. at 2n + 1 bliver til n. Fordi ved 2 * n, her har 2 tallet mindre betydning en n, og + 1 betyder mindre en n.

Triks: Hvis du skal lave et hurtigt skøn kan du bare kikke på hvor mange loops du har. A har en loop = n. B har 2 loops = n2, og C har ingen loop = 1. Men man skal passe på, fordi det ikke holder hver gang.

https://lh3.googleusercontent.com/DrW4q1bUR58hy0wUV3Ff5vspPRflTNqyAbkNivozlDw3ubWCNiwiZp79CKOfIOJ79G_hxOMmNhPNSRwzWmh3H4aaO8JZwUJw6UuxdKjxXbWL7hxU8Wgl*
https://lh6.googleusercontent.com/OQE45eqrT5UgR6rdAH56qG9JX8mJDz6AJ0CIC2wVIJa7gix0SIsu3LIaqhi95uiibIlaFrT_vygf46I4g5C1z-nVH-VZJqz03RX3PH8QoWDgMUsop6IS

Algoritme Effektivitet (Big O)

En algortime bruger både TID og PLADS (hugkommelse). Begge er selvfølgelig vigtige, men som udgangspunkt fokuseres primært på TID når man analyserer en algoritme.

I analysen tager man altid udgangspunkt i ANTAL elementer som algoritmen undersøger (n). Nu kan du undersøge hvor meget algoritmen relativt vokser når n vokser.

Den rigtige tid som en algoritme bruger er således IKKE interessant, fordi det afhænger i princippet lige så meget af den computer den kører på. Det er TENDENSEN man er interesseret i, og ikke den præcisse tid.

Normalt er vi også kun interesseret i Worst-case, men der findes også andre cases som Best-case, average-case.