Yinelenen dörtlü


10

Ben bir dörtlü uyguluyorum. Bu veri yapısını bilmeyenler için aşağıdaki küçük açıklamayı ekliyorum:

Bir Quadtree bir veri yapısıdır ve Öklid düzleminde bir Octree'nin 3 boyutlu bir uzayda ne olduğudur. Quadtrees'in yaygın kullanımı mekansal indeksleme.

Nasıl çalıştıklarını özetlemek için, bir dörtlü, maksimum kapasiteye ve bir ilk sınırlama kutusuna sahip bir koleksiyon - burada dikdörtgenler diyelim -. Bir elemanı maksimum kapasitesine ulaşmış olan bir dörtlü ağaç içine eklemeye çalışırken, dörtlü ağaç 4 dörtlü parçaya bölünür (geometrik temsili yerleştirilmeden önce ağaçtan dört kat daha küçük bir alana sahip olacaktır); her bir eleman, alt ağaçlara konumuna göre, yani yeniden dağıtılır. üst sol dikdörtgenle çalışırken sınırlıdır.

Yani dörtlü bir yapraktır ve kapasitesinden daha az elemente veya çocuk olarak 4 dörtlü (genellikle kuzey-batı, kuzey-doğu, güney-batı, güney-doğu) bir ağaca sahiptir.

Benim endişem, yinelenenleri eklemeye çalışırsanız, aynı öğe birkaç kez veya aynı konumda birkaç farklı öğe olabilir, dörtlü kenarların işlenmesi ile ilgili temel bir sorun vardır.

Örneğin, sınırlama kutusu olarak 1 kapasiteye sahip bir dörtlü ve birim dikdörtgeniyle çalışıyorsanız:

[(0,0),(0,1),(1,1),(1,0)]

Ve sol üst sınırı başlangıç ​​noktası olan bir dikdörtgeni iki kez eklemeyi denersiniz: (veya benzer şekilde N> 1 kapasiteli bir dörtlüğe N + 1 kez eklemeyi denerseniz)

quadtree->insert(0.0, 0.0, 0.1, 0.1)
quadtree->insert(0.0, 0.0, 0.1, 0.1)

İlk kesici uç sorun olmayacak: İlk kesici uç

Ama sonra ilk ekleme bir alt bölümü tetikleyecektir (çünkü kapasite 1'dir): İkinci kesici uç, ilk altbölüm

Böylece her iki dikdörtgen de aynı alt ağaçta yer alır.

Sonra tekrar, iki element aynı dörtlü olarak gelecek ve bir alt bölümü tetikleyecektir… İkinci kesici uç, ikinci altbölüm

Ve böylece, vb. Alt bölümleme yöntemi süresiz olarak çalışacaktır çünkü (0, 0) her zaman yaratılan dördün aynı alt ağacında olacaktır, yani sonsuz bir yineleme problemi meydana gelir.

Çiftleri olan bir dörtlü olması mümkün mü? (Değilse, kişi a olarak uygulanabilir Set)

Bir dörtlü mimarisini tamamen bozmadan bu sorunu nasıl çözebiliriz?


Nasıl davranmasını istersiniz? Uygulıyorsunuz, bu nedenle sizin için hangi davranışın doğru olduğuna karar vermelisiniz. Belki her benzersiz koordinat, bu koordinattaki öğelerin bir listesi olabilir. Belki puanlarınız benzersiz olmakla sınırlıdır. Neye ihtiyacın olduğunu biliyorsun, biz bilmiyoruz.
Yararsız

@Useless Bu çok doğru. Ancak konuyla ilgili oldukça fazla araştırma yapılmış olmalı ve tekerleği de yeniden icat etmek istemiyorum. TBH hala bu soru ... daha çok üzerinde, programmers.SE üzerinde, gamedev.SE üzerinde ve hatta math.SE üzerinde ait olup olmadığını bilmiyorum
Pierre Arlaud

Yanıtlar:


3

Bir veri yapısı uyguluyorsunuz, bu yüzden uygulama kararları vermelisiniz.

Dörtlü, benzersizlik hakkında söyleyecek özel bir şey olmadığı sürece - ve bunun farkında değilim - bu bir uygulama kararıdır. Bir dörtlü tanımına diktir ve istediğiniz gibi işlemeyi seçebilirsiniz. Dörtlü, anahtarları nasıl ekleyeceğinizi ve güncelleyeceğinizi söyler, ancak benzersiz olmaları ya da her bir düğüme ne ekleyebileceğiniz konusunda bilgi vermez.

Uygulama kararları vermek tekerleği yeniden icat etmek değildir , en azından kendi uygulamanızı en başta yazmaktan başka bir şey değildir.

Karşılaştırma için, C ++ standart kütüphanesi benzersiz bir set, benzersiz olmayan bir çoklu set, benzersiz bir harita (aslında sadece anahtarla sipariş edilen ve karşılaştırılan bir dizi anahtar / değer çifti) ve benzersiz olmayan bir çoklu harita sunar. Hepsi aynı kırmızı-siyah ağaç kullanılarak uygulanır ve hiçbiri mimariyi bozmaz , çünkü kırmızı-siyah ağacın tanımının tuşların benzersizliği veya yaprak düğümlerinde saklanan türler hakkında söyleyecek bir şeyi yoktur.

Son olarak, bu konuda bir araştırma olduğunu düşünüyorsanız, onu bulun ve sonra tartışabiliriz. Belki de göz ardı ettiğim dörtlü değişmez veya daha iyi performans sağlayan bazı ek kısıtlamalar vardır.


Benim sorunum, benzersizliğin bir gereklilik olduğunu belirten herhangi bir belge bulamıyorum. Ancak, örneğimi gördüyseniz, aynı öğeyi birkaç kez eklerseniz bunun gerçek bir sorun olduğunu görebilirsiniz.
Pierre Arlaud

Ağaç tür yapıları için, değere sahip düğüme bazen yinelenenleri arttıran ve azaltan bir "sayım" alanı verilmez mi?
J Trana

2

Bence burada yanlış anlaşılma var.

Anladığım kadarıyla, her dörtlü düğüm bir nokta ile dizinlenmiş bir değer içerir. Başka bir deyişle, üçlü (x, y, değer) içerir.

Ayrıca, boş olabilen alt düğümlere 4 işaretçi içerir. Anahtarlar ve alt bağlantılar arasında algoritmik bir ilişki vardır.

Eklentileriniz böyle görünmelidir.

quadtree->insert(0.0, 0.0, value1)
quadtree->insert(0.0, 0.0, value2)

İlk ekleme bir (üst) düğüm oluşturur ve buna bir değer ekler.

İkinci kesici uç bir alt düğüm oluşturur, ona bağlanır ve bu değere bir değer ekler (bu ilk değerle aynı olabilir).

Hangi alt düğümün başlatıldığı algoritmaya bağlıdır. Algoritma [x) biçimindeyse ve koordinat boşluğu [0,1) aralığındaysa, her çocuk [0,0,5) aralığını kapsayacak ve nokta KB çocuğuna yerleştirilecektir.

Sonsuz özyineleme görmüyorum.


Yani alt bölümlere ayırırken düğümleri çocuklara dörtlü olarak yeniden dağıtma yolumun benim uygulamamdaki sorun nedir?
Pierre Arlaud

Belki de sorun, bir değeri (ebeveynte) daha iyi bir yere (bir çocukta) taşımaya çalışmanızdır. Gerçekten böyle yapılmadı. Değer olduğu yerde gayet iyi. Ancak bu, farklı düğümlere iki özdeş noktanın yerleştirilebileceği (ancak her zaman ilgili ebeveyn ve çocuk) ilginç sonuca yol açar.
david.pfx

2

Karşılaştığım ortak çözünürlük (görselleştirme problemlerinde, oyunlarda değil), her zaman değiştiren veya asla değiştirmeyen noktalardan birini atmaktır.

Sanırım ana nokta, yapmanın kolay olmasıdır.


2

Aynı boyuttaki tüm öğeleri indekslediğinizi varsayıyorum, aksi takdirde hayat karmaşıklaşıyor, yavaşlıyor veya her ikisi de ……

Quadtree düğümünün sabit bir kapasiteye sahip olması gerekmez . Kapasite için kullanılır

  • Her ağaç düğümünün bellekte veya diskte sabit boyutta olmasına izin verin - ağaç düğümü değişken boyutlu bir öğe kümesi içeriyorsa ve başa çıkacak bir alan ayırma sistemi kullanıyorsanız gerekli değildir. (Örn. Bellekteki java / c # nesneleri.)
  • Düğümün ne zaman bölüneceğine karar verin.
    • Kuralı yeniden tanımlayabilirsiniz, böylece bir düğüm "n" den fazla bölge öğesi içeriyorsa bölünür; burada bölge öğelerin konumuna göre tanımlanır.
    • Veya bir " bileşik eleman" kullanın, böylece aynı konumda çarpma elemanları varsa, bu çarpma elemanlarının listesini içeren yeni bir eleman tanıtırsınız.

2

Uzamsal indeksleme sorunları ile uğraşırken, aslında bir uzamsal karma veya kişisel favorim olan sade eski ızgara ile başlamanızı öneririm.

resim açıklamasını buraya girin

... ve seyrek temsillere izin veren ağaç yapılarına geçmeden önce zayıflıklarını anlamak

Bariz zayıflıklardan biri, çok sayıda boş hücrede bellek harcayabiliyor olmanızdır (ancak iyi uygulanmış bir ızgara, aslında milyarlarca düğüm eklemek zorunda kalmadıkça hücre başına 32 bitten fazla gerektirmemelidir). Bir diğeri, bir hücrenin boyutundan daha büyük olan ve genellikle düzinelerce hücreye yayılan orta boyutlu öğeleriniz varsa, bu orta boyutlu öğeleri idealden çok daha fazla hücreye yerleştirerek çok fazla bellek harcayabilirsiniz. Benzer şekilde, uzamsal sorgular yaptığınızda, idealden daha fazla hücre, bazen çok daha fazla kontrol etmeniz gerekebilir.

Ancak, belirli bir girdiye karşı olabildiğince optimum hale getirmek için bir ızgara ile incelik yapmak için tek şey cell size, sizi düşünmek ve kemanlamak için çok fazla şey bırakmayan şeydir ve bu yüzden benim veri yapım kullanmama nedenleri bulana kadar uzamsal indeksleme sorunları için. Uygulaması basittir ve tek bir çalışma zamanı girdisinden başka bir şeyle uğraşmanızı gerektirmez.

Sade eski bir ızgaradan çok şey alabilirsiniz ve aslında ticari yazılımda kullanılan çok sayıda dört ağaç ve kd ağacı uygulamasını düz bir eski ızgarayla değiştirerek yendim (ancak bunlar en iyi uygulananlar değildi) , ancak yazarlar bir tabloyu kırmak için harcadığım 20 dakikadan çok daha fazla zaman harcadı). Çarpışma tespiti için bir ızgara kullanarak başka bir yerde bir soruyu cevaplamak için çırptığım kısa bir şey (gerçekten optimize edilmemiş, sadece birkaç saatlik bir çalışma ve çoğu zaman yol bulmanın soruyu cevaplamak için nasıl çalıştığını öğrenmek zorunda kaldım ve aynı zamanda bu tür çarpışma tespitini ilk kez uyguluyordum):

resim açıklamasını buraya girin

Izgaraların bir başka zayıflığı (ancak birçok uzamsal indeksleme yapısı için genel zayıflıklardır), aynı konuma sahip birçok nokta gibi çok sayıda çakışan veya çakışan eleman eklerseniz, aynı hücrelere ( ) ve o hücreden geçerken performansı düşürür. Benzer şekilde , hücre boyutundan çok daha büyük, çok daha büyük çok sayıda öğe eklerseniz , bir bot yük hücresine yerleştirilmek ve çok ve çok bellek kullanmak ve karttaki uzamsal sorgular için gereken süreyi kısaltmak isteyeceklerdir. .

Bununla birlikte, yukarıda rastlanan ve büyük elementlerle ilgili bu iki acil sorun aslında tüm mekansal indeksleme yapıları için problemlidir . Sade eski ızgara aslında bu patolojik vakaları diğerlerinden biraz daha iyi ele alır, çünkü en azından hücreleri tekrar tekrar alt bölümlere ayırmak istemez.

Izgara ile başladığınızda ve dört ağaç veya KD ağacı gibi bir şeye doğru ilerlediğinizde, çözmek istediğiniz ana sorun, çok fazla hücreye yerleştirilen, çok fazla hücreye sahip olan ve / veya bu tip yoğun gösterimle çok fazla hücreyi kontrol etmek zorunda kalmak.

Ancak dört ağacı bir ızgara üzerinde bir optimizasyon olarak düşünüyorsanızspesifik kullanım durumlarında, dört ağaç düğümlerinin özyinelemeli alt bölümünün derinliğini sınırlamak için hala bir "minimum hücre boyutu" fikrini düşünmeye yardımcı olur. Bunu yaptığınızda, dört ağacın en kötü senaryosu, yapraklardaki yoğun ızgaraya bozulmaya devam edecek, ızgaradan sadece daha az verimli olacaktır, çünkü kök yerine ızgara hücresine gitmek için logaritmik zaman gerektirecektir. sabit zamanlı. Ancak bu minimum hücre boyutunu düşünmek sonsuz döngü / özyineleme senaryosundan kaçınacaktır. Büyük elementler için, gevşek dörtlü ağaçlar gibi, eşit olarak bölünmeyen ve üst üste binen çocuk düğümleri için AABB'lere sahip olabilecek bazı alternatif varyantlar da vardır. BVH'ler, düğümlerini eşit şekilde bölmeyen mekansal indeksleme yapıları olarak da ilginçtir. Ağaç yapılarına karşı tesadüf unsurlar için, asıl mesele sadece alt bölümlere bir sınır koymak (veya diğerlerinin önerdiği gibi, sadece reddetmek veya yaprak ne zaman belirlendiğinde bir yapraktaki benzersiz sayıda öğeye katkıda bulunmuyormuş gibi davranmanın bir yolunu bulmaktır) alt bölümlere ayırmalıdır). Bir Kd ağacı, çok sayıda çakışan öğeye sahip girdileri öngörürseniz de yararlı olabilir, çünkü bir düğümün medyan bölünmesi gerekip gerekmediğini belirlerken yalnızca bir boyutu göz önünde bulundurmanız gerekir.


Çeyrekler için bir güncelleme olarak, birisi çarpışma tespiti için nasıl verimli hale getirileceği konusunda biraz geniş bir soru sordu (ama ben bunları seviyorum) ve sonunda bunları nasıl uyguladığımla ilgili cesaretimi döktüm. Ayrıca sorularınızı da yanıtlamalıdır: stackoverflow.com/questions/41946007/…
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.