Oppgavesett 2
Fra Hiofwiki
Innhold |
Løsningsforslag (Gruppe 3)
Linker til filer:
FragmentTester.java
Modul02.pdf
Oppgave 1
- Hvilken orden er det på de følgende funksjonene? (Oppgave 1.8 s. 27 i læreboka.)
- A
- 10n2 + 100n + 1000 er av orden O(N2)
- B
- 10n3 - 7 er av orden O(N3)
- C
- 2n + 100n3 er av orden O(N3)
- D
- n2 log n er av orden O(N2).
Oppgave 2
- Arranger funksjonene fra oppgave 1 i stigende rekkefølge etter effektivitet (raskeste arbeidstid) når N = 10 og N = 1000000 (Oppgave 1.9 s. 27 i læreboka.)
- N = 10
- O(N2)
- O(N3)
- O(N log N)
- N = 1000000
- O(N log N)
- O(N2)
- O(N3)
Valg av algoritme er mindre viktig ved små verdier av N, pga. liten forskjell mellom den raskeste og den tregeste algoritmen.
Ved store verdier av N er det mye mer viktig å velge riktig algoritme siden forskjellene kan her være fra noen timer (kanskje noen dager) med raskeste algoritme til flere år (mot uendelig)
med den tregeste algoritmen.
Litt mer informasjon om algoritmevalg Coding Horror
Oppgave 3
- En algoritme tar 0.5 ms når størrelsen på datamengden N = 100. Hvor stort problem kan løses på 1 minutt når vi antar at lavereordensledd er neglisjerbare og arbeidsmengden er:
- Lineær
- Kvadratisk
- Kubisk
- Lineær
1 minutt = 60 sekunder = 60 000 millisekunder
Konstantleddet C: T(N) = C × N T(100) = 0.5ms C × N = 0.5ms 100 × C = 0.5ms C = 0.5/100 = 0.005
Arbeidsmengde: C × N = 60000 N = 60000/C = 60000/0.005 = 12000000 = 12 × 106
- Kvadratisk
Konstantleddet C: T(N) = C × N2 T(100) = 0.5ms C × N2 = 0.5ms 1002 × C = 0.5ms C = 0.5/1002 = 0.00005
Arbeidsmengde: C × N2 = 60000 N2 = 60000/C = √60000/C = 20000 × √3 ≈ 34641
- Kvadratisk
Konstantleddet C: T(N) = C × N3 T(100) = 0.5ms C × N3 = 0.5ms 1003 × C = 0.5ms C = 0.5/1003 = 0.0000005
Arbeidsmengde: C × N3 = 60000 N3 = 60000/C = 3√60000/0.0000005 = 20000 × 3√15 ≈ 4932
Oppgave 4
- For hvert programfragment nedenfor skal du:
- Angi arbeidsmengde i O-notasjon
- Implementer koden og kjør for forskjellige verdier av N
- Sammenlikne analyse med observert kjøretid
1. O-notasjon for hvert fragment
- Fragment 1:
for (int i=0; i < n; i++)
sum++;
O-notasjon: O(N) [Lineær]
- Fragment 2:
for (int i=0; i < n; i += 2) sum++;
O-notasjon: O(N) [Lineær]
- Fragment 3:
for (int i=0; i< n; i++)
for (int j=0; j < n; j++)
sum++;
O-notasjon: O(N2) [Kvadratisk]
- Fragment 4:
for (int i=0; i< n; i++) sum++; for (int j=0; j< n; j++) sum++;
O-notasjon: O(N) [Lineær]
- Fragment 5:
for (int i=0; i< n; i++)
for (int j=0; j<n*n; j++)
sum++;
O-notasjon: O(N3) [Kubisk]
- Fragment 6:
for (int i=0; i< n; i++)
for (int j = 0; j < i; j++)
sum++;
O-notasjon: O(N2) [Kvardratisk]
- Fragment 7:
for (int i=0; i< n; i++)
for (int j=0; j< n*n; j++)
for (int k=0; k<j; k++)
sum++;
O-notasjon: O(N5) [Høyere orden]
- Fragment 8:
for (int i=1; i< n; i=i*2) sum++;
O-notasjon: O(log N) [Logaritmisk]
2. Implementert java kode:
// ORDER: O(N) - Linear
// Starting the clock
start = System.currentTimeMillis();
// Sets a value to the variable n
n = 1000000;
// Implemented fragment 1
for(int i=0; i < n; i++){
sum++;
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Denne gjennomkjøringen med lineære orden av N ble kjørt med N lik 1000000, 10000000, 100000000, 1000000000.
// ORDER O(N^2) - Quadratic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 1000;
// Implemented fragment 3
for(int i=0; i < n; i++){
for(int j=0; j < n; j++){
sum++;
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Denne gjennomkjøringen med kvadratisk orden av N ble kjørt med N lik 1000, 10000, 50000, 100000.
// ORDER O(N^3) - Cubic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 100;
// Implemented fragment 5
for(int i=0; i < n; i++){
for(int j=0; j < n*n; j++){
sum++;
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Denne gjennomkjøringen med kubisk orden av N ble kjørt med N lik 100, 500, 1000, 2000.
//ORDER O(N^5) - Higher order
start = System.currentTimeMillis();
// Sets a value to the var n
n = 10;
// Implemented fragment 7
for(int i=0; i < n; i++){
for(int j=0; j < n*n; j++){
for(int k=0; k < j; k++){
sum++;
}
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Denne gjennomkjøringen med høyere orden av N ble kjørt med N lik 10, 15, 100, 115.
//ORDER O(log N) - Logarithmic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 10000000;
// Implemented fragment 8
for(int i=1; i < n; i=i*2){
sum++;
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Denne gjennomkjøringen med logaritmisk orden av N ble kjørt med N lik 10000000, 100000000, 1000000000.
3. Sammenlikne analyse med observert kjøretid
Fragment 1:
Antall operasjoner Tid 1000000 O ms 10000000 47 ms 100000000 375 ms 1000000000 3782 ms
O-notasjonen: O(N) [Lineær]
Av listen over kjøretiden ser en at de øker lineær, og dette stemmer overens med O-notasjonen.
Fragment 3:
Antall operasjoner Tid 1000 O ms 10000 375 ms 50000 9453 ms 100000 37703 ms
O-notasjonen: O(N2) [Kvadratisk]
Av listen over kjøretiden ser en at de øker kvadratisk, og dette stemmer overens med O-notasjonen.
Fragment 5:
Antall operasjoner Tid 100 O ms 500 532 ms 1000 4328 ms 2000 38906 ms
O-notasjonen: O(N3) [Kubisk]
Av listen over kjøretiden ser en at de øker kubisk (realtivt hurtig økning), og dette stemmer overens med O-notasjonen.
Fragment 7:
Antall operasjoner Tid 10 O ms 50 500 ms 100 16125 ms 115 32531 ms
O-notasjonen: O(N5) [Høyere orden]
Av listen over kjøretiden ser en at de øker meget hurtig, og dette stemmer overens med O-notasjonen.
Fragment 8:
Antall operasjoner Tid 10000000 O ms 100000000 0 ms 1000000000 0 ms
O-notasjonen: O(log N) [Logaritmisk]
Her er kjøretiden så ekstrem rask at ved bruk av vanlig int verdier finner den en kjøretid lik 0 ms.
Løsningsforslag (Gruppe N)
Oppgave 1
- A
- 10n2 + 100n + 1000 =>O(N2)
- B
- 10n3 - 7 => O(N3)
- C
- 2n + 100n3 => O(N3)
- D
- n2 log n => O(N2).
Oppgave 2
- N = 10
- O(N2)
- O(N3)
- O(N log N)
- N = 1000000
- O(N log N)
- O(N2)
- O(N3)
Ser her at valget av algoritme ikke er viktig for kjøretiden ved liten N med den maskinkraft som er tilgjengelig i dag. Ved store verdier blir forskjellene større, da det setter et krav til valget av algoritme.
Oppgave 3
- Lineær
1 minutt = 60 000 ms
Konstantleddet C: T(N) = C × N T(100) = 0.5ms C × N = 0.5ms 100 × C = 0.5ms C = 0.5/100 = 0.005
Arbeidsmengde: C × N = 60000 N = 60000/C = 60000/0.005 = 12000000 = 12 × 106
- Kvadratisk
Konstantleddet C: T(N) = C × N2 T(100) = 0.5ms C × N2 = 0.5ms 1002 × C = 0.5ms C = 0.5/1002 = 0.00005
Arbeidsmengde: C × N2 = 60000 N2 = 60000/C = √60000/C = 20000 × √3 ≈ 34641
- Kvadratisk
Konstantleddet C: T(N) = C × N3 T(100) = 0.5ms C × N3 = 0.5ms 1003 × C = 0.5ms C = 0.5/1003 = 0.0000005
Arbeidsmengde: C × N3 = 60000 N3 = 60000/C = 3√60000/0.0000005 = 20000 × 3√15 ≈ 4932
Oppgave 4
1. O-notasjon for hvert fragment
- Fragment 1:
for (int i=0; i<n; i++)
sum++;
O-notasjon: O(N) [Lineær]
- Fragment 2:
for (int x=0; x<n; x+=2) sum++;
O-notasjon: O(N) [Lineær]
- Fragment 3:
for (int i=0; i<n; i++)
for (int j=0; j< n; j++)
sum++;
O-notasjon: O(N2) [Kvadratisk]
- Fragment 4:
for (int x=0; x<n; x++) sum++; for (int y=0; y<n; y++) sum++;
O-notasjon: O(N) [Lineær]
- Fragment 5:
for (int k=0; k< n; k++)
for (int l=0; l<n*n; l++)
sum++;
O-notasjon: O(N3) [Kubisk]
- Fragment 6:
for (int i=0; i< n; i++)
for (int j = 0; j < i; j++)
sum++;
O-notasjon: O(N2) [Kvadratisk]
- Fragment 7:
for (int i=0; i<n; i++)
for (int j=0; j<n*n; j++)
for (int k=0; k<j; k++)
sum++;
O-notasjon: O(N5) [Orden høyere enn kubisk!]
- Fragment 8:
for (int i=1; i< n; i=i*2) sum++;
O-notasjon: O(log N) [Logaritmisk]
2. Implementert java kode:
// ORDER: O(N) - Linear
// Starting the clock
start = System.currentTimeMillis();
// Sets a value to the variable n
n = 1000000; // 1.000.000
// n = 10000000; // n = 100000000; // n = 1000000000;
// Implemented fragment 1
for(int i=0; i<n; i++){
sum++;
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Lineære orden av N kjørt med N = 1000000, 10000000, 100000000, 1000000000.
// ORDER O(N^2) - Quadratic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 1000;
// n = 10000; // n = 50000; // n = 100000;
// Implemented fragment 3
for(int j=0; j<n; j++){
for(int k=0; k<n; k++){
sum++;
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Kvadratisk orden av N kjørt med N = 1000, 10000, 50000, 100000.
// ORDER O(N^3) - Cubic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 100;
// n = 500; // n = 1000; // n = 2000;
// Implemented fragment 5
for(int l=0; l<n; l++){
for(int m=0; m<n*n; m++){
sum++;
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Kubisk orden av N kjørt med N = 100, 500, 1000, 2000.
//ORDER O(N^5) - Higher order
start = System.currentTimeMillis();
// Sets a value to the var n
n = 10;
// n = 15; // n = 100; // n = 115;
// Implemented fragment 7
for(int i=0; i < n; i++){
for(int j=0; j < n*n; j++){
for(int k=0; k < j; k++){
sum++;
}
}
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Orden høyere enn kubisk av N kjørt med N = 10, 15, 100, 115.
//ORDER O(log N) - Logarithmic
start = System.currentTimeMillis();
// Sets a value to the var n
n = 10000000;
// n = 100000000; // n = 1000000000;
// Implemented fragment 8
for(int i=1; i < n; i=i*2){
sum++;
}
stop = System.currentTimeMillis();
System.out.println("| N: " + n + " | Tid: " + (stop - start) + " millisekunder ");
Logaritmisk orden av N kjørt med N = 10000000, 100000000, 1000000000.
3. Sammenlikne analyse med observert kjøretid
Fragment 1:
Antall operasjoner Tid 1000000 O ms 10000000 55 ms 100000000 413 ms 1000000000 5001 ms
O-notasjonen: O(N) [Lineær]
Lineær økning stemmer med O(N).
Fragment 3:
Antall operasjoner Tid 1000 O ms 10000 402 ms 50000 8992 ms 100000 39644 ms
O-notasjonen: O(N2) [Kvadratisk]
Kvadratisk økning stemmer med O(N2.
Fragment 5:
Antall operasjoner Tid 100 O ms 500 547 ms 1000 4447 ms 2000 41109 ms
O-notasjonen: O(N3) [Kubisk]
Kubisk økning stemmer med O(N3!
Fragment 7:
Antall operasjoner Tid 10 O ms 50 499 ms 100 18222 ms 115 33954 ms
O-notasjonen: O(N5) [Orden høyere enn kubisk]
En høyere orden stemmer her, veldig rask økning!
Fragment 8:
Antall operasjoner Tid 10000000 O ms 100000000 0 ms 1000000000 0 ms
O-notasjonen: O(log N) [Logaritmisk]
Kjedelig, burde brukt større verdier for å se om man fikk en innvirkning på log N.
