R-träd | |||||||
---|---|---|---|---|---|---|---|
Sorts | Flerdimensionellt träd Binärt sökträd | ||||||
Uppfinningens år | 1984 | ||||||
Författare | Antonin Guttman | ||||||
Komplexitet i O-symboler | |||||||
|
|||||||
Mediafiler på Wikimedia Commons |
R-tree ( Eng. R-trees ) är en trädliknande datastruktur ( tree ), föreslagen 1984 av Antonin Guttman . Det liknar ett B-träd , men används för att komma åt rumslig data, det vill säga för att indexera flerdimensionell information , såsom geografiska data med tvådimensionella koordinater ( latitud och longitud ). En typisk fråga med R-träd kan vara: "Hitta alla museer inom 2 kilometer från min nuvarande plats."
Denna datastruktur delar upp ett flerdimensionellt utrymme i en uppsättning hierarkiskt kapslade och möjligen korsande rektanglar (för ett tvådimensionellt utrymme). I fallet med tredimensionellt eller flerdimensionellt utrymme kommer dessa att vara rektangulära parallellepipeder ( kuboider ) eller parallellotoper .
Algoritmerna för insättning och borttagning använder dessa begränsningsrutor för att säkerställa att "nära" objekt placeras på samma bladvertex. I synnerhet kommer det nya objektet att träffa bladets topp som behöver den minsta expansionen av sin begränsningsruta. Varje bladnodelement lagrar två datafält: ett sätt att identifiera de data som beskriver objektet (eller själva datan) och begränsningsrutan för detta objekt.
På liknande sätt använder sökalgoritmer ( t.ex. korsning, inkludering, grannskap) begränsningsrutor för att bestämma om de ska söka i en undernod. De flesta av hörnen berörs alltså aldrig under sökningen. Precis som med B-träd gör denna egenskap hos R-träd dem lämpliga för databaser , där hörn kan bytas ut till disk efter behov.
För att dela upp översvämmade hörn kan olika algoritmer användas, vilket leder till uppdelningen av R-träd i undertyper: kvadratiska och linjära.
Inledningsvis garanterade inte R-träd bra prestanda i värsta fall , även om de fungerade bra på riktiga data. Men 2004 publicerades en ny algoritm som bestämmer prioriterade R-träd . Det hävdas att denna algoritm är lika effektiv som de mest effektiva moderna metoderna, och samtidigt är optimal för värsta fall [1] .
Varje hörn av R-trädet har ett variabelt antal element (inte mer än något förutbestämt maximum). Varje element i en icke-bladspunkt lagrar två datafält: ett sätt att identifiera den underordnade vertexen, och en begränsningsruta (kuboid) som omsluter alla element i den underordnade vertexen. Alla lagrade tuplar lagras på samma djupnivå, så trädet är perfekt balanserat. När du designar ett R-träd måste du ställa in några konstanter:
För att algoritmerna ska fungera korrekt måste villkoret MinEntries <= MaxEntries / 2 uppfyllas. Rotnoden kan ha från 2 till MaxEntries avkomlingar. Ofta väljs MinEntries = 2, då är samma villkor uppfyllda för roten som för resten av hörnen. Det är också ibland klokt att avsätta separata konstanter för antalet punkter i bladens hörn, eftersom du ofta kan göra fler av dem.
Konstruktionen av ett R-träd sker som regel genom att upprepade gånger anropa operationen att infoga ett element i trädet. Idén med infogning liknar infogning i ett B-träd : om att lägga till ett element till nästa vertex resulterar i ett spill, då delas vertexet. Nedan är den klassiska infogningsalgoritmen som beskrivs av Antonin Guttman .
Infoga funktionOlika algoritmer kan användas för att separera hörn, detta är en av dem. Den har bara linjär komplexitet och är lätt att implementera, även om den inte ger den mest optimala separationen. Praxis visar dock att en sådan komplexitet vanligtvis är tillräcklig.
Ibland, istället för ett R-träd, används det så kallade cR-trädet (c står för clustered ). Grundidén är att klustringsalgoritmer som k-medel används för att separera hörn eller punkter . Komplexiteten hos k-medel är också linjär, men i de flesta fall ger den ett bättre resultat än den linjära Guttman-separationsalgoritmen, i motsats till vilken den inte bara minimerar den totala arean av lådornas kuvert, utan också avståndet mellan dem och överlappningsområdet. För punktklustring används det valda måttet för det ursprungliga utrymmet; för vertexklustring kan du använda avståndet mellan mitten av deras envelopper av parallellepipederna eller det maximala avståndet mellan dem.
Klustringsalgoritmer tar inte hänsyn till det faktum att antalet avkomlingar till en vertex begränsas uppifrån och under av algoritmens konstanter. Om klusterdelningen ger ett oacceptabelt resultat kan du använda den klassiska algoritmen för denna uppsättning, eftersom detta inte händer ofta i praktiken.
En intressant idé är att använda klustring i flera kluster, där flera kan vara fler än två. Det bör dock beaktas att detta medför vissa begränsningar för parametrarna för p-trädstrukturen.
Observera att förutom cR-trädet finns dess variation clR-träd baserat på klustringsmetoden, där en iterativ algoritm för att lösa "placeringsproblemet" används som centrum. Algoritmen har en kvadratisk beräkningskomplexitet, men tillhandahåller konstruktionen av mer kompakta envelopper av parallellepipeder i strukturvertexposterna.
Att söka i ett träd är ganska trivialt, du behöver bara ta hänsyn till det faktum att varje punkt i rymden kan täckas av flera hörn.
Denna algoritm [2] tar bort någon post E från R-trädet. Algoritmen består av följande steg:
FindLeaf-funktion
Låt T vara roten till trädet och låt E vara den önskade posten.
CondenseTree funktion
Låt post E raderas från blad L. Sedan är det nödvändigt att eliminera noden som har få poster kvar (mindre än MinEntries) och flytta dess poster. När du flyttar upp i trädet, om nödvändigt, radera poster (med samma kriterier). På vägen till roten, räkna om rektanglarna, gör dem så små som möjligt. Algoritmen beskrivs nedan. Denna funktion kan också implementeras med hjälp av rekursion.
Träd (datastruktur) | |
---|---|
Binära träd | |
Självbalanserande binära träd |
|
B-träd | |
prefix träd |
|
Binär uppdelning av utrymme | |
Icke-binära träd |
|
Bryter upp utrymmet |
|
Andra träd |
|
Algoritmer |