Zoeken in twee dimensies Wat is het probleem? Eerder heb je gezien hoe je snel in een gesorteerde tabel kunt zoeken met binair zoeken. Stel je nu voor dat je ergens in een bos staat en moet bepalen wat de dichtstbijzijnde boom is. Opdracht 1 De bomen hebben de volgende coördinaten: (3,4), (4,2) en (6,7). Jij staat op het punt (5;4,5)1. Welke boom staat het dichtst bij? Als je een tekening van dit 'bos' maakt zie je het antwoord wellicht meteen. Een eerste oplossing Opdracht 2 Een computer kan de oplossing echter niet zo maar 'zien'. Je moet hem leren hoe je bepaald wat je met 'dichtstbijzijnde' bedoeld. Bereken nu de afstand van de drie bomen en bepaal zo met zekerheid welke boom het meest dichtstbij staat. Hint: gebruik de stelling van Pythagoras. 1 Als je kommagetallen als coördinaten gebruikt moet je de x- en y-coördinaat met een puntkomma scheiden. Als je dat niet doet is niet duidelijk wat je met (2,5,6) bedoeld: (2,5;6) of (2;5,6). Opdracht 3 In de laatste stap van de stelling van Pythagoras bereken je de wortel. Kun je het dichtstbijzijnde punt ook bepalen als je die stap achterwege laat? Bijvoorbeeld: 3 is kleiner dan 7, dan is ook 3*3 kleiner dan 7*7 Je moet nu van alle punten de afstand bepalen om de dichtstbijzijnde te vinden. Dat is bij drie punten nog wel handmatige te doen. Bij een groter aantal punten is een computer handiger. Een programma doorloopt alle punten en houdt bij welke punt tot nu toe het meest nabij was. In een moderne routeplanner zitten alle wegen van Europa. Om de wegen te onthouden zijn twee gegevens nodig: de coördinaten van punten en de verbindingen ertussen (dus welke punten met elkaar verbonden zijn). Elk kruispunt is een punt, maar soms zijn er tussen twee kruispunten ook extra punten nodig om de kromming van de weg te beschrijven. Een rotonde is een cirkel die uit een paar punten bestaat. Op sommige punten sluit een weg op de rotonde aan. Opdracht 4 Maak een schatting van het aantal punten dat in de wegendatabase van Europa staat. Beargumenteer te antwoord. In een navigatiecomputer zit tegenwoordig een microprocessor die met ongeveer 400 MHz werkt. Dat zijn dus meer dan 400 miljoen instructies per seconde. We gaan er voor de eenvoud even vanuit dat optellen, aftrekken, vermenigvuldigen, worteltrekken en het vergelijken van twee getallen eenvoudig instructies zijn die in 1 klokcyclus van de processor berekend kunnen worden. Voor de afstandsberekening met Pythagoras heb je dus zeker 7 instructies nodig.2 Opdracht 5 Hoe lang duurt het om de hele database te doorzoeken om het meest nabije punt te zoeken? Als je op de oprit staat en naar school wilt fietsen, moet het programma weten waar het moet beginnen op de landkaart. {to do: hoe lang duurt een wortelberekening echt?} Zou een sortering helpen? We hebben nog niets gezegd over de sortering van de database. Onze methode werkt dus altijd. Dus ook als de database niet gesorteerd is. Alleen zou het wel wat sneller mogen... Zouden we voordeel van een sortering kunnen hebben zoals bij binair search? Er is nog een ander probleem. Wat is sorteren in twee dimensies eigenlijk? Als je één rijtje getallen hebt, kun je die best in oplopende volgorde leggen. Maar hoe doe je dat bij punten met twee coördinaten? Opdracht 6 Denk nog eens terug aan het 'bos' van opdracht 1. Kun je de bomen in oplopende afstand sorteren? Stel dat je de volgende tien punten hebt: (0,0), (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9) De punten zijn in dit geval op zowel de x- als de y-coordinaat gesorteerd. Jij bevindt je op (1,9). Welk van de 10 punten is het dichtst bij? De berekening staat in de onderstaande tabel: punt x 1 y 9 lijst x 0 1 2 3 4 y 0 1 2 3 4 verschil x -1 0 1 2 3 verschil y -9 -8 -7 -6 -5 afstand 9.06 8.00 7.07 6.32 5.83 2 Dat is een heel erg grove vereenvoudiging van de werkelijkheid. Worteltrekken is een ingewikkelde berekening die zeker meer dan 1 klokcyclus duurt. Gelukkig heb je in opdracht 3 gezien dat je het berekenen van de wortel ook achterwege kunt laten. Bovendien zijn er nog extra instructies nodig om gegevens uit het geheugen in te lezen. 5 6 7 8 9 5 6 7 8 9 4 5 6 7 8 -4 -3 -2 -1 0 kleinste afstand 5.66 5.83 6.32 7.07 8.00 5.66 Er gloort hoop. Je kunt ten opzichte van je huidige positie de bomen in oplopend afstand sorteren. punt x 1 y 9 lijst x 5 4 6 3 7 2 8 1 9 0 y 5 4 6 3 7 2 8 1 9 0 verschil x verschil y 4 -4 3 -5 5 -3 2 -6 6 -2 1 -7 7 -1 0 -8 8 0 -1 -9 kleinste afstand afstand 5.66 5.83 5.83 6.32 6.32 7.07 7.07 8.00 8.00 9.06 5.66 Opdracht 7 Je staat nu op (2,2). Klopt de sortering van de bomen nog steeds? Omdat je vooraf niet weet t.o.v. van welke positie je de afstand gaat bepalen kun je deze sortering niet steeds hergebruiken. Vast ijkpunt Stel nu dat we van alle punten de afstand tot een vast punt kennen, zou dat helpen? Opdracht 8 Neem (0,0) als vast punt. Bereken de afstand van de drie bomen tot dit punt. Sorteer de punten in oplopend volgorde (Dit gebeurt vooraf en staat daarna in de database al vast vermeld). Bereken nu de afstand van jezelf tot het vaste punt. In de onderstaande afbeelding is jouw positie met de pijl aangegeven. De afstanden zijn t.o.v. de oorsprong berekend. Er zijn nog drie punten die (ongeveer) dezelfde afstand tot de oorsprong hebben, maar die punten liggen duidelijk niet het dichtst bij jouw punt. Als we nu geleidelijk de straal R van de binnenste cirkel kleiner maken en de straal r van de buitenste cirkel evenveel groter zullen er steeds meer punten binnen de cirkels vallen (We zorgen er voor dat ons punt steeds op de middencirkel van de ring blijft liggen). Telkens als er weer een punt binnen de ring valt berekenen we de afstand a tot ons punt. Opdracht 9 De dikte d van de ring is het verschil van de straal van de buitenste cirkel R en de straal van de binnenste cirkel r: d=R-r Kun je een criterium bedenken waarbij je d en de afstand a tot jouw punt vergelijkt en dan zeker weet of dit het dichtstbijzijnde punt is?3 In dit voorbeeld met slechts 12 punten moeten we nog steeds bijna alle punten doorlopen om het dichtstbijzijnde te vinden. Dat komt omdat de puntendichtheid (het aantal punten per oppervlakte) erg laag is. Bij een echte wegenkaart met heel veel punten hoeft de ring maar een beetje te worden uitgerekt om het dichtstbijzijnde punt te vinden. Je hoeft dus maar van een heel klein aantal punten de afstand tot jouw punt uit te rekenen. We vinden een punt als het op de rand van de ring valt. Dat is dus (gemiddeld) als de dikte van de ring net iets minder dan α is. Opdracht 10 We hebben als vast punt tot nu toe (0,0) genomen. Als de punten werkelijk overal kunnen liggen is dat een goede keuze. Is (0,0) ook een goede keuze voor het vaste punt als er alleen positieve x- en y-coördinaten voorkomen? Opdracht 11 Bedenk een regel om een geschikte positie voor het vaste punt te berekenen uit de posities van de punten. Samenvatting Wat moeten we allemaal doen op op deze manier sneller te kunnen zoeken. 1) klaar maken van de tabel 3 Het antwoord vind je verderop. Bereken de gemiddelde x- en y-coördinaat. Dit geeft dan de positie van het vaste punt. Bereken voor alle punten de afstand tot het vaste punt. Sorteer de punten oplopend op deze afstand. 2) doorzoeken van de tabel Je bevindt je op het punt (a,b). Bereken de afstand r tot het vaste punt. Zoek in de tabel een punt dat zich ook op een afstand r (of zo dicht mogelijk daarbij) bevindt. Als jouw afstand r tot het vaste punt 3,5 is, beginnen we in de onderstaande tabel bij punt 4. punt 1 2 3 4 5 6 7 afstand 2 3 3,3 3,5 3,7 4 4,5 Doorzoek nu alle punten die dichter en verder van het vaste punt af liggen. In de bovenstaande tabel gaan we dus verder met de punten 3 en 5, 2 en 6, etc. Bereken van elk punt de afstand. Het dichtstbijzijnde punt (met afstand s) toe dan toe wordt steeds onthouden. Zodra de afstanden in de tabel te veel verschillen met het startpunt kunnen we stoppen. Bij punt 1 en 7, is het verschil 4,5-2=2,5. Als de afstand van het dichtsbijzijn de punt 2,5/2=1,25 (of kleiner is) kunnen we stoppen. Een andere manier Het tweede idee is om het aardoppervlak in gebieden te verdelen. In elk gebied ligt een centraal punt. Alle punten in het gebied liggen niet verder dan (bijvoorbeeld) 1 km van dat centrale punt. Een punt dat wel verder dan 1 km van het centrale punt ligt, moet in een ander gebied liggen. Dat gebied heeft ook een centraal punt. Als je op deze manier de cirkels tegen elkaar aan legt zitten er stukje tussen de cirkel die nergens bij horen: De cirkels moeten elkaar dus overlappen. Je kunt zo’n gebieden met een passer mooi construeren. Begin met een cirkel met een straal van 4 cm. Zet de punt ergens op de rand van die cirkel en teken weer een cirkel met een straal van 4 cm. Op het snijpunt van de rode en de zwarte cirkel herhaal je dat, teken deze cirkel bijna onzichtbaar (hieronder groen). Op het snijpunt van de groene en de rode cirkel teken je weer een goed zichtbare (zwarte) cirkel. Tussen de snijpunten van de zwarte cirkels teken je verbindingslijnen. Als je dit recept verder uitbreidt, krijg je zwarte cirkels, waarin blauwe zeshoeken zitten. De zeshoeken zijn de gebieden. De middelpunten van de zwarte cirkels zijn de centrale punten. Opgave 12 Maar een mooie (computer-)tekening van deze cirkel met daarin een honingraat. Elke punt op de landkaart hoort precies bij 1 gebied. Bovendien is er een lijst met centrale punten. Algoritme Bepaal je positie (a,b) en zoek het centrale punt dat het dichtste bij jou in de buurt ligt. Bepaal daarna van alle punten in het gebied rond het centrale punt de afstand. Stel dat er 100 miljoen punten zijn en dat er in elk gebied (gemiddeld) 1000 punten liggen. Dan zijn er 100.000 gebieden. Daarvan is in gemiddeld 100.000 stappen te bepalen welk gebied we moeten hebben. Daarna moeten nog 1000 punten gecontroleerd worden. In totaal zijn dan 100.000 + 1000 = 101.000 zoekstappen. Als je minder gebieden kiest, zitten er gemiddeld meer punten in een gebied. Als het aantal gebieden g is, kun je het aantal zoekstappen zo opschrijven: g + 100.000.000/g Opgave 13 Kun je met wat wiskunde bepalen voor welke waarde van g je de minste zoekstappen nodig hebt (hint: differentiëren en daarna het minimum bepalen). Als het aantal punten in een gebied en het aantal gebieden gelijk is, heb je dus de minste zoekstappen nodig. Bij 100.000.000 punten maar 20.000. Uitgaande van 1ms per stap heb je 20s nodig. Dat is nog steeds te lang voor een TomTom. Misschien dat je daarom denkt dat we op de verkeerd weg zijn. Nu je het idee van ‘verdelen in gebieden’ begrijpt kunnen we een stap extra maken. Een gelijkzijdige driehoek is in 4 kleinere gelijkzijdige driehoeken te verdelen. Die kleinere driehoeken zijn ook weer in kleinere driehoeken te verdelen. Daar kun je een tijdje mee doorgaan. Opgave 14 Ga uit van een driehoek met zijde 10. De punt linksonder ligt bij (0,0). Ga er vanuit dat 1 zijde over de x-as loopt. Bereken/bepaal nu de coördinaten van de overige twee punten. Opgave 15 Nu je de coördinaten van de grote driehoek kent, kun je ook de coördinaten van de driehoek daarbinnen berekenen. Doe dat. Schrijf daarna van elk van de vier kleine driehoeken de coördinaten van de drie hoekpunten op. Elke driehoek heeft een zogenaamd zwaartepunt. De coördinaat daarvan is het gemiddelde van de coördinaten van de hoekpunten. Opgave 16 Bereken de coördinaten van het zwaartepunt van de driehoek uit opgave 14. Opgave 17 Een grote driehoek wordt in 4 kleinere driehoeken opgedeeld. Hoe bepaal je de driehoek waarin een punt ligt? Op deze manier kun je een oppervlak in een aantal stappen in hele kleine driehoeken opdelen. Bovendien heeft elke kleine driehoek een grotere ‘moeder’-driehoek. Die moeder heeft ook weer een moeder, etc. In de vorige opgaven heb je gezien hoe je uit de hoekpunten van een driehoek, de coördinaten van de hoekpunten van de kleinere driehoeken kunt berekenen. Door de afstand tot de zwaartepunten te berekenen kun je bepalen in welke driehoek je ligt. We kunnen de driehoeken op een hele gemakkelijke manier nummeren. De grootste driehoek krijgt geen nummer. De vier driehoeken daarin krijgen nummer 0,1, 2 en 3. De vier driehoeken binnen driehoek 0 krijgen nummer 00, 01, 02 en 03. Opgave 18 Begrijp je nu welke nummers de driehoeken binnen driehoek 2 krijgen? Ook voor de driehoeken die binnen driehoek 23 liggen gaat het schema zo verder: 230, 231, 232 en 233. Op deze manier weet je dus dat driehoek 23213 de volgende driehoek is: driehoek 3 binnen 1, binnen 2, binnen 3, binnen 2. De zijden van elke driehoek is de helft van die van 'haar moeder'. Stel dat je met een enorme driehoek begint, met een zijde van 40.000 km (de omtrek van de aarde, gemeten over de evenaar). De kinderen van deze driehoek hebben dan een zijde van 20.000 km. In de tabel kun je zien hoe het verder gaat. driehoek 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 zijde (km) 40.000 20.000 10.000 5.000 2.500 1250 625 312.5 156.25 78, 12 39,1 19,5 9,8 4,9 2,4 1,2 0,6 0,3 Dus in 16 stappen heb je driehoeken zo klein als een blok huizen. Binnen zo een blok van 300mx300m liggen niet zo heel erg veel punten. Zelfs als er om de 10m een punt ligt kunnen het er maximaal 30x30/2=450 zijn (gedeeld door 2 omdat het een driehoek is) Als we bovendien niet 16, maar 18 stappen maken, zijn de driehoeken nog maar 75m lang. Dat zijn maximaal 64 punten. Die 64 punten zijn snel in de database te vinden als je gebruik maakt van de namen van de driehoeken. Uitgaande van 18 niveau’s met driehoeken, zijn de namen van elke kleinste driehoekje 18 cijfers lang: bijvoorbeeld 1322012030110301. Voor de naam van punt nemen we nog 3 cijfers extra. Zo kunnen punt 000 to punt 999 maken. De punten in driehoek 1322012030110301 heten dan 1322012030110301000 tot en met 1322012030110301999. Zo hebben we elk punt een uniek nummer gegeven. De hele database is daarop te sorteren. Omdat je nu nog maar op één getal hoeft te sorteren kunnen we gewoon … binair zoeken! Dus na 18+64=80 zoekstappen weten welk punt het dichtstbij ligt. Dat kost ongeveer 80x0,025s=2s. Dus na 2s weet het programma welk punt het dichtste bij ons in de buurt ligt. Natuurlijk zijn er nog wat problemen om op te lossen, bijvoorbeeld: hoe past een gelijkzijdige driehoek op een halve bol? Een driehoek past immer niet mooi om een bol. We verdelen de aardbol om te beginnen in een aantal driehoeken (de zeshoeken in het tweede plaatje zijn ook in 6 driehoeken te verdelen. Voor de vijfhoeken los je dat niet zo eenvoudig op, helaas). twintig vlak afgeknot twintig vlak Antwoorden Opdracht 1 Doen Opdracht 2 Opdracht 3 Ja. Stel dat je de volgende afstanden hebt: 1,2,3. Dan staan de kwadraten van deze getallen in dezelfde volgorde: 1,4,9. In het algemeen: als a<b, dan is a2<b2 (Kun je dat bewijzen?) Opdracht 4 Zoek op internet Opdracht 7 Het klopt niet meer. De afstanden tot de tien punten zijn veranderd. punt x y 2 2 lijst x y 2 3 1 4 0 5 6 7 8 9 2 3 1 4 0 5 6 7 8 9 verschil x verschil y 0 0 1 1 -1 -1 2 2 -2 -2 3 3 4 4 5 5 6 6 7 7 kleinste afstand afstand 0.00 1.41 1.41 2.83 2.83 4.24 5.66 7.07 8.49 9.90 0.00 Dat had je ook meteen kunnen zien: (2,2) is één van de punten in de lijst. opdracht 9 Het eerste punt dat op de rand van de ring ligt en dan precies d/2 als afstand heeft is het dichtstbijzijnde punt. Opdracht 10 Als er alleen positieve coördinaten voorkomen ligt (0,0) niet meer ergens midden in de puntenwolk. Daarom is het dan een slechte keuze. Opdracht 11 Het vaste punt moet ergens midden in de wolk liggen. Je kunt een goede positie vinden door et gemiddelde van alle x-coördinaten, en het gemiddelde van alle y-coördinaten te bereken. Opgave 13 Het aantal zoekstappen y wordt gegeven door de formule yg 100.000.000 g ' 1100.0g020.000 differentiëren geeft y Voor y ' 0 vindt je de extremen (minima en maxima). Dus 1 100.000.000 g2 2 0, g 1 0 0 .0 0 0 .0 0 0, g 1 0 0 . 0 0 0 . 0 0 0 1 0 . 0 0 0 Als het aantal punten in een gebied en het aantal gebieden gelijk is heb je dus de minste zoekstappen nodig. Bij 100.000.000 punten maar 20.000. Uitgaande van 1ms per stap heb je maar 20s nodig. Opgave 17 Binnen 1 grote driehoek liggen 4 kleinere driehoeken. Die hebben elk een zwaartepunt. Bereken de afstand tot de 4 zwaartepunten. Het punt ligt binnen de driehoek waarvan het zwaartepunt het dichtstbij ligt. Opgave 18 De driehoeken binnen driehoek twee krijgen de volgende nummer: 020, 021, 022, 023