Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version



Relaterede dokumenter
Abstrakte datatyper C#-version

Rekursion C#-version

Invarianter. Invariant: Et forhold, som vedligeholdes af algoritmen gennem (dele af) dens udførelse. Udgør ofte kernen af ideen bag algoritmen.

Forelæsning 17, tirsdag 2. november 1999 Søgning efter en given værdi i en tabel. Programmering 1999

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

26 Programbeviser I. Noter. PS1 -- Programbeviser I. Bevis kontra 'check af assertions' i Eiffel. Betingelser og bevisregler.

Algoritmer og invarianter

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen (bemærk at log n betegner totals logaritmen): n 2 (log n) 2 2.

3 Algebraisk Specifikation af Abstrakte Datatyper.

Søgning og Sortering. Søgning og Sortering. Søgning. Linæer søgning

Python programmering. Per Tøfting. MacFest

Programmering for begyndere Lektion 2. Opsamling mm

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 7 n 1/ log n. (log n) 4

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: (logn) 5. 5n 2 5 logn. 2 logn

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 4 n n 3n n 2 /logn 5 n n (logn) 3n n 2 /logn 4 n n 5 n

Skriftlig eksamen i Datalogi

Eksempel: et ordresystem note 5 Lagdeling s. 1

Binære søgetræer. Binære søgetræer. Nærmeste naboer. Nærmeste nabo

Noter til C# Programmering Iteration

Objektorienteret design med arv og polymorfi:

Forelæsning Uge 4 Torsdag

Skriftlig Eksamen Algoritmer og Datastrukturer (DM507)

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: (logn) 2 2 n 1/n (logn) n. n 2

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 5n 4. logn. n 4n 5 n/logn. n n/logn 5n

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

BRP Sortering og søgning. Hægtede lister

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: (logn) 7 n 1/2 2 n /n 3 2logn n 2 /logn

Skriftlig eksamen i Datalogi

dintprog Manual Revision: 1241 August 24, 2010 I Introduktion 3 1 Notation 3 II Begreber 4 2 Grundbegreber om programmering 4

Ugeseddel 4 1. marts - 8. marts

Opgave 1 (10%) I det følgende angiver log n 2-tals-logaritmen af n. Ja Nej. n+3n er O(2n)? n 6 er O(n 5 )? nlogn er O(n 2 /logn)? 4n 3 er O(3n 4 )?

Binære søgetræer. Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb. Philip Bille

Søgning og Sortering. Søgning Linæer søgning Binær søgning Sortering Indsættelsessortering Flettesortering. Philip Bille

Forelæsning Uge 3 Torsdag

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n+logn logn (logn) 7 (3/2) n

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n 3/2. n logn (3/2) n. 2 3logn (3/2) n

Forelæsning Uge 2 Torsdag

INSTITUT FOR DATALOGI, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Forelæsning Uge 4 Mandag

DM507 Algoritmer og datastrukturer

Tilgang til data. To udbredte metoder for at tilgå data: Sekventiel tilgang Random access: tilgang via ID (også kaldet key, nøgle) for dataelementer.

DM507 Algoritmer og datastrukturer

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 23n log n. 4 n (log n) log n

dsoftark E2007 Gruppe 14: Anders, Troels & Søren 15. november 2007 Rapport til a. 1 'TDD rytmen'

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Design by Contract Bertrand Meyer Design and Programming by Contract. Oversigt. Prædikater

16. december. Resume sidste gang

Programmering og Problemløsning, 2017

Kursusarbejde 3 Grundlæggende Programmering

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n 7 n 1 7 7/n. 7nlogn. 7n 7nlogn n7

Software Construction 1 semester (SWC) Spørgsmål 1

INSTITUT FOR DATALOGI, AARHUS UNIVERSITET EKSAMEN. Grundkurser i Datalogi. Algoritmer og Datastrukturer 1 (2003-ordning)

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Sortering. Eksempel: De n tal i sorteret orden

Forelæsning Uge 3 Torsdag

Studiepraktik. Thomas Bøgholm Mikkel Hansen Jacob Elefsen

Sortering af information er en fundamental og central opgave.

Målet for disse slides er at beskrive nogle algoritmer og datastrukturer relateret til at gemme og hente data effektivt.

Datastrukturer (recap)

Forelæsning Uge 3 Torsdag

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Introduktion til datastrukturer

Forelæsning Uge 4 Torsdag

Forelæsning Uge 4 Mandag

INSTITUT FOR DATALOGI, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

BRP Tal. Om computer-repræsentation og -manipulation. Logaritmer

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Indledning. Hvorfor det forholder sig sådan har jeg en masse idéer om, men det bliver for meget at komme ind på her. God fornøjelse med læsningen.

dintprog Manual Revision: 731 September 30, Introduktion Notation... 3 I Begreber 4 2 Grundbegreber om programmering 4

Forelæsning Uge 2 Mandag

Skriftlig Eksamen Algoritmer og Datastrukturer 1. Datalogisk Institut Aarhus Universitet. Mandag den 22. marts 2004, kl

Skriftlig Eksamen Algoritmer og Datastrukturer 1. Datalogisk Institut Aarhus Universitet

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Datalogi C + Datastrukturer og Algoritmer

Et udtryk er (som bekendt?) lineært hvis den differentierede er en konstant funktion, dvs. at den ikke afhænger af x. Betragt f lgende værdiprocedurer

Eksamens spørgsmål Software Construction. Objekter. Spørgsmål 1: Januar Giv en beskrivelse af Objekt-begrebet og deres brug

UNION-FIND. UNION-FIND-problemet. Forbundethed kan være svær at afgøre (især for en computer) Eksempel på udførelse

Datastrukturer (recap)

Løsning af møntproblemet

Sortering. Eksempel: De n tal i sorteret orden

Kapitel 3 Betinget logik i C#

Sortering i lineær tid

Danmarks Tekniske Universitet

Design by Contract. Design and Programming by Contract. Oversigt. Prædikater

Forelæsning Uge 4 Mandag

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 4

Tilgang til data. To udbredte metoder for at tilgå data: Sekventiel tilgang Random access: tilgang via ID (key, nøgle) for dataelementer.

SWC eksamens-spørgsmål. Oversigt

28 Algoritmedesign. Noter. PS1 -- Algoritmedesign

DATALOGISK INSTITUT, AARHUS UNIVERSITET. Det Naturvidenskabelige Fakultet EKSAMEN. Grundkurser i Datalogi

Datastrukturer (recap) Datastruktur = data + operationer herpå

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n 2 n (log n) 2. 3 n /n 2 n + (log n) 4

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Kontrol-strukturer i PHP

Målet for disse slides er at diskutere nogle metoder til at gemme og hente data effektivt.

Transkript:

Note til Programmeringsteknologi Akademiuddannelsen i Informationsteknologi Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version Finn Nordbjerg 1/9

Indledning I det følgende introduceres et par abstrakte algoritmer eller algoritmeskabeloner. Idéen bag indførelse af algoritmeskabeloner er, at en lang række problemer kan løses med algoritmer, som har en fælles grundstruktur. Det er en stor hjælp, hvis man kan henføre en given algoritme til en skabelon: Man har en kendt grundstruktur, så den dybe tallerken ikke skal opfindes igen og igen. Det er enklere at verificere korrekthed, når man kan sammenholde sin løsning med en kendt skabelon. Skabelonen har et navn, så man kan snakke om den i forbindelse med udvikling, dokumentation og vedligeholdelse. Om notation. I det følgende anvendes et C#-lignende pseudosprog, hvor de abstrakte operationer er angivet i skarpe parenteser ("<...>"). En abstrakt operation skal konkretiseres til C#-sætninger, som realiserer den konkrete algoritme. Ved specifikation af operationer anvendes PRE til at angive en pre-betingelse for operationen, dvs. hvad der skal være opfyldt for, at det er meningsfuldt at udføre operationen. Tilsvarende anvendes POST ved angivelse af post-betingelsen for operationen, dvs. hvad der er opfyldt efter, operationen er udført under forudsætning af at pre-betingelsen var opfyldt inden. Om sweep-algoritmer. En lange række algoritmer er karakteriseret ved, at de hæmningsløst fejer (eng. sweep) henover en datamængde, kikker på alle elementer og gør et eller andet ved alle (evt. kun en del af) elementerne. Den abstrakte sweep-algoritme kan formuleres som følger: < evt. initiering af hensyn til GØR-operationen (GØR-INIT) >; < INITIER ubesøgt mængde, UM >; while <! FÆRDIG (dvs. UM ikke er tom)> { < UDVÆLG aktuelt element fra UM >; < GØR noget ved aktuelt element>; < FJERN aktuelt element fra UM> 2/9

Hvorledes operationerne INITIER, FÆRDIG, UDVÆLG og FJERN skal realiseres afhænger af repræsentationen af datamængden. Realiseringen af GØR-INIT og GØR afhænger endvidere af den konkrete opgave, som algoritmen skal løse. Om sweep-algoritmer på sekvenser af heltal. Hvis vores datamængde er et array af heltal (int[] a), kan INITIER, UDVÆLG, FÆRDIG og FJERN realiseres vha. en simpel tællerkonstruktion, og så får sweep-skabelonen følgende udseende, hvor vi antager, at i er en variabel af typen int: INITIER: i = 0 UDVÆLG: a[i] FÆRDIG: i > =a.length FJERN: i++ Indsættes dette i skabelonen, fås: < GØR-INIT >; int i=0; while ( i < a.length) { < GØR noget ved a[i] >; i++; Som bekendt kan tæller-styrede løkker udtrykkes simplere i C# vha. for-sætningen: < GØR-INIT >; for (int i=0 ; i<a.length ; i++ ) { < GØR noget ved a[i]>; } // end for Er opgaven fx. at tælle antal nuller i en sekvens af heltal kan de manglende operationer realiseres som følger: GØR-INIT: int result= 0; GØR: if (a[i] = = 0) result++; Indsættes dette i skabelonen, fås: 3/9

int result= 0; for (int i=0 ; i<a.length ; i++){ if (a[i] = = 0) result++; } // end for På samme måde kan andre algoritmer, der arbejder på sekvenser af heltal (eller sekvenser af alt muligt andet, for den sags skyld) ses som konkretiseringer af sweep-skabelonen. Specielt for C#: foreach og Enumerators I visse tilfælde i C# kan et sweep skrives endnu enklere ved brug af foreach-konstruktionen: int[] a= new int[10]; for(int i= 0; i<a.length; i++) a[i]= 2*i+1;//lav et array med nogle tal foreach(int x in a){ //gør noget ved x } Herved behandles alle elementer i a efter tur. Generelt har foreach-sætningen følgende form: foreach(type varnavn in collectionnavn) Sætning Hvor Type er en type (simple eller klasse), som er assignment-kompatibel med elementerne i collectionnavn, og collectionnavn er et objekt af en type, som implementerer IEnumerableinterfacet (herom ved en anden lejlighed). Alle C# s standard-collections (incl. Array) implementer dette interface. Variablen varnavn tildeles værdien af hver forekomst i collectionnavn efter tur og Sætning udføres for hver værdi. For et arrays vedkommende svarer sætningen altså fuldstændig til foreach(int x in a) for(int i= 0; i<a.length; i++) int x= a[i]; 4/9

foreach-konstruktionen kan dog ikke anvendes, hvis elementerne i collectionnavn skal ændres. F.eks. opgaven "læg een til alle elementer" : GØR-INIT: GØR: a[i]= a[i]+1; Indsat i skabelonen: Derimod vil for (int i= 0 ; i<a.length ; i++) { a[i]= a[i] +1; } // end for foreach(int x in a) x= x+1; ikke virke. foreach-loopet er baseret på iterator-begrebet: Kort fortalt er en iterator et objekt, som gør det muligt at iterere over en collection uden at kende den interne struktur. En collection som fx ArrayList (skal implementere IEnumerable) har en metode, som returnerer en iterator. Iteratoren har metoder til rykke til næste element, til at tilgå aktuelt element mv. I C# kaldes iteratorer enumeratorer, og de har statisk type IEnumerator: Eksempel: IList a = new ArrayList(); IEnumerator it = a.getenumerator();//få en iterator it while (it.movenext()) { System.Console.WriteLine(it.Current); //it.current = (int)it.current * 3;//Virker ikke. Current er read-only } it.reset();//sæt iteratoren før første element En nyoprettet iterator står før første element i collectionen, metoden MoveNext() flytter iteratoren til næste element og returnere sand, hvis der er et næste element. Hvis der ikke er flere elementer returneres falsk. Current er en read-only property, som returnerer aktuelt element. Reset() resetter iteratoren til umiddelbart før første element, så vi er klar til en ny iteration. 5/9

Algoritmeskabeloner og søgealgoritmer Om søgealgoritmer Søgealgoritmer er karakteriseret ved, at de undersøger en samling elementer (søgemængden) for en evt. forekomst af et element med nogle bestemte karakteristika. Det søgte element kaldes målelementet, m. Strategien er at udvælge et element, kandidatelementet, k fra den del af søgemængden, som ikke allerede er undersøgt (kandidatmængden, KM); undersøge dette element: er det m, så er vi færdige, hvis ikke så splittes KM i en ny kandidatmængde og en del, hvori m ikke kan befinde sig, og søgningen fortsættes i den nye kandidatmængde. Algoritmen kan formuleres, som følger: < INITIER KM >; bool found= false; while (! found && < KM Ø > ) { < UDVÆLG k fra KM >; if ( k==m ) found = true; else { < SPLIT KM i forhold til k og m > }//end else Hvorledes de abstrakte operationer INITIER, KM Ø, UDVÆLG, og SPLIT skal realiseres afhænger af repræsentationen af datamængden. Det skal bemærkes, at søgeskabelonen adskiller sig fra sweep-skabelonen ved, at en sweepalgoritme altid gennemløber hele datamængden, mens en søgealgoritme standser første gang den møder målelementet. Krav til de abstrakte operationer INITIER: PRE none POST KM = søgemængden Efter INITIER er udført, skal KM være lig hele søgemængden. Vi må altså ikke fjerne noget på forhånd. (Notationen KM : mærket angiver variablens (objektets) tilstand efter operationen er udført.) KM Ø: PRE none POST returnerer true, hvis kandidatmængden er tom, ellers false 6/9

UDVÆLG: PRE KM Ø POST k KM UDVÆLG må kun kaldes, hvis KM ikke er tom. Det eneste krav er, at k skal udvælges fra kandidatmængden. SPLIT: PRE k m && KM Ø && k KM POST k er fjernet fra KM. m må ikke fjernes. SPLIT må kun kaldes, hvis målelementet ikke er fundet, hvis der flere kandidatelementer i KM,, og hvis k er i KM. Der må gerne fjernes flere elementer end kandidatelementet - bare ikke målelementet (hvis det findes i KM). Om søgealgoritmer på sekvenser af heltal Hvis vores datamængde er et array af heltal (int[] a ), kan INITIER, UDVÆLG, KM Ø og SPLIT realiseres vha. en tællerkonstruktion, og så får søgeskabelonen følgende udseende: INITIER: int i = 0 UDVÆLG: k = a[i] KM Ø: i < a.length SPLIT: i ++ Dette skal forståes på den måde, at KM er tallene i arrayet a fra plads i til enden af a. (Opgave: Overvej om disse realiseringer overholder kravene til de abstrakte operationer.) Indsættes dette i skabelonen, fås: int k; int i= 1; bool found= false; while (!found && i<a.length ) { k = a[i]; if (k == m) found= true; else i ++; 7/9

(Opgave: Hvis det vides, at søgemængden er sorteret (ikke-aftagende), kan man så effektivisere ovenstående realisering ved at ændre realiseringen af <KM Ø>? Løsningen kaldes binær søgning i en sorteret datamængde.) En "smart" realisering af søgeskabelonen på et sorteret array (binær søgning) Strategien i binær søgning er kort fortalt: kik i midten af kandidatmængden: er målelementet lig midterelementet, så er vi færdige er målelementet større end midterelementet, så søg i den del af kandidatmængden, som ligger over midten er målelementet mindre end midterelementet, så søg i den del af kandidatmængden, som ligge under midten gentag dette til målelementet er fundet eller kandidatmængden er tom Hvis søgemængden er et array, kan kandidatmængden repræsenteres ved to index, low og high, som udpeger start og slut på den del af søgemængden, som målelementet kan være i. Følgende realisering kan anvendes: INITIER: int low = 0; int high = a.length-1; UDVÆLG: middle = (high + low) / 2; k = a[middle]; KM Ø: low <= high SPLIT: if (k<m) { low= middle + 1 } else { high= middle 1} (Opgave: Overvej om disse realiseringer overholder kravene til de abstrakte operationer.) Realiseringen af skabelonen bliver hermed: 8/9

int low = 0; int high = a.length-1; int k, middle; bool found = false; while (! found && low<=high ) { middle = (high + low) / 2; k= a[middle]; if (k == m) found= true; else if ( k<m ) low = middle+1; else high= middle-1; På et sorteret array vil binær søgning være langt hurtigere end lineær søgning. (Opgave: Hvorfor? Hvor meget hurtigere?) Det viser sig, at en søgning i en liste med n elementer skal UDVÆLG, SPLIT og KM Ø udføres et antal gange, som proportional med n, hvis man anvender den simple søge-algoritme, men kun med log(n) ved den binære søgning. (Dette betyder, at hvis liste fx indeholder ca. 1000 elementer, så vil den simple søgning i gennemsnit kikke på ca. 500 elementer, mens binær søgning kun kikker på ca. 10 elementer!). Til gengæld kræver binær søgning at listen er sorteret. 9/9