PH 트리
PH-tree| PH 트리 | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 유형 | 트리, 지도 | ||||||||||||||||||||
| 발명된 | 2014 | ||||||||||||||||||||
| 빅 O 표기의 시간 복잡도 | |||||||||||||||||||||
| |||||||||||||||||||||
PH-트리는[1] 지리 좌표, 점, 특징 벡터, 직사각형 또는 경계 상자 등 다차원 데이터(키)의 공간 인덱싱에 사용되는 트리 데이터 구조입니다.PH 트리는 쿼드 트리 [3]또는 옥트리와 유사한 구조를 가진 공간 분할[2] 인덱스입니다.단, 쿼드리와는 달리 시도 기반 분할 정책을 사용하며 키의 비트 표현을 기반으로 하는 Crit 비트 트리와 유사합니다.비트 기반 분할 정책은 노드에 대해 서로 다른 내부 표현을 사용할 때 고차원 데이터에 대한 확장성을 제공합니다.비트 표현 분할 정책도 최대 깊이를 요구하므로 트리 퇴화와 재조정 필요성을 [1]피할 수 있습니다.
개요
기본 PH 트리는 정수를 가진 d차원 벡터인 키를 사용자 정의 값에 매핑하는 공간 인덱스입니다.PH 트리는 Crit 가 1차원 키를 트리와 동등하다는 점에서 Crit 비트트리를 다차원적으로 일반화한 것입니다.Crit 비트 트리와 마찬가지로 다른 대부분의 공간 인덱스와 달리 PH 트리는 멀티맵이 [1][4]아닌 맵입니다.
d차원 PH-tree는 각 노드를 2 사분면으로 하여 공간을 분할하는 노드의 트리입니다(아래 참조).각 사분면에는 키-값 쌍(리프 사분면) 또는 키-서브노드 쌍 중 하나의 항목이 포함됩니다.키와 서브노드 쌍의 경우 키는 서브노드의 중심을 나타냅니다.키는 서브노드와 그 자 서브노드의 모든 키의 공통 프리픽스(비트 표현)이기도 합니다.각 노드에는 적어도2개의 엔트리가 있습니다.그렇지 않으면 부모 [1]노드와 Marge 됩니다.
PH-Tree의 다른 구조적 특성은 다음과 같다.[1]
- })-나무입니다.
- 이러한 키는 본질적으로 불균형하지만 깊이가 키의 비트 폭(예를 들어 32비트 정수의 d으로 제한되기 때문에 불균형이 제한됩니다.
- 삽입 또는 삭제 조작에 의해 정확히1개의 노드가 변경되어 두 번째 노드가 추가 또는 삭제될 가능성이 있습니다.이는 동시 구현에 유용합니다.이는 또한 수정 비용의 변동이 거의 없음을 의미합니다.
- 이들 구조는 삽입/제거 순서와는 무관합니다.
분할 전략
대부분의 쿼드리와 마찬가지로 PH 트리는 모든 노드가 모든 [1]d차원으로 공간을 분할하는 노드의 계층입니다.따라서 노드에는 최대 의d(\ 2의 서브노드를 사용할 수 있습니다(각 사분면에 1개).
사분면 번호부여부
PH 트리는 다차원 키의 비트를 사용하여 트리에서 해당 비트의 위치를 결정합니다.선두 비트가 같은 키는 모두 [1]트리의 같은 분기에 저장됩니다.
예를 들어 레벨 L의 노드에서는 키를 삽입(또는 삭제 또는 조회)할 필요가 있는 쿼드런트를 결정하기 위해 키의 각 치수의 L 비트를 조사합니다.8개의 사분면이 있는 3D 노드의 경우(입방체를 형성함) 키의 첫 번째 차원 L의 비트는 큐브의 왼쪽 또는 오른쪽에 있는지, 두 번째 차원의 L의 비트는 큐브의 앞 또는 뒤에 있는지, 세 번째 차원의 L의 비트는 아래 vs 위를 결정합니다.
1D 예시
8비트 값을 가진 3개의 1D 키가 있는 예: { 10 { } { _ { 0 }= \ { \ } base \ 2} , 1 = 10 { \{}=\{ k(\ k_{ k {1빈 트리에 추가하면 노드가 됩니다.두 키는 먼저 6번째 비트에서 다르므로 노드의 은 L ({ L0부터 시작))입니다.노드에는 양쪽 키의 공통 5비트를 나타내는5비트 프리픽스가 있습니다.노드에는 2개의 사분면이 있으며 각 키는 1개의 사분면에 저장됩니다.세 번째 를 추가하면 L ({ L에서 노드 하나가 추가되며, 하나는 원래 노드를 서브노드로 포함하고 다른 하나는 새 키 [citation needed]를 포함합니다.
2D 예시
2D 키를 사용하는 경우 모든 에는 4{디스플레이 2^{d}=4의 사분면이 키가 저장되는 사분면의 위치는 키의 각 비트에서, 각 치수에서 1비트를 추출합니다.노드의 4개 사분면은 2D 하이퍼 큐브를 형성합니다(사분면은 비어 있을 수 있습니다).키에서 추출된 비트는 hypercube h(k 0= h { 00 { k { \ h \ {\ }} 및 { \ { \ 01 \ displaystyle h } { \ 01 } ) { \ { \ h} h } { \ 02 { \ tyle h } { display h } { display h} {노드의 [citation needed]하이퍼큐브입니다
노드 구조
노드의 엔트리의 순서는 항상 Z 순서 뒤에 있습니다.예를 들어 노드의 엔트리는 크기가 인 크기배열에 저장할 수 있습니다h는 실질적으로 쿼드런트의 인덱스가 됩니다.따라서 O {O(를 하여 조회, 삽입 및 제거할 수 있으며 h를 저장할 필요가 없습니다. 공간 복잡도는 노드당O( {O(이므로 고차원 [1]데이터에는 적합하지 않습니다.
또 다른 솔루션은 동적 배열 및/또는 B-트리와 같은 정렬된 컬렉션에 엔트리를 저장하는 것입니다.이것에 의해, O「 e _ t ) ( \ O ( \ { n _ _ node \ _ } ) o oper oper oper oper oper oper oper oper oper oper this this this this this this this ( n d e _ n s[1] o o o o o o o o o o o o o o o o o o o o o o o o o로 메모리 소비량이 합니다.
최초의 실장에서는,[1] 어느 쪽이 메모리를 적게 사용하는지에 따라, 고정 어레이 표시와 동적 어레이 표시로 전환해, 메모리 소비를 최소한으로 억제하는 것을 목적으로 하고 있었습니다.기타 실장 [1][2]에서는 으로 전환되지 않지만 d use의 고정 d 동적 및 고차원 데이터의 경우 를 사용합니다.
운용
룩업, 삽입 및 삭제 조작은 모두 매우 비슷하게 동작합니다.올바른 노드를 찾아 해당 노드에서 조작을 수행합니다.윈도우 쿼리와 k-neighbor 검색은 더 복잡합니다.
찾다
조회 작업은 트리에 키가 있는지 여부를 확인합니다.트리를 내려가서 후보 서브노드 또는 [1]키에 일치하는 사용자 값이 포함되어 있는지 모든 노드를 체크합니다.
function lookup(key)은 entry = get_root_entry() // 트리가 비어 있지 않은 경우 루트 엔트리에 루트 노드가 포함되어 있습니다.한편 do node ← entry ← node.get_node(key) repeat return ent entry // 엔트리는 NIL일 수 있습니다.
함수 get_entry(key)는 노드 ← 현재 노드 h ← extract_bits_at_depth(key, node.get_depth() entry ← node.get_entry_at(h) return entry // 엔트리는 NIL일 수 있습니다.
삽입
키가 아직 존재하지 않는 한 삽입 작업은 새 키와 값 쌍을 트리에 삽입합니다.이 조작은 Lookup 함수처럼 트리를 통과하여 노드에 키를 삽입합니다.고려해야 [1]할 몇 가지 사례가 있습니다.
- 쿼드런트가 비어 있으므로 쿼드런트에 새 엔트리를 삽입하고 반환하기만 하면 됩니다.
- 쿼드런트에는 새 엔트리와 동일한 키를 가진 사용자 엔트리가 포함됩니다.이러한 충돌에 대처하는 방법 중 하나는 삽입에 실패했음을 나타내는 플래그를 반환하는 것입니다.트리가 노드의 엔트리로 컬렉션을 포함하는 멀티맵으로 구현될 경우 새 값이 해당 컬렉션에 추가됩니다.
- 쿼드런트에 다른 키를 가진 엔트리(사용자 엔트리 또는 서브노드 엔트리)가 포함됩니다.이 경우 기존 엔트리를 오래된 엔트리와 새로운 엔트리를 유지하는 새로운 서브노드로 교체해야 합니다.
함수 insert(노드, 키, 값) ← node.get_level() // root h ← extract_bits_at_level(키, 수준) ← node.get_entry(h) ← node == NIL 그 다음 // entry_new ← create_entry(키, 값) 노드의 경우 레벨이 0입니다.set_entry(h, entry_new) 그렇지 않으면 !entry.is_subnode() & & entry.get_key() == 키를 누른 후 // 케이스 2를 누릅니다.충돌, 이미 항목 반환 ← failed_diff else // case 3. level_diff ← get_level_of_relence(key, entry). entry_new ← 기존 엔트리와 새 엔트리가 있는 새 서브노드 ← create_node(level_diff, entry)node.set_entry(h, subnode_new)가 반환되면 종료됩니다.
제거한다.
삭제는 삽입과 반대로 동작하며, 엔트리가 2개 미만인 경우 서브노드를 삭제해야 한다는 추가 제약이 있습니다.나머지 엔트리는 부모 [1]노드로 이동합니다.
윈도 쿼리
Windows 쿼리는 직사각형 축으로 정렬된 하이퍼박스 내에 있는 모든 키를 반환하는 쿼리입니다.쿼리 상자의 "왼쪽 하단" 및 "오른쪽 상단" 모서리를 나타내는 2개의 d차원 최소 m 최대로 정의할 수 있습니다.간단한 실장은 노드 내의 모든 엔트리를 통과합니다(루트노드부터 시작). 엔트리가 일치하면 결과 목록에 추가하거나(사용자 엔트리인 경우), 재귀적으로 통과합니다(서브노드인 [1]경우).
기능 cm는foreach 진입 ← node.get_entries()더라도 entry.is_subnode()다면 entry.get_prefix()>)분, entry.get_prefix()<>)max 다음 query(entry.get_subnode(),분, max, result_list) 끝나면 다른 만약 entry.get_key()>)분, entry.get_key()<>)max. result_list.add(엔트리) end if end if repeat return if
시간의 복잡성을 정확하게 추정하기 위해 분석에는 치수 d d 를 트래버스 및 비교할 필요가 있습니다의 는 d입니다entries은 d d 차원 키를 n/과 할마다 (min 이 소요되기 입니다노드에는 의 d 2개의 엔트리를 포함할 수 있으므로 에 따라 적절히 확장되지 않습니다하이퍼큐브 주소 [4]h를 사용함으로써 이 접근 방식을 개선할 수 있는 방법은 다양합니다.
최소 시간 및 최대 시간
쿼드런트의 주소의 최소값과 하여 쿼드런트가 쿼리 박스와 겹치지 않도록 합니다C C를 노드의 중심(노드의 프리픽스와 동일)으로 n({})과 m a x를 각각 d d의 2비트 문자열로 .또한, 첨자 ii< 0≤과{\displaystyle 나는}, d{\displaystyle 0\leq i<, d}ih의{\displaystyle 나는}좀 나는}과 h m x{\displaystyle h_{맥스}}이고, mi{\displaystyle 나는}'th 차원{\displaystyle분}의{\displaystyle h_{분}의 스녀 m, m x{\disp을 나타낸다.laystmax C {\ C 입니다.
n ( n ) ({ h _ { } = ( _ { \ C _ {} ) h a , ( i = ( style h { , i } \ = ( i } \ ) ( max _ i )\ ) c c c m )) 。ll 사분원이 쿼리 상자와 겹치지 않습니다.마찬가지로 h n{ h { } 、 「 """ does does does does does 」의 반쪽이 쿼리 박스와 겹치지 않는 모든 치수에 { 0}이 표시됩니다.
으로 h (\min}) m 를 합니다.< h < h { } > > { max} 의 사분원은 쿼리 박스와 교차하지 않습니다.증명은 [4]다음에서 입수할 수 있습니다.이를 통해 위의 쿼리 기능을 다음과 같이 개선할 수 있습니다.
함수 쿼리(node, min, max, result_list)는 h_min ← 계산h_min h_max ← 각 엔트리에 대해 계산h_max ← 계산h_max ← node.get_min_range(h_min, h_max) do [...] 반복 반환
n(\ h x(\의 은O ( ( (\O ()=O 입니다.이 접근방식은 노드 내에서 점유된 사분면의 분포에 따라 거의 모든 키 비교를 피할 수 있습니다.이렇게 하면 평균 트래버설 시간이 단축되지만 복잡도는 + d d O[4]가 됩니다.
쿼드런트가 쿼리 상자와 겹치는지 확인합니다.
n({ ~ m ({ 에는 쿼리 박스와 겹치지 않는 사분면이 존재할 수 있습니다.Idea: and each have one bit for every dimensions that indicates whether the query box overlaps with the lower/upper half of a node in that dimension.이 기능을 사용하여 의중복 여부를 빠르게 확인할 수 있습니다차원 키를 할 필요가 없습니다.는쿼드런트h와 중복됩니다.예를 들어의 각 에 대응하는 값이 00일 경우 쿼드런트h와 중복됩니다. 0 비트 h n(\ 및 h h 비트에 하는(\1)비트가 x(\에 있습니다.따라서 64비트 레지스터를 가진 CPU에서는 오버랩을 체크할 수 있습니다. 64 치수 키 ){O([4]
함수 is_subrant(h, h_min, h_max)는 반환(h h_min) & h_max == h // 사분면과 쿼리가 겹치면 'true'로 평가됩니다.
함수 쿼리(node, min, max, result_list)는 h_min ← calculate h_min h_max ← calculate h_max ← calculate h_max ← node.get_max (h_min, h_max) do h ← entry.get_h() 입니다. (h)의 경우 쿼리와 오버랩이 반환되는 경우 true로 평가됩니다.
그 결과 시간의 은 O + e n t O와 전체 [4]반복의 Od style _ s O와 됩니다.
쿼리 상자와 겹치는 사분원 이동
노드가 큰 고차원의 경우 모든 h에서 반복되지 않고 쿼리 상자와 겹치는 다음 h를 직접 계산할 수도 있습니다.첫 번째 단계에서는 쿼리 박스와 겹치지 않는 모든 사분면에 1}) 비트를 지정된 n t({})에 넣습니다.두 번째 단계는 된와 추가된 1) 비트를 증가시켜 오버랩되지 않는 사분원을 건너뛸 수 있도록 오버플로를 트리거합니다.마지막 단계에서는 오버플로우 트리거에 사용되는 모든 바람직하지 않은 비트를 제거합니다.로직은 [4]에 자세히 설명되어 있습니다.계산은 다음과 같이 이루어집니다.
함수 increment_h(h_input, h_min, h_max)는 h_out = h_input (~h_max ) // pre - mask h_out + = 1 // increment h_out = ( h_out & h_max ) // post - mask returnut h_out
d 64{ d 64}의 경우 O( ){ O (1의 대부분의 CPU에서 이 작업을 수행할 수 있습니다.노드를 통과하는 시간의 복잡도는 O + e a s O[4]입니다.쿼리 상자와 겹치는 사분면의 대부분이 엔트리에 점유되어 있는 경우에 가장 적합합니다.
k-param 네이버
k 가장 가까운 네이버 검색은 표준 [5]알고리즘을 사용하여 구현할 수 있다.
부동 소수점 키
PH 트리는 정수 값만 저장할 수 있습니다.부동소수점 값은 정수로 저장할 수 있습니다.그러나 의 저자들은 정밀도 [1][4]손실 없이 접근법도 제안한다.
무손실 전환
부동소수점 값의 32비트 또는 64비트를 단순히 정수(32비트 또는 64비트)로 해석함으로써 정밀도를 달성할 수 있는 경우 부동소수점 값을 무손실(및 백)으로 변환합니다.IEEE 754가 부동소수점 값을 인코딩하는 방식에 따라 적어도 양의 값에 대해 결과 정수 값은 원래의 부동소수점 값과 동일한 순서를 가집니다.비부호 [1][4]비트를 반전시킴으로써 음수 값의 순서를 설정할 수 있습니다.
Java에서의 구현 예:
long encode(이중값) { long r = Double.ToRawLongBits(값); return (r > = 0) ?r : r ^ 0x7FFFFFFFFFF; } C++에서의 실장 예:
std::int64_t encode(이중값) { std::int64_t r; memcpy(&r, &value, sizeof(r)), r >= 0 ?r : r ^ 0x7FFFFFFFF;}를 반환합니다. 부호화(및 역디코딩)는 모든 부동소수점 값에 대해 무손실입니다.이 순서는 ± \infty및 0(\ 등 실제로는 잘 작동하지만 정수 표현은 을 N NaN으로 하고 무한대는 서로 비교 가능하며 -0.0은 더 큽니다. 0.0[6]보다 작습니다.즉, 예를 들어 쿼리범위 [0 00])는 -0.00의과 일치하지 않습니다({을일치시키려면 쿼리 범위가[-0, 0[citation needed]이어야 합니다.
하이퍼박스 키
로 건반, 구현 일반적으로-dimensional 최소 점 수 및 상자의 최대의 모서리{\displaystyle d}2∗ d와 치수{2*d\displaystyle}예를 들어 단일 키로 끼워 넣기로써 두 d로 변환합니다 코너 representation[7]을 사용하기 위해 저장하기 위해 볼륨:k={m나의 0,인데 m(axis-aligned hyper-boxes)0 , x1 ,., m n - , - } displaystyle k= \ { { , _ { 1 }_ { { } ,_ { d- 1) 。
이것은 조회, 삽입 및 제거 작업에 대해 세 가지 방법으로 작동합니다.윈도우 쿼리는 dd-dimensional 에서 2 d_-dimensional 로 변환해야 합니다.예를 들어 조회 상자 안에 완전히 있는 모든 상자에 일치하는 창 조회의 경우 조회 키는 다음과 같습니다.[7][8]
쿼리 상자와 교차하는 모든 상자에 일치하는 창 쿼리 작업의 경우 쿼리 키는 다음과 같습니다.[8]
확장성
엔트리가 인 고차원에서는 PH 트리에 노드가1개밖에 없어 사실상 Z차 곡선의 B-Tree로 '전락할 수 있습니다.추가/삭제/조회 조작은 O인 로(\ { 윈도우 쿼리는 쿼드런트필터를 사용할 수 있습니다.그러나 d d d { d인 고차원 데이터의 경우 PH 트리가 전체 [9]스캔보다 약간만 우수합니다.
사용하다
연구 결과,[10] 크고 빠르게 변화하는 데이터셋에 대한 빠른 추가/제거/정확한 일치 작업이 보고되었습니다.창 쿼리는 특히 작은[11] 창 또는 큰 데이터[12] 세트에 잘 작동하는 것으로 나타났습니다.
PH 트리는 주로 메모리 내 [10][13][14]사용에 적합합니다.노드의 크기(엔트리 수)는 고정되어 있지만 영속적인 스토리지는 구성 가능한 노드 크기를 가진 인덱스의 이점을 활용하여 노드의 크기를 디스크의 페이지 크기에 맞추는 경향이 있습니다.이것은 R-Tree와 같은 다른 공간 인덱스를 사용하면 더 쉽습니다.
실장
- Java: 오리지널 발명가의 GitHub 저장소
- C++: 오리지널 발명가의 GitHub 저장소
- C++: GitHub 저장소
- C++: GitHub 저장소
「 」를 참조해 주세요.
레퍼런스
- ^ a b c d e f g h i j k l m n o p Zäschke, Tilmann; Zimmerli, Christoph; Norrie, Moira C. (June 2014). "The PH-tree: a space-efficient storage structure and multi-dimensional index". Proc. 2014 ACM SIGMOD International Conference on Management of Data: 397–408. doi:10.1145/2588555.2588564. ISBN 9781450323765. S2CID 6862850. Retrieved 10 February 2022.
- ^ Kouahla, Z.; Benrazek, A.-E.; Ferrag, M. A.; Farou, B.; Seridi, H.; Kurulay, M.; Anjum, A.; Asheralieva, A. (2022). "Survey on Big IoT Data Indexing: Potential Solutions, Recent Advancements, and Open Issues". Future Internet. 14 (1): 19. doi:10.3390/fi14010019.
- ^ Mahmood, A. R.; Punni, S.; Aref, W. G. (2018). "Spatio-temporal access methods: a survey (2010 – 2017)". Geoinformatica. 23 (1): 1–36. doi:10.1007/s10707-018-0329-2. S2CID 106407322.
- ^ a b c d e f g h i j Zäschke, Tilmann; Norrie, Moira (2017). "Efficient Z-Ordered Traversal of Hypercube Indexes". Lecture Notes in Informatics (LNI). P-265 (Datenbanksysteme für Business, Technologie und Web (BTW 2017)): 465–484. doi:10.3929/ethz-a-010802003.
- ^ Hjaltason, Gísli R.; Samet, Hanan (June 1999). "Distance browsing in spatial databases". ACM Transactions on Database Systems. 24 (2): 265–318. doi:10.1145/320248.320255. S2CID 10881319. Retrieved 12 February 2022.
- ^ IEEE 754 2019
- ^ a b Seeger, B.; Kriegel, H. P. (1988). "Techniques for Design and Implementation of Efficient Spatial Access Methods". Proceedings 1988 VLDB Conference: 14th International Conference on Very Large Data Bases. 14: 360.
- ^ a b Samet, Hanan (2006). Foundations of multidimensional and metric data structures. San Francisco: Elsevier/Morgan-Kaufmann. pp. 440–441, 453–457. ISBN 0-12-369446-9.
- ^ Li, Yan; Ge, Tingjian; Chen, Cindy (2020). "Online Indices for Predictive Top-k Entity and Aggregate Queries on Knowledge Graphs". 2020 IEEE 36th International Conference on Data Engineering (ICDE): 1057–1068. doi:10.1109/ICDE48307.2020.00096. ISBN 978-1-7281-2903-7. S2CID 218907333.
- ^ a b Sprenger, Stefan (2019). "Efficient Processing of Range Queries in Main Memory". doi:10.18452/19786.
{{cite journal}}:Cite 저널 요구 사항journal=(도움말) - ^ Khatibi, A.; Porto, F.; Rittmeyer, J. G.; Ogasawara, E.; Valduriez, P.; Shasha, D. (August 2017). "Pre-processing and indexing techniques for constellation queries in big data" (PDF). International Conference on Big Data Analytics and Knowledge Discovery. Lecture Notes in Computer Science. 10440: 164–172. doi:10.1007/978-3-319-64283-3_12. ISBN 978-3-319-64282-6. S2CID 3857469.
- ^ Winter, C.; Kipf, A.; Anneser, C.; Zacharatou, E. T.; Neumann, T.; Kemper, A. (2020). "GeoBlocks: A Query-Cache Accelerated Data Structure for Spatial Aggregation over Polygons". EDBT. 23: 169–180. doi:10.5441/002/edbt.2021.16.
- ^ Wang, S.; Maier, D.; Ooi, B. (2016). "Fast and Adaptive Indexing of Multi-Dimensional Observational Data". Proceedings of the VLDB Endowment. 9 (14): 1683. doi:10.14778/3007328.3007334.
- ^ Herrera, Stiw; da Silva, Larissa Miguez; Reis, Paulo Ricardo; Silva, Anderson; Porto, Fabio (2021). "Managing Sparse Spatio-Temporal Data in SAVIME: an Evaluation of the PH-tree Index". Anais do XXXVI Simpósio Brasileiro de Bancos de Dados: 337–342. doi:10.5753/sbbd.2021.17895. S2CID 245185935.