KD-Tree vs. Quadtree yang sepenuhnya dinamis?

11

Mengerjakan permainan saya, saya berada pada titik di mana saya perlu melacak semua unit di dunia sehingga saya dapat melakukan pemeriksaan tetangga terdekat untuk pertempuran. Ini adalah permainan seperti RTS, dengan kemungkinan ribuan unit otomatis kecil bergerak.

Saya telah mencari di KD-Trees dan Quadtrees (terutama Point Quadtrees). Saya masih mencoba mempelajari detail cara kerjanya, tetapi sejauh ini Point Quadtrees paling masuk akal bagi saya. Namun, saya mendapat kesan bahwa KD-Trees lebih cepat untuk mencari, yang penting dengan jumlah poin yang saya miliki di pohon.

Di sisi lain, dalam kasus saya, saya akan melacak sejumlah besar unit yang selalu bergerak. Dari bingkai ke bingkai, posisi mereka akan selalu berbeda. Quadtrees tampaknya lebih cepat untuk menyeimbangkan kembali daripada KD-Trees, tapi saya tidak tahu apakah itu berlaku ketika Anda menyeimbangkan kembali setiap titik di pohon.

Saya bertanya-tanya apakah akan lebih baik dalam hal ini untuk hanya memotong pohon setiap frame dan membangunnya kembali dari awal, daripada mencoba untuk menyeimbangkan kembali setiap titik di pohon? Jika Quadtree lebih cepat menyeimbangkan kembali, apakah itu juga berarti lebih cepat untuk membangun dari awal? Jika demikian, itu mungkin lebih penting untuk kinerja daripada kecepatan pencarian KD-Tree, tergantung pada seberapa banyak beban untuk membuat pohon, tapi saya tidak tahu ...

Nairou
sumber

Jawaban:

12

KD-tree secara definitif tidak cukup dinamis untuk dipertimbangkan, jujur. Memindahkan beberapa unit dengan mudah mengharuskan Anda membangun kembali seluruh KD-Tree. Plus, KD-tree sangat efisien untuk query, tetapi tidak terlalu banyak untuk pencarian tetangga.

Quadtree lebih fleksibel dari waktu ke waktu, karena modifikasi disimpan lebih lokal. Kerugiannya adalah bahwa jika Anda memiliki banyak unit di satu tempat yang sering bergerak, itu mungkin membagi terlalu banyak dan memerlukan banyak pembaruan karena pergerakan unit. Anda dapat menetapkan ambang di mana, tidak ada subdivisi yang dapat terjadi. Namun berhati-hatilah, itu menyiratkan banyak unit berpotensi berada di leaf square yang sama.

Namun jika Anda hanya tertarik untuk menemukan semua unit dalam radius konstan r , Anda tidak perlu quadtree dan kd-tree segera. Anda cukup membuat array 2D sel sisi panjang r dan menumpuk unit Anda di setiap sel sesuai dengan posisinya. Dengan begitu, Anda selalu memiliki paling tidak 9 sel untuk dicari. Hanya jika peta Anda besar , grid seperti itu akan terlalu besar untuk diimplementasikan.

Ada dua struktur yang sama sekali berbeda yang tidak kami bicarakan: AABB hierarkis dan tabel hash yang sensitif terhadap lokal. Jika asal dari masing-masing AABB hierarkis dijelaskan relatif terhadap AABB induk, itu memiliki keuntungan bahwa jika sekelompok besar unit mempertahankan formasinya, maka Anda tidak perlu memperbarui AABB yang lebih kecil karena mereka mempertahankan posisi relatif yang sama. Tentu saja, memutar formasi dapat menyebabkan banyak pembaruan, dalam hal ini penggunaan volume pembatas lain seperti bola atau kotak pembatas berorientasi (OBB) mungkin lebih efisien.

Tabel hash lokal-sensitif hanya memberikan solusi perkiraan secara efisien, jadi saya tidak akan repot dengan mereka.

Apa yang akan saya lakukan? Saya mungkin akan mulai dengan kisi-kisi sederhana, dan ketika saya membutuhkannya, saya akan memutakhirkannya ke quadtree dan jika saya membutuhkannya, saya akan menggabungkannya dengan hierarki volume yang terikat di bawah beberapa ambang batas: quadtrees bekerja dengan baik pada umumnya skala, volume pembatas relatif bekerja dengan baik pada skala kecil. Melakukannya secara bertahap, saya tidak perlu menghabiskan waktu dari awal untuk mendapatkan struktur data terbaik dengan segera .

Lærne
sumber
Terima kasih! Saya belum pernah mendengar tentang AABB hierarkis dan tabel hash yang peka terhadap lokal, saya akan mencari mereka untuk masa depan. Untuk saat ini saya akan menggunakan kotak sederhana dan akan berkembang jika diperlukan, seperti yang Anda sebutkan. :)
Nairou
4

Saran Lærne sangat bagus, tetapi saya juga akan menyarankan pohon volume dinamis AABB. Secara konseptual, dynamic volume bounding tree menyimpan pohon node yang seimbang yang dapat ditanyakan kapan saja untuk elemen-elemen dekat dengan melewatkan AABB dan mengambil pasangan yang tumpang tindih. Pohon itu tidak dibangun kembali setiap frame. Sebaliknya AABB setiap node sedikit meningkat ketika dimasukkan ke dalam pohon, dan pohon hanya dibangun kembali setiap kali AABB aktual node tidak lagi terkandung oleh AABB meningkat. Saya menggunakannya di mesin fisika saya dan bekerja dengan sangat baik.

Kode sumber Box2D memiliki implementasi yang hebat.

https://github.com/erincatto/Box2D/blob/master/Box2D/Box2D/Collision/b2DynamicTree.h

Berikut ini adalah ulasan yang baik tentang implementasi mereka:

http://www.randygaul.net/2013/08/06/dynamic-aabb-tree/

Steven
sumber
Ya, kurang lebih itu yang saya maksud dengan AABB hierarkis, saya tidak begitu tepat. Oh, dan di unit RTSes sering mobile, tetapi dalam formasi. Jadi menggunakan koordinat relatif terhadap simpul AABB induk bisa sangat efisien, dengan margin kesalahan "inflasi".
Lærne
Bisakah Anda memperbarui tautan kode Google?
kolenda