1 Søgning II 2 Plan Søgning ved nøgletransformation (hashing) –Hashfunktioner –Kollisionsstrategier –Effektivitet –Hashing i Java ( class HashTable )

Slides:



Advertisements
Lignende præsentationer
Den danske befolknings syn på handicappedes rettigheder
Advertisements

VMS data Geografisk og tidsmæssig udvikling af indsatsen i tobisfiskeriet v/ dataspecialist Josefine Egekvist Sekretariat for myndighedsbetjening.
Atomer Et programmeret forløb. En måde at lære på.
NemID og Fællesskema 2014 v/Signe Hansen Blegmand
1 Problemkompleksitet 2 Problemers kompleksitet En ineffektiv algoritme: køretiden vokser eksponentielt med input- størrelsen Et problem, der ikke kan.
Velkommen til Softwarekonstruktion
v/ Professor Lars Ehlers, Aalborg Universitet
Bolig selskabernes Landsforening– Almene lejeboliger - Maj/Juni Almene lejeboliger - Danmarkspanelet - Maj/Juni 2010.
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.
Datastrukturer og Collections Oversigt og forskel imellem Jave og.net Collections library Collection interfaces ArrayList IList interface Hashtable Hashtable.
1 Effektiv forrentning Kjeld Tyllesen PEØ, CBS Erhvervsøkonomi / Managerial Economics Kjeld Tyllesen, PEØ, CBS.
Arbejdsmarkedsuddannelser – også for personer med læse-, skrive- og regnevanskeligheder Oplæg fra AMU-Fyn Konference d. 22/5 -07.
Representations for Path Finding in Planar Environments.
HUSKESPIL – den lille tabel
Titel: Arial, fed, skriftstr. 20, mørkegrå. Tekst: Arial, normal, fed eller kursiv, skriftstr. 10, 12 og 14 til print – 16 og 18 til projektor – mørkegrå.
Begreber og Redskaber 8. Plan for idag Sortering fortsat Comparable Søgning –Lineær søgning –Binær søgning.
 2 3  3 =  83  43  53  63  73  93  10 4.
Søgning & sortering Intro søgning Lineær søgning Binær søgning
1 Bevisteknikker. 2 Bevisteknikker (relevant både ved design og verifikation) Teorem: Der findes uendeligt mange primtal Bevis: Antag at der findes et.
GP5, Martin Lillholm 1 Grundlæggende Programmering (GP) Efterår 2005 Forelæsning 5 Slides ligger på nettet. Du er velkommen til at printe dem nu. Vi begynder.
Pleje og Sundhed Gennemførte719 Inviterede895 Svarprocent80% FREDERICIA KOMMUNE MTU og Psykisk APV 2012 Rapportspecifikationer.
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.
MM4 Algoritmiske grundprincipper. MM1 Lister, stakke og køer. MM2 Hash-tabeller og Træer. MM3 Sortering.MM4 Søgning.MM5.
FEN IntroJava AAU1 Java grundelementer Variable og datatyper Sætninger og udtryk Metoder.
Trivselsundersøgelse og ledelsesevaluering Anæstesiologisk Afdeling Flere ledere
Datastrukturer og Collections Rasmus D. Lehrmann DM
ETU 2008 | Elevtilfredshedsundersøgelse Erhvervsskolen Nordsjælland HTX (Teknisk Gymnasium) - Hillerød Baseret på 313 besvarelser.
Begreber og Redskaber 5. Collections i Java 1.2 Framework: samling af datastrukturer og algoritmer som generelt værktøj. En ramme til at arbejde med søgning.
1 Borgerpanelet i Silkeborg Kommune.
1 Søgning I. 2 Plan Sekventiel søgning Binær søgning Binære søgetræer Balancerede binære søgetræer træer.
Finansiel vurdering af investeringer
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.
Matematik B 1.
1 Tråde 2 Plan Trådbegrebet Synkronisering Koordinering Eksempel: et flertrådet spil.
Grunde til at jeg elsker dig
GP 11, 14/ Grundlæggende programmering Efterår 2001 Forelæsning 11 onsdag 14/ kl. 9:15 – 12:00.
1 Søgetræer. 2 Binære søgetræer Definition Operationer Balancerede binære søgetræer AVL-træer Rød-sort-træer (AA-træer) B-træer Plan.
Lektion 7 Læsestof: Kopier fra Caranno
Fundamentale datastrukturer
GP 8, 24/ Grundlæggende programmering Efterår 2001 Forelæsning 8 onsdag 24/ kl. 9:15 – 12:00.
FEN KbP/seminar2: design11 Kontraktbaseret programmering Seminar 2 Klassedesign – grundprincipper Eksempler: Stack Dictionary.
Forelæsning 5.1 Brug af klassen Collections og interfacet Comparable samt parametriserede typer Projektuge: Ants and Spiders / Lommeregner dIntProg,
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.
1 Sortering. 2 Plan Elementære metoder til sortering -sortering ved indsættelse -Shellsort Sorteringsmetoder baseret på rekursion –quicksort –flettesortering.
Grafalgoritmer II.
1 Sortering. 2 Sortering ved fletning (merge-sort) 7 2 | 9 4  | 2  2 79 | 4   72  29  94  4.
10. Datastrukturer. 2 Nordjyllands Erhvervakademi Collections library Datastrukturer i.NET kaldes normalt Collections Findes i namespace System.Collections.
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer,
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper : arrays, stakke, køer,
1 Kap. 4, Jordens Tyngdefelt = Torge, 2001, Kap. 3. Tyngdekraftens retning og størrelse g (m/s 2 ) Acceleration Tyngdepotentialet (W): evene til at udføre.
1 Hashing. 2 Hashing Hashfunktioner Kollisionsstrategier Effektivitet Hashing i Javas biblioteker Prioritetskøer Binær hob Anvendelser: heapsort, ekstern.
1 Sortering. 2 Plan Elementære metoder til sortering -sortering ved indsættelse -Shellsort Sorteringsmetoder baseret på rekursion –quicksort –flettesortering.
Algoritmer Gerth Stølting Brodal Institut for Datalogi Aarhus Universitet MasterClass i Matematik, 10. april 2014, Aarhus Universitet.
KF04 GRAY Item 2, 12, 22, 32, 42, 52. Consider a builder when faced with many constructor parameters Item 2.
Anvendelser I Leg og spil.
Længste plateau En klassisk problemstilling (Gries, 1981) - og her i Java!!! Denne opgave drejer sig om at bestemme længden af det længste plateau i en.
Grundlæggende programmering Forår 2002
Begreber og Redskaber 11. Plan for idag Lidt afrunding: Collections Framework i Java Noget om oversættere og sprog Evaluering Sidste gang øvelser før.
Effective Java Blå gruppe. Item 18: Interfaces frem for abstrakte klasser Kan implementeres i klasser der ikke nedarver Eksisterende klasser kan nemt.
Begreber og Redskaber 4. Plan for idag Om metoder, parametre, returværdier Et par ord om objekt-orientering Håndkøring af programmer.
Begreber og Redskaber 3. Plan for idag Om metoder, parametre, returværdier Overblik over klasser,objekter,nedarvning Et par ord om objekt-orientering.
 Henrik B. Christensen, 1999Introducerende objektorienteret programmering8B.1 Interfaces En ren kontrakt.
Containerklasser – klassifikation og brug.  Michael E. Caspersen, 2003IOOPContainerklasser.2 Mange objekter Containerklasser –antag at man skal repræsentere.
Algoritmer og Datastrukturer 1 Hashing [CLRS, kapitel ]
Algoritmer og Datastrukturer 1
Præsentationens transcript:

1 Søgning II

2 Plan Søgning ved nøgletransformation (hashing) –Hashfunktioner –Kollisionsstrategier –Effektivitet –Hashing i Java ( class HashTable ) –Et eksempel på anvendelse Diagnostisk prøve

3 Hashing søgning ved nøgletransformation Med balancerede træer foretages O(log 2 N) sammenligninger af nøgler. Men er O(log 2 N) den bedst opnåelige kompleksitet? Nej. Hvordan opnås lavere kompleksitet? Med hashing, en metode, der benytter transformationer af nøgler til direkte at kunne referere til poster i en tabel. Med hashing opnås under gunstige omstændigheder kompleksitet O(1).

4 Gem poster i en tabel på en plads, der er bestemt af deres nøgle. En hashfunktion er en metode til beregning af et tabelindeks ud fra en nøgle. Matematisk udtrykt: en hashfunktion er en afbildning af en mængde af nøgler på et indeksinterval. Ideelt burde to forskellige nøgler afbildes på to forskellige indices. At to eller flere nøgler afbildes på samme indeks kaldes en kollision. En kollisionsstrategi er en algoritme til håndtering af kollisioner. Grundlæggende ide

5 Tid/plads-opvejning (tradeoff) Ingen pladsbegrænsninger: benyt nøglen som indeks (triviel hashfunktion) Ingen tidsbegrænsninger: benyt sekventiel søgning Hvis der er begrænsninger på både plads og tid: benyt hashing

6 Hashingteknikken Lad h betegne hashfunktionen. Indsættelse: En post med nøgle K placeres på indeks h(K), med mindre der i forvejen er en post på dette indeks. Så må posten placeres på anden måde (hvordan - afhænger af kollisionsstrategien). Søgning: Ved søgning efter en post med nøgle K, undersøges først posten på indeks h(K). Hvis denne indeholder K afsluttes søgningen med succes. Ellers fortsætter søgningen (hvordan - afhænger af kollisionsstrategien).

7 “Gode” hashfunktioner Kollisioner bør så vidt muligt undgås. Hashfunktionen bør sprede funktionsværdierne jævnt på hele indeksintervallet. Hashfunktionen bør være beregningsmæssigt billig

8 Konstruktion af hashfunktioner (Korte nøgler) Korte nøgler (kan være i et maskinord): betragt nøglen som et heltal og beregn h(K) = K mod M (i Java: K % M) hvor M er tabelstørrelsen. h(K) [0;M-1]

9 Nøgler bestående af 4 ascii-tegn, tabelstørrelse 101. ascii a b c d hex bin Eksempel med korte nøgler 0x = % 101 = 11 Nøglen “abcd” hasher til 11. 0x = % 101 = 57 Nøglen “dcba” hasher til 57. 0x = % 101 = 57 Nøglen “abbc” hasher også til 57. Kollision!

10 Tabelstørrelsen Vælg tabelstørrelsen som et primtal. Hvorfor? I eksemplet før havde vi “abcd” = 0x = 97* * * Hvis tabelstørrelsen vælges til 256, vil kun det sidste tegn have betydning ved beregning af h. En simpel måde at sikre sig, at alle tegn bidrager, er at vælge tabelstørrelsen som et primtal.

11 Konstruktion af hashfunktioner (Lange nøgler) Lange nøgler (kan ikke være i et maskinord): betragt nøglen som et langt heltal og beregn h(K) = K mod M hvor M er tabelstørrelsen. Altså i princippet som for korte nøgler.

12 Eksempel med lange nøgler Eksempel med 4 tegn. Men metoden virker for vilkårligt lange nøgler. Benyt Horners regel: 0x = 97* * * = ((97* )* )* Tag modulo efter hver addition (for at undgå aritmetisk overløb): (97* = 24930) % 101 = 84 (84* = 21603) % 101 = 90 (90* = 23140) % 101 = 11

13 int hash(String key, int M) { int h = 0; for (int i = 0; i < key.length(); i++) h = (h*117 + key.charAt(i)) % M; return h; } For at sprede værdierne bedre er 256 her erstattet med 117. Hashfunktion i Java Java har en metode til hashkodning, hashCode, knyttet til klassen String. Metoden hash kunne derfor alternativt programmeres således: int hash(String key, int M) { return key.hashCode() % M; }

14 public int hashCode() { int h = 0; int off = offset; char val[] = value; int len = count; if (len < 16) { for (int i = len; i > 0; i--) h = (h * 37) + val[off++]; } else { // only sample some characters int skip = len / 8; for (int i = len; i > 0; i -= skip, off += skip) h = (h * 39) + val[off]; } return h; } public int hashCode() { int h = 0; int off = offset; char val[] = value; int len = count; if (len < 16) { for (int i = len; i > 0; i--) h = (h * 37) + val[off++]; } else { // only sample some characters int skip = len / 8; for (int i = len; i > 0; i -= skip, off += skip) h = (h * 39) + val[off]; } return h; } Javas implementering af hashCode i String (Java 1.1)

15 Javas implementering af hashCode i String (Java 1.2) public int hashCode() { int h = 0; int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) h = 31*h + val[off++]; return h; }

16 Kollisioner Fødselsdagsparadokset: Hvor mange personer skal være forsamlet i et selskab, for at der er mere en 50% sandsynlighed for at mindst to personer har fødselsdag på samme dag? Svar: 24. Lad M være tabelstørrelsen. Hvor mange indsættelser kan i gennemsnit foretages, før der opstår en kollision? M

17 Kollisionstrategier Antal poster: N Tabelstørrelse: M Mulighed 1 (separat kædning): Tillad N > M: læg nøgler, der hasher til samme indeks, ind i en liste (med cirka N/M nøgler per liste). Mulighed 2 (åben adressering): Sørg for at N < M: læg kolliderende nøgler i tabellen.

18 Separat kædning Simpel, praktisk og meget udbredt metode. Metode: M hægtede lister - en for hver tabelindgang. 0:* 1:L A W * 2:M X * 3:N C * 4:* 5:E P * (M = 11) 6:* (N = 14) 7:G R * 8:H S * 9:I * 10:* Nedbringer den gennemsnitlige søgetid med en faktor M i forhold til sekventiel søgning. succesfuld søgning: (7*1+6*2+1*3)/17 = 22/17 ≈ 1.29 mislykket søgning: ( )/11 = 14/11≈ 1.27

19 Indsættelse og søgning ved separat kædning class Node { String key, info; Node next; Node(String k, String i, Node n) { key = k; info = i; next = n; } } void insert(String key, String info) { int i = hash(key, M); a[i] = new Node(key, info, a[i]); } String search(String key) { for (Node n = a[hash(key, M)]; n != null; n = n.next) if (key.equals(n.key)) return n.info; return null; }

20 Effektivitet Indsættelse: 1 Mislykket søgning:N/M (i gennemsnit) Succesfuld søgning: N/M/2 (i gennemsnit) Værste tilfælde for søgning: N. Hvis listerne holdes sorteret: Tid for indsættelse øges til N/M/2 Tid for mislykket søgning mindskes til N/M/2

21 Eksempel på åben adressering Lineær prøvning Åben adressering: Ingen hægter. Alle poster opbevares i tabellen. Lineær prøvning: Start lineær søgning fra hashpositionen, og stands ved den søgte post eller en tom position. Stadig konstant søgetid, hvis M er tilstrækkelig stor.

22 Et simpelt eksempel Mængden af nøgler er alfabetets store bogstaver. Der er ingen information tilknyttet nøglerne. Tabelstørrelsen er 7. h(K) = (K’s nummer i alfabetet) mod 7 = (K - ‘A’ + 1) %

23 h(N) = 14 % 7 = 0 h(C) = 3 % 7 = 3 h(K) = 11 % 7 = 4 h(S) = 19 % 7 = C S N K Tabel efter indsættelse af nøglerne C, K, N, S

24 Indsættelse af Y giver kollision h( Y ) = 25 % 7 = C S N N Placering efter 3 forsøg C S N N Y

25 Indsættelse og søgning ved lineær prøvning String search(String key) { int i = hash(key, M); while (a[i].info != null && !key.equals(a[i].key)) i = (i+1) % M; return a[i].info; } void insert(String key, String info) { int i = hash(key, M); while (a[i].info != null) i = (i+1) % M; a[i].key = key; a[i].info = info; } Hvad sker der, hvis tabellen bliver fuld? Hvorledes foretages sletning?

26 Sletning ved lineær prøvning void remove(String key) { int i = hash(key, M); while (a[i].info != null && (a[i].info == deleted || !key.equals(a[i].key))) i = (i+1) % M; if (a[i].info != null) a[i].info = deleted; } static final String deleted = new String(); insert: while (a[i].info != null && a[i].info != deleted) i = (i+1) % M; search: while (a[i].info != null && (a[i].info == deleted || !key.equals(a[i].key))) i = (i+1) % M;

27 Effektivitet Tyndt besat tabel: ligesom separat kædning. Lineær prøvning bruger gennemsnitligt færre end 5 forsøg for en hashtabel, der er mindre end 2/3 fuld. De præcise udtryk er: forsøg ved mislykket søgning, og forsøg ved succesfuld søgning, hvor  = N/M betegner fyldningsgraden.

28 Effektivitetskurver for lineær prøvning Mislykket søgningSuccesfuld søgning  

29 Klyngedannelse Efterhånden som tabellen bliver fyldt op, opstår der klynger.

30 Antag at alle positioner [i:j] indeholder poster, mens i-1, j+1 og j+2 er tomme. Argumentation for tendens til klyngedannese i-1j+1j+2 Så vil chancen for, at en ny post placeres på position j+1 være lig med chancen for, at en ny post skal placeres i intervallet [i:j+1]. For at den nye post placeres på j+2, skal dens hashværdi derimod være præcis j+2.

31 Klyngedannelse Uheldigt fænomen. Lange klynger har en tendens til at blive længere. Søgelængen vokser drastisk, når tabellen fyldes. Lineær prøvning er for langsom, når tabellen bliver 70-80% fuld.

32 Dobbelt hashing Undgå klyngedannelse ved at bruge en ekstra hashfunktion. Derved øges sandsynligheden for at finde tomme indgange ved indsættelse. I stedet for som i lineær prøvning at prøve successive indgange, foretages prøvningen med en fast afstand bestemt af den anden hashfunktion.

33 String search(String key) { int i = hash(key, M); int u = hash2(key, M); while (a[i].info != null && !key.equals(a[i].key)) i = (i+u) % M; return a[i].info; } Dobbelt hashing i Java void insert(String key, String info) { int i = hash(key, M); int u = hash2(key, M); while (a[i].info != null) i = (i+u) % M; a[i].key = key; a[i].info = info; }

34 Krav til den anden hashfunktion Den bør ikke returne 0. Den skal altid returnere værdier, der er primiske med M. Kan opnås ved at vælge M som et primtal og lade h 2 (k) < M for ethvert k. Den skal være forskellig fra den første. Forslag 1: h 2 (k) = 1 + (M-2-k) mod (M-2) Forslag 2 (simplere og hurtigere): h 2 (k) = 8 - (k % 8) (k % 8 er de sidste 3 bit af k)

35 Effektivitet Dobbelt hashing bruger gennemsnitligt færre forsøg end lineær prøvning. Metoden bruger i gennemsnit færre end 5 forsøg ved en søgning, når tabellen højst er 80% fuld, og færre end 5 forsøg ved en succesfuld søgning, når tabellen højst er 99% fuld. De præcise udtryk er: forsøg ved mislykket søgning, og forsøg ved succesfuld søgning, hvor  er fyldningsgraden.

36 Dobbelt hashing contra lineær prøvning   Mislykket søgningSuccesfuld søgning dobbelt hashing Mislykket søgning Succesfuld søgning   lineær prøvning

37 Antag at en nøgle og en peger fylder det samme: 1 ord. Antag endvidere at der er 4M poster. Separat kædning contra dobbelt hashing Dobbelt hashing med samme tidsforbrug: 4M poster, gennemsnitlig søgetid: 2.5 Pladskrav: cirka 6.7M ord (idet 1/(1-4/6.7) ≈ 2.5) d.v.s. 26% mindre plads. Dobbelt hashing med samme pladsforbrug: 4M poster, tabelstørrelse: 9M ord (9 M poster) Gennemsnitlig søgetid: 1/(1-4/9) ≈ 1.8, d.v.s. 28% hurtigere Plads ved separat kædning og tabelstørrelse M: 4M nøgler, 4M hægter i knuder, M tabelindgange (pegere til knuder) Pladskrav: 9M ord til 4M poster Gennemsnitlig søgetid: (1+4)/2 = 2.5

38 Antag at en peger til postens information fylder 1 ord. Separat kædning contra dobbelt hashing Dobbelt hashing med samme tidsforbrug: 4M poster, gennemsnitlig søgetid: 2.5 Pladskrav: cirka 2*6.7M ord (idet 1/(1-4/6.7) ≈ 2.5) d.v.s. 3% mere plads. Dobbelt hashing med samme pladsforbrug: 4M poster, tabelstørrelse: 13 M ord (6.5 M poster) Gennemsnitlig søgetid: 1/(1-4/6.5) ≈ 2.6, d.v.s. 4% langsommere Plads ved separat kædning og tabelstørrelse M: 4M nøgler, 4M pegere til posternes information 4M hægter i knuder, M tabelindgange (pegere til knuder) Pladskrav: 13M ord til 4M poster Gennemsnitlig søgetid: (1+4)/2 = 2.5

39 Fordele ved separat kædning Idiotsikker metode (bryder ikke sammen) Antallet af poster behøver ikke at være kendt på forhånd Sletning er simpel Tillader ens nøgler

40 Hashing i Java class Dictionary public abstract class Dictionary { abstract public Object put(Object key, Object value); abstract public Object get(Object key); abstract public Object remove(Object key); abstract public int size(); abstract public boolean isEmpty(); abstract public Enumeration keys(); abstract public Enumeration elements(); }

41 class Hashtable public class Hashtable extends Dictionary implements Cloneable { public Hashtable(int initialCapacity, float loadFactor) {... } public Hashtable(int initialCapacity) {... } public Hashtable() { this(101, 0.75f); } public synchronized Object put(Object key, Object value) {... } public synchronized Object get(Object key) {... } public synchronized Object remove(Object key) {... } public int size() {... } public boolean isEmpty() {... } public synchronized Enumeration keys() {... } public synchronized Enumeration elements() {... } public synchronized boolean contains(Object value) {... } public synchronized boolean containsKey(Object key) {... } public synchronized void clear() {... } public synchronized Object clone() {... } public synchronized String toString() {... } protected void rehash() {... } }

42 Metoden get (benytter separat kædning) class HashtableEntry { int hash; Object key; Object value; HashtableEntry next; } private HashtableEntry table[]; private int count; private int threshold; private float loadFactor; public synchronized Object get(Object key) { HashtableEntry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (HashtableEntry e = tab[index]; e != null; e = e.next) if (e.hash == hash && e.key.equals(key)) return e.value; return null; }

43 public synchronized Object put(Object key, Object value) { if (value == null) throw new NullPointerException(); HashtableEntry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (HashtableEntry e = tab[index]; e != null; e = e.next) if (e.hash == hash && e.key.equals(key)) { Object old = e.value; e.value = value; return old; } if (count >= threshold) { rehash(); return put(key, value); } HashtableEntry e = new HashtableEntry(); e.hash = hash; e.key = key; e.value = value; e.next = tab[index]; tab[index] = e; count++; return null; } Metoden put

44 protected void rehash() { int oldCapacity = table.length; HashtableEntry oldTable[] = table; int newCapacity = oldCapacity*2 + 1; HashtableEntry newTable[] = new HashtableEntry[newCapacity]; threshold = (int)(newCapacity * loadFactor); table = newTable; for (int i = oldCapacity; i-- > 0; ) { for (HashtableEntry old = oldTable[i]; old != null; ) { HashtableEntry e = old; old = old.next; int index = (e.hash & 0x7FFFFFFF) % newCapacity; e.next = newTable[index]; newTable[index] = e; } } } Metoden rehash

45 public synchronized Object remove(Object key) { HashtableEntry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (HashtableEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key.equals(key)) { if (prev != null) prev.next = e.next; else tab[index] = e.next; count--; return e.value; } } return null; } Metoden remove

46 I Java 1.2 anbefales det at bruge interface Map i stedet for class Dictionary. class Dictionary er forældet (eng.: obsulete). Udover class HashTable findes class HashMap. Begge implementerer Map. De har meget tilfælles, men i modsætning til HashTable er HashMap ikke synkroniseret. Desuden kan det nævnes, at class TreeMap implementerer interfaceSortedMap ved hjælp af rød- sort-træer. Hashing i Java 1.2

47 Et avanceret eksempel på anvendelse af hashing (Den rejsende sælgers problem) En sælger skal besøge n byer. Find den korteste tur, som starter og ender i en given by. A B C D E F G Eksempel med 7 byer:

48 Heuristisk algoritme: (1) Start med en tilfældig tur. (2) Så længe 2 kanter kan ombytttes med 2 andre kanter, således at turen forkortes, så foretag ombytningen. Udfør denne algoritme et givet antal gange og vælg den korteste af de fundne ture. Effektivitetsproblem: Tiden til undersøgelse af, at ingen forbedring er mulig udgør 30-50% af køretiden. Denne tid (checkout time) kan mindskes, hvis det kan konstateres, at den aktuelle tur er blevet undersøgt før. 2-opt swap

49 (1) h er invariant overfor cyklisk permutering: h(c 1,c 2,..., c n-1,c n ) = h(c 2,c 3,..., c n,c 1 ) =... = h(c n-1,c n,..., c n-3,c n-2 ) = h(c n,c 1,..., c n-2,c n-1 ) (2) h er invariant overfor spejling: h(c 1,c 2,..., c n-1,c n ) = h(c n,c n-1,..., c 2,c 1 ) (3) h er beregningsmæssigt billig xor xor i Java: ^ En mulig hashfunktion: h(c 1,c 2,..., c n-1,c n ) = (c 1 *c 2 ) xor (c 2 *c 3 ) xor... xor (c n-1 *c n ) xor (c n *c 1 ) Problem: Bestem en hashfunktion h(c 1,c 2,..., c n-1,c n ) hvor c 1,..., c n angiver byernes numre, således at

50 Opdatering ved hver ombytning: h ^= r[c1]*r[c2] ^ r[c3]*r[c4] ^ r[c2]*r[c4] ^ r[c3]*r[c1]; 2-opt swap c3c3 c4c4 c2c2 c1c1 c3c3 c1c1 c2c2 c4c4 idet (a ^ b) ^ b = a Forbedret løsning: h(c 1,c 2,..., c n-1,c n ) = (r[c 1 ]*r[c 2 ]) xor (r[c 2 ]*r[c 3 ]) xor... xor (r[c n ]*r[c 1 ) hvor r[1..n] er en tabel af tilfældige heltal.

51 Grunde til ikke at bruge hashing Hvorfor bruge andre metoder? Der er ingen effektivitetsgaranti Hvis nøglerne er lange, kan hashfunktionen være for kostbar at beregne Bruger ekstra plads Understøtter ikke sortering

52 Ugeseddel oktober - 3. november Læs kapitel 19 (side ) og side i kapitel 21 i lærebogen Løs følgende opgaver 1. Opgave 16.3 og 16.5.