1 Algoritmik ved Keld Helsgaun. 2 Plan Algoritmebegrebet et simpelt eksempel Et eksempel på algoritmedesign.

Slides:



Advertisements
Lignende præsentationer
At Dividere.
Advertisements

At Dividere Decimaltal.
Funktioner Grundbegreber.
1 Problemkompleksitet 2 Problemers kompleksitet En ineffektiv algoritme: køretiden vokser eksponentielt med input- størrelsen Et problem, der ikke kan.
Trivselsundersøgelse og ledelsesevaluering
1 Rekursion og algoritmedesign. 2 Rekursion Rekursiv definition af X: X defineres i termer af sig selv. Rekursion er nyttig, når en generel version af.
Symbolsk maskinsprog.
1 Går fra at vil maksimere dækning til at minimere omkostning Det kender vi fra den anden bog Omkostningen er afstanden gange antal enheder der skal transporteres.
GP10, Martin Lillholm 1 Grundlæggende Programmering (GP) Efterår 2005 Forelæsning 10 Slides ligger på nettet. Du er velkommen til at printe dem nu. Vi.
Økonometri 1: Specifikation og dataproblemer1 Økonometri 1 Specifikation, og dataproblemer 4. november 2005.
Signalbehandling og matematik (Tidsdiskrete signaler og systemer)
Validering af data (Access, del 7)
Datastruktur & Algoritmik1 Datastruktur & Algoritmik 99 Kim Guldstrand Larsen.
FEN Diskret matematik/Seminar 3 - proofs 1 Beviser Et bevis er en argumentation, som overbeviser om, at en påstand er sand, påstanden kaldes.
Begreber og Redskaber 8. Plan for idag Sortering fortsat Comparable Søgning –Lineær søgning –Binær søgning.
Datastrukturer og algoritmer
Økonometri 1: Dummy variable
1 Bevisteknikker. 2 Bevisteknikker (relevant både ved design og verifikation) Teorem: Der findes uendeligt mange primtal Bevis: Antag at der findes et.
LINEÆR FUNKTIONER MATEMATIK A.
1 UNION-FIND. 2 inddata: en følge af heltalspar (p, q); betydning: p er “forbundet med” q uddata: intet, hvis p og q er forbundet, ellers (p, q) Eksempel.
GP 10, 7/ Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/ kl. 9:15 – 12:00.
Kvalitet i almindelighed og i relation til softwareudvikling.
MM4 Algoritmiske grundprincipper. MM1 Lister, stakke og køer. MM2 Hash-tabeller og Træer. MM3 Sortering.MM4 Søgning.MM5.
Induktion og rekursion
1 Logaritmer Logaritmer optr æ der hyppigt i forbindelse med algoritmeanalyse. Definition: For ethvert B > 0 og N > 0 g æ lder, at log B N = X, hvis B.
FEN Rekursion og induktion1 Induktion og (især) rekursion Mange begreber defineres ud fra en basis og så en gentagen anvendelse af et antal regler.
1 Algoritme til at løse knude P-center problemet Algoritmen brugte set covering problemet Virker derfor kun til knude problemer Vi vil alligevel bruge.
Økonometri 1: Specifikation og dataproblemer1 Økonometri 1 Specifikation, og dataproblemer 7. april 2003.
1 Datalogi C Datastrukturer og algoritmer ved Keld Helsgaun.
FEN Prædikater/Seminar 11 Prædikatslogik eller Kvantificerede udtryk Prædikater udvider propositionslogikken på to måder: –Vi tillader variable.
Globaliseringsredegørelsen 24.mar. 14 Figurer fra Danmark tiltrækker for få udenlandske investeringer i Sådan ligger landet
1 Sortering I elementære metoder. 2 Plan Terminologi Elementære metoder til sortering -sortering ved udvælgelse -sortering ved indsættelse -Shellsort.
Anvendelser I Leg og spil.
Hvordan kan man læse dette regnestykke? -7 – 3
Økonometri 1: F121 Økonometri 1 Heteroskedasticitet 27. oktober 2006.
1 Vi ser nu på en general graf Men antager at alle afstande er heltallige (Det er ikke så restriktivt) Algoritmen leder efter den mindst mulige dækningsdistance.
1 USB Gennemgang af installering af USB driver til ICT. Er fortaget på Windows XP.
Delprøve i kurset ”Calculus og indledende lineær algebra” 29. oktober 2014 Delprøve i M2CAL2 29. oktober A. B. A. 1x1 + 1x4 + 1x(-1) = 4 B. 1x4 =
Delprøve (reduceret) i kurset ”Calculus og indledende lineær algebra” den 7. maj 2014 Delprøve i M2CAL2, Betragt matricen til højre. Hvilket.
1 Algoritmik ved Keld Helsgaun. 2 Plan Hvad er algoritmik? Et eksempel Kursusbeskrivelse formål, indhold og form.
GP 11, 14/ Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/ kl. 9:15 – 12:00.
W1b1 PC baseret analyse og simulering. w1b2 Definition Digital Elektronisk beregningsmaskine, der har intern hukommelse til lagring af program og mellem-regninger.
1 PC baseret dataanalyse og simulering Week2 A. 2 SAS input/output filer Inddata -textfil - SAS-program -textfil- SAS datasæt SAS system SAS listing -print.
1 Design, analyse og verifikation. 2 Algoritmebegrebet Design Bevisteknikker Design ved hjælp at matematisk induktion Analyse O-notation Logaritmer Binær.
Fundamentale datastrukturer
FEN KbP/seminar 1: Specifikationer/Notationen Q 1 Kontraktbaseret programmering: Seminar 1 Om specifikationer Algoritmenotationen Q.
Design, verifikation og analyse
1 Design, analyse og verifikation. 2 Design Bevisteknikker Design ved hjælp at matematisk induktion Analyse O-notation Logaritmer Binær søgning Verifikation.
Opslagsfelter (Access, del 6). RHS – Informationsteknologi – Udgangspunkt Vi er ofte i den situation, at valg af en type for et felt ikke begrænser.
FEN IntroJava AAU1 Loops og algoritmer Sweep – for-loop Søgning – while-loop.
1 Sortering. 2 Sortering ved fletning (merge-sort) 7 2 | 9 4  | 2  2 79 | 4   72  29  94  4.
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper : arrays, stakke, køer,
DIEB4.1 Kursusgang 4 Oversigt: Sidste kursusgang Opgaver Aktivitet 2: Generer design (fortsat) Design af interaktionselementer.
Økonometri 1: Specifikation og dataproblemer1 Økonometri 1 Specifikation, og dataproblemer 9. november 2004.
Kapitel 5 Lineære DB-modeller
Økonometri 1: Specifikation og dataproblemer1 Økonometri 1 Specifikation og dataproblemer 2. november 2004.
Økonometri 1: F151 Økonometri 1 Specifikation og dataproblemer 10. november 2006.
Grundlæggende programmering Forår 2002
DAIMIIntroducerende objektorienteret programmering4B.1 Typer og tilstand i Java Typer, tilstand, erklæring, variable, primitive datatyper, reference- og.
DAIMIIntroducerende objektorienteret programmering4B.1 Grundlæggende og Reference Typer i Java Typer, tilstand, erklæring, reference- og værdi semantik,
I o p o DAIMI, AU, December 1999Introducerende objektorienteret programmering14A.1 Del, løs og kombinér.
I o p o DAIMI, AU, November 1999Introducerende objektorienteret programmering9D.1 Del, løs og kombinér.
 Michael E. Caspersen, 2000 Introducerende objektorienteret programmering4A.1 Sweep-algoritmer Programmering med invarianter og uden kaniner.
Del, løs og kombinér Et algoritmemønster.
Præsentationens transcript:

1 Algoritmik ved Keld Helsgaun

2 Plan Algoritmebegrebet et simpelt eksempel Et eksempel på algoritmedesign

3 Algoritmebegrebet En algoritme er en metode til at løse et problem Bemærk. Det er ikke et krav, at en algoritme skal kunne udføres på en datamat! Dette kursus omhandler dog mest algoritmer af denne type. Inddata Uddata Algoritme Foreløbig definition:

4 Databegrebet Data: En formaliseret repræsentation af kendsgerninger eller forestillinger på en sådan form, at den kan kommunikeres eller omformes ved en eller anden proces. Datalogi: Læren om data, deres væsen og brug. Information: Det betydningsindhold, et menneske tillægger data ud fra en vedtagen konvention.

5 Hvad forstås ved en “god” algoritme? (1) En algoritme, der løser problemet korrekt (2) En algoritme, der er (tilstrækkelig) hurtig (3) En algoritme, der kræver et (tilstrækkeligt) lille lagerforbrug (4) En algoritme, der er simpel De sidste tre krav kan ofte være i konflikt med hinanden.

6 Teknologi forbedrer hastigheden med en konstant faktor. Med godt algoritmedesign opnås ofte langt større hastighedsforbedringer. En dårlig algoritme på en supercomputer kan være langsommere end en god algoritme på en kugleramme Betydningen af effektive algoritmer Hvorfor bekymre sig om effektivitet med dagens hurtige computere? Antag at en algoritmes tidsforbrug vokser kvadratisk med problemstørrelsen. Med anskaffelsen af en ny computer med 10 gange så meget lager, kan der løses problemer, der er 10 gange så store. Men hvis den nye computer “kun” er 10 gange hurtigere, vil det tage 10 gange så lang tid at udføre algoritmen. Kraftigere computere medfører ønske om at løse større problemer

7 Algoritmebegrebet Historie: Ordet “algoritme” er oprindelig afledt af “algorisme”: (i middelalderen) at udføre aritmetik med arabertal, i modsætning til “abacisme”: at udføre aritmetik med kugleramme. Algorisme er igen afledt at navnet på en persisk forfatter af matematiklærebøger, Abu Ja´far Mohammed ibn Mûsâ al-Khowârizmî (cirka år 825).

8 Euklids algoritme En af de første ikke-trivielle algoritmer blev designet af Euklid (græsk matematiker cirka 300 år f. Kr.) Givet Løsning 24 og 32 8 og 12 7 og 8 Den største fælles divisor for to positive heltal er det største heltal, der “går op” i begge tal (giver resten 0 ved division). Problem: Find den største fælles divisor for to givne positive heltal

9 Lad gcd(u,v) betegne største fælles divisor for u og v. Problemet kan da formuleres således: Givet to heltal u ≥ 1 og v ≥ 1. Bestem gcd(u,v). gcd betegner greatest common divisor Løsning af problemet er bl.a. relevant ved forkortelse af brøker: 24 = 24/gcd(24,32) = 24/8 = /gcd(24,32) 32/8 4

10 En simpel algoritme er følgende (skrevet i Java): To simple algoritmer for (d = 1; d <= u; d++) if (u % d == 0 && v % d == 0) gcd = d; Algoritmernes ineffektivitet er tydelig for store værdier af u og v, f.eks og (hvor gcd er lig med 18). d = u < v ? u : v; while (u % d != 0 || v % d != 0) d--; gcd = d; En anden simpel algoritme er:

11 Euklids algoritme Euklid benyttede følgende observation til at opnå en mere effektiv algoritme: Hvis u ≥ v, og d går op i både u og v, så går d også op i differensen mellem u og v. Hvis u > v, så gælder gcd(u,v) = gcd(u-v,v). Hvis u = v, så gælder gcd(u,v) = v [ = gcd(0,v) ] Hvis u < v, så udnyttes, at gcd(u,v) = gcd(v,u) [ u og v ombyttes ]

12 while (u > 0) { if (u < v) { int t = u; u = v; v = t; } u = u - v; } gcd = v; Euklids algoritme (version 1) u = , v = 18 u = , v = 18 u = , v = u = 18, v = 18 u = 0, v = /18 = iterationer } Eksempel på kørsel:

13 Kan effektiviteten forbedres? Ja. Algoritmen trækker v fra u, indtil u bliver mindre end v. Men det er præcis det samme som at dividere u med v, og så sætte u lig med resten. Hvis u > v, så er gcd(u,v) = gcd(u%v,v). Euklids algoritme (version 2) while (u > 0) { if (u < v) { int t = u; u = v; v = t; } u = u % v; } gcd = v; Antallet af iterationer ved kørsel af eksemplet fra før reduceres til 1.

14 Udførelse af version 2 u = ,v = u = , v = u = 3240, v = u = 2898, v = 3240 u = 342, v = 2898 u = 162, v = 342 u = 18, v = 162 u = 0, v = 18 7 iterationer } Algoritmen er meget effektiv, selv for store værdier af u og v. Hvor effektiv kan bestemmes ved algoritmeanalyse. [ antal iterationer ≤ 4.8 log 10 N , gennemsnitligt antal iterationer ≈ 1.94 log 10 N ]

15 log b betegner logaritmefunktionen med base b. log b N = x  b x = N Værd at vide om logaritmer Specielt gælder log 10 (10N) = 1 + log 10 N log 2 (2N) = 1 + log 2 N To særligt interessante logaritmefunktioner er log 10 og log 2 ( = lg). log 10 N = x  10 x = N log 2 N = x  2 x = N log b (M*N) = log b M + log b N

16 Alle logaritmefunktioner er proportionale Eksempel: log 2 N = k*log 10 N, hvor k = 1/log 10 2 ≈ 3.3 Funktionskurve for log 2 N N log 2 N ° ° ° ° °

17 En alternativ algoritme? Ethvert positivt heltal kan udtrykkes som et produkt af primfaktorer u = 2 u 2 3 u 3 5 u 5 7 u 7 11 u = ∏ p u p p primtal Lad u og v være to heltal. Så kan gcd(u,v) bestemmes som ∏ p min(u p, v p ). p primtal Eksempel: u = 7000 = , v = 4400 = gcd(u,v) = = 200 Ulempe ved metoden: der kendes i dag ingen effektiv metode til at opløse et tal i dets primfaktorer! Dette faktum udnyttes i krypteringsalgoritmer (algoritmer til hemmeligholdelse af meddelelser).

18 Algoritmebegrebet (præcisering) Ved en algoritme forstås en fremgangsmåde til løsning af et problem. Udover blot at være en sekvens af operationer skal en algoritme have følgende 4 egenskaber: (1) Endelighed. Algoritmen skal terminere efter et endeligt antal skridt. (2) Entydighed. Hvert skridt skal være defineret præcist og utvetydigt. (3) Effektfuldhed. Hvert skridt skal kunne udføres på endelig tid. (4) Korrekthed. Udførelse af algoritmen skal resultere i uddata, der opfylder en specificeret relation med de givne inddata.

19 Euklids algoritme er en algoritme En kogebogsopskrift er i mange tilfælde ikke en algoritme [ fordi udsagn som “tilsæt en smule salt”, “rør forsigtigt” ikke er tilstrækkeligt præcise]

20 Matematisk definition af begrebet “algoritme” En beregningsmetode er et tupel (Q, I, Ω, f), hvor Q er en mængde, der omfatter mængderne I og Ω, og f er en funktion fra Q på sig selv. Endvidere skal f(q) være lig med q for alle q i Ω. Q, I, Ω og f repræsenterer henholdsvis mængden af beregningstilstande, mængden af inddatatilstande, mængden af uddatatilstande og den beregningsmæssige regel. Hvert element x i I definerer en beregningssekvens x 0 = x, x k+1 = f(x k ) for k ≥ 0. En beregningssekvens siges at terminere i k skridt, hvis k er det mindste heltal, for hvilket x k tilhører Ω. En algoritme er en beregningsmetode, der for enhver beregningssekvens terminerer i et endeligt antal skridt.

21 Notation for algoritmer (1) Natursproglig beskrivelse E1. [Find rest] Divider u med v, og lad r betegne resten. E2. [Er den nul?] Hvis r = 0, så terminerer algoritmen med v som svar. E2. [Ombyt] Sæt u lig med v, og v lig med r. Gå til trin E1. (2) Rutediagram Start r = u % v r = 0 ? u = v; v = r; Stop nej ja

22 (3) Programmeringssproglig beskrivelse, f.eks. i Java (eller en tilpasset delmængde heraf) eller ved brug af rekursion int gcd(int u, int v) { return v == 0 ? u : gcd(v, u % v); } [ Disse tre algoritmer er ækvivalente ] while (true) { int r = u % v; if (r == 0) { gcd = v; break; } u = v; v = r; } eller while ((r = u % v) != 0) { u = v; v = r) gcd = v;

23 Alternativer int gcd(int u, int v) { return u == 0 ? v : gcd(u % v, v); } er ikke korrekt! for (k = 0; (u & 1) == 0 && (v & 1) == 0; k++) { u >>= 1; v >>= 1; } while ((u & 1) == 0) u >>= 1; while ((v & 1) == 0) v >>= 1; if (v > u) { t = u; u = v; v = t; } while ((r = u % v) != 0) { while ((r & 1) == 0) r >>= 1; u = v; v = r; } gcd = v << k; er korrekt

24 En effektiv algoritme uden brug af % for (k = 0; (u & 1) == 0 && (v & 1) == 0; k++) { u >>= 1; v >>= 1; } t = (u & 1) == 1 ? -v : u; do { while ((t & 1) == 0) t >>= 1; if (t > 0) u = t; else v = -t; t = u - v; } while (t != 0); gcd = u << k;

25 inddata: en følge af heltalspar (p, q); betydning: p er “forbundet med” q uddata: intet, hvis p og q er forbundet, ellers (p, q) Eksempel på anvendelse: Forbindelser i et computernetværk Hvert heltal repræsenterer en computer Hvert talpar repræsenterer en tovejs netværks- forbindelse imellem to computere UNION-FIND-problemet

26 indudbegrundelse Eksempel på udførelse

27 Forbundethed kan være svær at bestemme (især for en computer)

28 (1) Hvis p er forbundet med q, så er q forbundet med p Kommutativitet:F(p,q) fi  F(q,p) F er en ækvivalensrelation Egenskaber ved relationen “forbundet med”, F Knuder, der er forbundet med hinanden, tilhører samme ækvivalensklasse (komponent). (2) Hvis p er forbundet q, og q er forbundet med r, så er p forbundet med r Transitivitet:F(p,q) ^ F(q,r) fi  F(p,r) (3) p er forbundet med sig selv Refleksivitet:F(p,p)

29 public class Program { public static void main(String args[]) { int N = IO.readInt(); int id[] = new int[N]; for (int i = 0; i < N; i++) id[i] = i; while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); if (id[p] == id[q]) continue; int t = id[p]; for (int i = 0; i < N; i++) if (id[i] == t) id[i] = id[q]; IO.println(p + " " + q); } } } Vedligehold et array, id, over navne på komponenter: hvis p og q er forbundet, så er id[p] = id[q] (ellers er id[p] ≠ id[q] ) Dette kan gøres ved for hvert par ( p, q ) at gøre ingenting, hvis id[p] = id[q] ellers ændre alle elementer med p ’s id til q ’s id Version 1 (Quick-FIND)

30 Quick-FIND Navnet skyldes et konstant tidsforbrug til at afgøre,om der findes en forbindelse mellem p og q (om p og q tilhører samme komponent). Denne operation kaldes for FIND. Med hvad med tidsforbruget til at forene to komponenter? Denne operation kaldes for UNION. Et fingerpeg herom fås ved at følge ændringerne af arrayet id.

Problem ved Quick-FIND: undersøger alle elementer i id ved UNION og er derfor langsom for “store” problemer Inddata id

32 Brug grafisk repræsentation Numre i knuder Topknuder repræsenterer komponenter ( id ) Knude i tilhører komponenten id[i]

34 Problemstørrelse og tidsforbrug Givet et stort problem med 10 9 knuder og forbindelser (f.eks. telefonnetværk, computerchip) For hver ny forbindelse gennemløber Quick-FIND hele arrayet id. Hvis der for hver tabeltilgang i gennemsnit benyttes 10 maskinoperationer, så udføres i alt cirka *10 9 *10 = maskinoperationer. Antag at tidsforbruget for en maskinoperation i gennemsnit er sekunder. Så vil det samlede tidsforbrug være cirka *10 -9 sekunder = sekunder ≈ 3000 år!

35 int N = IO.readInt(); int id[] = new int[N]; for (int i = 0; i < N; i++) id[i] = i; while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); int i = p, j = q; while (i != id[i]) i = id[i]; while (j != id[j]) j = id[j]; if (i == j) continue; id[i] = j; IO.println(p + " " + q); } Vedligehold et array over navne på komponenter: hvis p og q er forbundet, så er ( id[p] )* = ( id[q] )*, hvor ( id[p] )* = id[id[id[...id[p]]]] (fortsæt indtil værdien ikke ændres) (ellers er ( id[p] )* ≠ ( id[q] )*) Dette kan gøres ved for hvert par ( p, q ) at gøre ingenting, hvis ( id[p] )* = ( id[q] ) * ellers sættes id[i] lig med j, hvor i = ( id[p] )* og j = ( id[q] )* Version 2 (Quick-UNION)

36 Quick-UNION Navnet skyldes et konstant tidsforbrug til at forene to komponenter. (operationen UNION) Med hvad med tidsforbruget til at at afgøre, om der findes en forbindelse mellem p og q ? (operationen FIND) Et fingerpeg herom fås ved at følge ændringerne af arrayet id.

Problem ved Quick-UNION: beregningen af ( id[p] )* og ( id[p] )* kan tidsmæssigt være dyr Hurtigere end Quick-FIND for “tilfældige” inddata (men er inddata i praksis tilfældige?) Inddata id

40 Den grafiske repræsentationen af Quick-UNION viser: eller Kan effektiviteten øges ved at vælge sammen- kædningen hensigtsmæssigt? FIND-operationen gennemløber et eller to træer (tester om den samme rod nås) UNION-operationen sammenkæder to træer

41 int N = IO.readInt(); int id[] = new int[N], size[] = new int[N]; for (int i = 0; i < N; i++) id[i] = i; for (int i = 0; i < N; i++) size[i] = 1; while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); int i = p, j = q; while (i != id[i]) i = id[i]; while (j != id[j]) j = id[j]; if (i == j) continue; if (size[i] < size[j]) { id[i] = j; size[j] += size[i]; } else { id[j] = i; size[i] += size[j]; } IO.println(p + " " + q); } Modificer Quick-UNION så “ubalance” undgås: vedligehold et array, size, over komponenternes størrelse sammenkæd ved at sætte en mindre komponent under en større komponent Version 3 (vægtet quick-UNION)

Inddata id size

45 For at besvare dette spørgsmål: udfør empiriske undersøgelser, og analyser algoritmen matematisk Det ses, at “højden” af det største træ kun øges, når det sammensættes med et lige så stort træ. Det kan bevises, at FIND-delen i værste tilfælde foretager 2*log 2 N undersøgelser per forbindelse. I tilfældet med 10 9 knuder og forbindelser udføres programmet på under 1 minut (jvf. med de 3000 år for Quick-FIND) ] Er effektiviteten forbedret?

46 int N = IO.readInt(); int id[] = new int[N], size[] = new int[N]; for (int i = 0; i < N; i++) id[i] = i; for (int i = 0; i < N; i++) size[i] = 1; while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); int i = p, j = q; while (i != id[i]) i = id[i]; while (j != id[j]) j = id[j]; if (i == j) continue; int root; if (size[i] < size[j]) { root = id[i] = j; size[j] += size[i]; } else { root = id[j] = i; size[i] += size[j]; } for (i = p; i != root; i = id[i]) id[i] = root; for (j = q; j != root; j = id[j]) id[j] = root; IO.println("p + " " + q); } Version 4 (Vægtet Quick-UNION med vejkomprimering) Metode: Sørg i UNION-delen for at alle knuder, der er besøgt i FIND-delen, peger på den nye rod.

49 lg*(2) = 1 lg*(4) = lg*(2 2 ) = 1 + lg*(2) = 2 lg*(16) = lg*(2 4 ) = 1 + lg*(4) = 3 lg*(65536) = lg*(2 16 ) = 1 + lg*(16) = 4 lg*( ) = 1 + lg*(65536) = 5 Sætning: Den maksimale højde er lg*(N) hvor lg*(N) er det antal gange, log 2 kan tages af N, førend værdien bliver ≤ 1. Effektiviteten af version 4 lg* vokser meget langsomt, således er lg*(N) ≤ 5 for alle praktiske værdier af N (N ≤ ≈ ). Den maksimale højde er i praksis konstant. Beviset for sætningen er meget svært (på trods af, at algoritmen er simpel). [ lg(10 9 ) ≈ 30, mens lg*(10 9 ) ≈ 5 ]

50 while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); if (find(p) == find(q)) continue; union(p,q); IO.println(p + " " + q); } void union(int p, int q) { int i = find(p), j = find(q); if (i == j) return; if (size[i] < size[j]) { id[i] = id[p] = j; size[j] += size[i]; } else { id[j] = id[q] = i; size[i] += size[j]; } } int find(int p) { return id[p] == p ? p : (id[p] = find(id[p])); } Alternativ implementering

51 int N = IO.readInt(); int id[] = new int[N]; for (int i = 0; i < N; i++) id[i] = -1; while (!IO.eof()) { int p = IO.readInt(), q = IO.readInt(); int i = p, j = q; while (id[i] >= 0) i = id[i]; while (id[j] >= 0) j = id[j]; if (i == j) continue; int root; if (id[i] > id[j]) { id[j] += id[i]; id[i] = root = j; } else { id[i] += id[j]; id[j] = root = i; } for (i = p; id[i] > 0; i = id[i]) id[i] = root; for (j = q; id[j] > 0; j = id[j]) id[j] = root; IO.println("p + " " + q); } Arrayet size kan undværes, hvis informationen om komponenters størrelse opbevares i rødderne på de respektive træer. Størrelsen af hver komponent gemmes i roden med negativt fortegn (så der kan skelnes imellem rødder og ikke-rødder). Reduktion af pladskrav

52 Empirisk undersøgelse af UNION-FIND-algoritmerne Tid (i sekunder) på en 400 MHz Mac PowerBook G3 Metrowerks CodeWarrior Pro 5 N M F U W P N : antal knuder M : antal tilfældige forbindelser (som bevirker, at alle knuder er forbundet) F : Quick-FIND U : Quick-UNION W : Vægtet Quick-UNION P : Vægtet Quick-UNION med vejkomprimering

53 Sammenfatning Det maksimale tidsforbrug per forbindelse er proportionalt med Quick-FINDN Quick-UNIONN Vægtet Quick_UNION log 2 (N) Vejkomprimeringlg*(N) ≤ 5 Hvad har vi lært? start med en simpel algoritme benyt ikke en simpel algoritme på et “stort” problem abstraktioner (her træer) er værdifulde tilstræb garanti for acceptabelt køretidsforbrug i værste tilfælde

54 Ugeseddel september september Læs kapitel 3 og 4 i lærebogen (side 15-49) Løs følgende opgaver 1. Opgave 2.6 (Kapitel 2, opgave 6 i lærebogen). 2. Implementer en privat metode, gcd, til at forkorte en brøk,, der er repræsenteret som et objekt af klassen class Fraction { int a, b; } hvor a og b angiver henholdsvis brøkens tæller og nævner. Programmér passende konstruktører for klassen og udvid klassen med metoder til addition, subtraktion, multiplikation, division og udskrivning. Skriv et program, der beregner og udskriver værdien af summen 1 + 1/2 + 1/3 + …+ 1/9 + 1/10 som en forkortet brøk. 3. Den i opgave 2 udviklede klasse kan kun håndtere brøker, hvor både tæller og nævner kan repræsenteres i 32 bit. Benyt. Javas klasse BigInteger til at opnå en klasse Fraction, der ikke har en sådan begrænsning. Skriv et program, der beregner og udskriver værdien af summen 1 + 1/2 + 1/3 + …+ 1/99 + 1/100 som en forkortet brøk.