Algoritmen & complexiteit: oefenvragen met uitleg

Gratis meerkeuzevragen over Algoritmen & complexiteit met hints en uitleg, op drie niveaus: kernbegrippen en feiten, begrippen toepassen, casussen en analyse.

Gratis oefenopgaveMakkelijk

Welke complexiteitsklasse groeit het snelst voor grote n?

Oefen Algoritmen & complexiteit gratisOefen nu Algoritmen & complexiteitElke dag 5 gratis opgaven. Geen creditcard nodig.

Wat je oefent

  1. Makkelijkkernbegrippen en feiten
  2. Gemiddeldbegrippen toepassen
  3. Moeilijkcasussen en analyse

Leer Algoritmen & complexiteit vanaf nul

1Wat complexiteit meet

Een algoritme is een eindige lijst van precieze stappen die een probleem oplost, zoals een lijst sorteren of een naam in een telefoonboek zoeken.

Twee algoritmen kunnen hetzelfde probleem oplossen maar heel verschillend veel tijd kosten. Complexiteit beschrijft hoe het werk groeit als de invoer groter wordt.

De grootte van de invoer heet n: het aantal items om te sorteren, de lengte van een lijst, het aantal knopen in een graaf.

Denk aan het zoeken van een naam in een telefoonboek van 1000 pagina’s. Elke pagina lezen kost maximaal 1000 stappen. Het boek in het midden openen en telkens halveren kost ongeveer 10 stappen.

Tijdcomplexiteit telt de stappen. Ruimtecomplexiteit telt het extra geheugen. Beide worden geschreven als functie van n.

Meestal kijk je naar het slechtste geval: het meeste werk over alle invoeren van grootte n. Soms wordt in plaats daarvan naar het gemiddelde of het beste geval gevraagd.

Zelftoets Een algoritme waarvan het werk groeit als n² doet er 1 seconde over voor n = 1000. Hoe lang duurt het ongeveer voor n = 2000?
  1. 1 seconde
  2. 2 seconden
  3. 4 seconden
  4. 8 seconden

Antwoord: 4 seconden. Een verdubbeling van n vermenigvuldigt n² met 2² = 4, dus de tijd gaat van ongeveer 1 naar ongeveer 4 seconden. 2 seconden zou het antwoord zijn bij lineaire groei, en 8 bij n³.

2Big O en de groeiklassen

De Big O-notatie houdt alleen over wat telt voor grote n. Je laat constante factoren weg en houdt alleen de snelst groeiende term.

3n² + 5n + 2 ⇒ O(n²)

Voor n = 1000 is de n²-term 3 000 000, terwijl 5n maar 5000 is. De kleinere termen veranderen het totaal nauwelijks.

Deze klassen komen steeds terug, van langzaamste naar snelste groei:

  • O(1), constant: een array-element lezen via zijn index.
  • O(log n), logaritmisch: binair zoeken, dat het probleem in elke stap halveert.
  • O(n), lineair: één keer langs alle items, zoals het zoeken van de grootste waarde.
  • O(n log n): goede sorteeralgoritmen zoals merge sort.
  • O(n²), kwadratisch: twee geneste lussen over de items, zoals bubble sort.
  • O(2ⁿ), exponentieel: elke deelverzameling proberen. Het wordt snel onbruikbaar.
ntlog nnn log nn²2ⁿ

Big O is een bovengrens: het werk groeit hoogstens zo snel. Ω (Big Omega) is een ondergrens en Θ (Theta) is een scherpe grens, zowel boven als onder.

Het grondtal van een logaritme doet er in Big O niet toe, omdat logaritmen met verschillende grondtallen alleen door een constante factor verschillen.

Zelftoets Wat is de Big O van 4n + 2n² + 100?
  1. O(100)
  2. O(2n²)
  3. O(n)
  4. O(n²)

Antwoord: O(n²). Voor grote n domineert de n²-term en wordt de constante factor 2 weggelaten. O(n) houdt de verkeerde term, en O(2n²) vergeet de constante weg te laten.

3Zoeken, sorteren en recursie

Een paar algoritmen komen in bijna elke cursus voor. Leer hun complexiteiten als feiten.

  • Lineair zoeken controleert items één voor één: O(n). Binair zoeken heeft een gesorteerde array nodig en halveert het bereik in elke stap: O(log n).
  • Bubble sort, insertion sort en selection sort vergelijken en verwisselen items in geneste lussen: O(n²). Insertion sort is O(n) op een array die al gesorteerd is.
  • Merge sort splitst de array in helften, sorteert ze en voegt ze samen: O(n log n) in elk geval, met O(n) extra geheugen.
  • Quicksort splitst rond een pivot: O(n log n) gemiddeld, maar O(n²) in het slechtste geval, bijvoorbeeld een gesorteerde array met het eerste element als pivot.
  • Geen sortering die alleen items vergelijkt, kan in het slechtste geval beter zijn dan Ω(n log n). Counting sort is sneller omdat het niet vergelijkt.

Een recursieve functie roept zichzelf aan op een kleinere invoer totdat hij een basisgeval bereikt dat hij direct beantwoordt. Zijn rekentijd wordt geschreven als een recurrente betrekking:

  • T(n) = T(n/2) + O(1) geeft O(log n), zoals binair zoeken.
  • T(n) = 2T(n/2) + O(n) geeft O(n log n), zoals merge sort.
  • T(n) = T(n − 1) + O(n) geeft O(n²).
  • T(n) = 2T(n − 1) + O(1) geeft O(2ⁿ).

Drie ontwerpideeën zijn het kennen waard. Verdeel en heers splitst, lost op en combineert. Greedy kiest in elke stap de lokaal beste keuze. Dynamisch programmeren slaat de antwoorden op van overlappende deelproblemen, zodat ze maar één keer worden berekend.

Zelftoets Wat is de tijdcomplexiteit van quicksort in het slechtste geval?
  1. O(log n)
  2. O(n log n)
  3. O(n)
  4. O(n²)

Antwoord: O(n²). Bij slechte pivots laat elke splitsing n − 1 items aan één kant over, wat O(n²) geeft. O(n log n) is het gemiddelde geval, en het slechtste geval van merge sort.

4De methode stap voor stap

Zo vind je de tijdcomplexiteit van een stuk code:

  1. Bepaal wat n is: de grootte van de invoer.
  2. Tel hoe vaak elke lus draait. Een lus die elke keer 1 optelt, draait ongeveer n keer. Een lus die verdubbelt of halveert, draait ongeveer log₂ n keer.
  3. Lussen binnen elkaar vermenigvuldig je. Lussen na elkaar tel je op.
  4. Schrijf bij een recursieve functie de recurrente betrekking op: hoeveel aanroepen, op welke grootte, plus het werk per aanroep.
  5. Houd de snelst groeiende term en laat de constanten weg.
  6. Controleer met een klein getal, bijvoorbeeld n = 8 of n = 1024.

Noem bij een theorievraag eerst het algoritme of idee dat wordt beschreven, en haal dan zijn complexiteit en voorwaarden op (gesorteerde invoer, niet-negatieve gewichten, overlappende deelproblemen).

5Een uitgewerkt voorbeeld

Volg elke stap. Probeer de volgende stap te voorspellen voordat je hem opent.

Uitgewerkt voorbeeld

Wat is de tijdcomplexiteit van deze code? for i = 1 to n: (j = 1; while j < n: j = j × 2)

1

Noem de invoergrootte

n is het getal waartot de lussen lopen.

2

Tel de buitenste lus

i loopt van 1 tot n in stappen van 1, dus de buitenste lus draait n keer.

3

Tel de binnenste lus

j neemt de waarden 1, 2, 4, 8, … aan en stopt als het n bereikt. Na k rondes is j = 2k, dus de lus stopt na ongeveer log₂ n rondes.

4

Combineer de lussen

De binnenste lus zit in de buitenste lus, dus de aantallen vermenigvuldigen.

n · log₂ n ⇒ O(n log n)
5

Controleer met een getal

Voor n = 1024 draait de binnenste lus log₂ 1024 = 10 keer, dus de body draait 1024 · 10 = 10 240 keer. Dat is veel minder dan n² = 1 048 576.

Antwoord

O(n log n)

6Veelgemaakte fouten

  • Lussen vermenigvuldigen die na elkaar draaien. n + n = 2n is nog steeds O(n).
  • Constanten houden, zoals in O(2n) of O(n/2). Beide zijn O(n).
  • Een verdubbelingslus tellen als n rondes. Hij draait ongeveer log₂ n keer.
  • Binair zoeken gebruiken op ongesorteerde gegevens, of op een gelinkte lijst waar het midden niet in één stap bereikt kan worden.
  • Het gemiddelde geval van quicksort geven terwijl naar het slechtste geval wordt gevraagd.
  • Denken dat grote O “precies” betekent. O(n²) is een bovengrens; Θ(n²) is de exacte groei.
Zelftoets Een functie voert een lus van n iteraties uit en daarna, los daarvan, nog een lus van n iteraties. Wat is de tijdcomplexiteit?
  1. O(2n)
  2. O(log n)
  3. O(n)
  4. O(n²)

Antwoord: O(n). Lussen die na elkaar komen, tel je op: n + n = 2n, en de constante laat je weg, dus O(n). O(n²) zou alleen juist zijn als de ene lus binnen de andere zat.

7Hoe tentamenvragen eruitzien

  • Makkelijk: kernbegrippen en feiten. De complexiteit van binair zoeken, merge sort of toegang tot een array, de betekenis van O, Ω en Θ, wat recursie is.
  • Gemiddeld: concepten toepassen. De complexiteit van een stuk code, een recurrente betrekking oplossen, hoe de tijd verandert als n verdubbelt, welk algoritme bij een taak past.
  • Moeilijk: gevallen en analyse. De hoofdstelling (master theorem), slechtste gevallen van quicksort, greedy versus dynamisch programmeren, en de klassen P, NP en NP-volledig.

P bevat de problemen die in polynomiale tijd op te lossen zijn. NP bevat de problemen waarvan de oplossingen in polynomiale tijd gecontroleerd kunnen worden. Elk probleem in P zit in NP; of P = NP is nog onbekend.

Leer het stap voor stap in de appLeer het stap voor stap in de app

Voorbeeldvragen

Voorbeeld 1Makkelijk

Welke notatie beschrijft een bovengrens voor de groei?

  1. AGrote Omega (Big Omega)
  2. BKleine omega (little omega)
  3. CGrote O (Big O)
  4. DGrote Theta (Big Theta)
Hints tonen
  1. "Hoogstens".
  2. Twee foute antwoorden zijn nu doorgestreept. Een van de twee overgebleven antwoorden is goed.
Toon het antwoord en de uitleg

Waarom dit het antwoord is

O geeft een bovengrens, Ω een ondergrens en Θ een strakke grens.

Antwoord

C · Grote O (Big O)
Voorbeeld 2Gemiddeld

In een gesorteerde array zoek je twee elementen die samen een doelwaarde opleveren door vanaf elk uiteinde een pointer naar binnen te bewegen. Wat is de tijdcomplexiteit?

  1. AO(n)
  2. BO(n log n)
  3. CO(n²)
  4. DO(log n)
Hints tonen
  1. Elke stap verplaatst één pointer één positie.
  2. Twee foute antwoorden zijn nu doorgestreept. Een van de twee overgebleven antwoorden is goed.
Toon het antwoord en de uitleg

Waarom dit het antwoord is

Is de som te klein, dan gaat de linkerpointer naar rechts; is ze te groot, dan gaat de rechterpointer naar links. Er zijn dus hoogstens n stappen.

Antwoord

A · O(n)
Voorbeeld 3Moeilijk

Het algoritme van Strassen vermenigvuldigt matrices met 7 in plaats van 8 recursieve vermenigvuldigingen van blokken van halve grootte. Wat is de looptijd?

  1. AΘ(n² log n)
  2. BΘ(n2)
  3. CΘ(n³)
  4. DΘ(nlog₂ 7), ongeveer n2,81
Hints tonen
  1. De recurrente betrekking is T(n) = 7T(n/2) + O(n²).
  2. Twee foute antwoorden zijn nu doorgestreept. Een van de twee overgebleven antwoorden is goed.
Toon het antwoord en de uitleg

Waarom dit het antwoord is

Met a = 7 en b = 2 domineert nlog₂ 7 het O(n²)-optelwerk, wat ongeveer n2,81 geeft.

Antwoord

D · Θ(nlog₂ 7), ongeveer n2,81

Vragen en antwoorden

Algoritmen & complexiteit: wat is het?

Een algoritme is een eindige lijst van precieze stappen die een probleem oplost, zoals een lijst sorteren of een naam in een telefoonboek zoeken.

Twee algoritmen kunnen hetzelfde probleem oplossen maar heel verschillend veel tijd kosten. Complexiteit beschrijft hoe het werk groeit als de invoer groter wordt.

Algoritmen & complexiteit: hoe leer je het stap voor stap?
  1. Wat complexiteit meet
  2. Big O en de groeiklassen
  3. Zoeken, sorteren en recursie
  4. De methode stap voor stap
  5. Een uitgewerkt voorbeeld
  6. Veelgemaakte fouten
  7. Hoe tentamenvragen eruitzien
Algoritmen & complexiteit: wat oefen je?
  • Makkelijk: kernbegrippen en feiten
  • Gemiddeld: begrippen toepassen
  • Moeilijk: casussen en analyse

Elke vraag heeft vier antwoordopties en maar één is juist. Kom je vast te zitten? Open eerst een kleine hint en de volledige uitleg pas als je die nodig hebt.

Zo werkt het oefenen

  • Elke vraag heeft vier antwoordopties en maar één is juist.
  • Kom je vast te zitten? Open eerst een kleine hint en de volledige uitleg pas als je die nodig hebt.
  • Je voortgang, fouten en bewaarde opgaven blijven bewaard, zodat je vóór het tentamen kunt herhalen.

Onderwerpen ervoor en erna

Daarna verder met

Vakken met dit onderwerp

Meer onderwerpen in Informatica

Printbaar werkblad

Oefen Algoritmen & complexiteit gratisOefen nu Algoritmen & complexiteitElke dag 5 gratis opgaven. Geen creditcard nodig.