Bir harita oluşturan sonlu büyüklükte fayans ızgarası var. Haritanın içindeki karoların bazıları bölge olarak bilinen bir kümeye konur. Bu bölge birbirine bağlı, ancak şekli hakkında hiçbir şey bilinmiyor. Çoğu zaman oldukça düzenli bir damla olurdu, ancak bir yönde çok uzatılabilir ve potansiyel olarak delikleri bile olabilir. Bölgenin (dış) sınırını bulmakla ilgileniyorum.
Yani, bölgedeki fayanslardan birine dokunmadan tüm fayansların bir listesini istiyorum. Bunu bulmanın etkili bir yolu nedir?
Ekstra zorluk için, karolarımın altıgen olduğu, ancak bunun çok fazla fark yaratmadığından, her karonun hala bir x ve y koordinatıyla etiketlendiğinden ve bir karo verildiğinde, komşularını kolayca bulabileceğimden şüpheleniyorum. Aşağıda birkaç örnek verilmiştir: Siyah bölge, mavi ise bulmak istediğim sınır. Bu kendi başına zor bir problem değildir, Sözde python'da bunun için basit bir algoritma:
def find_border_of_territory(territory):
border = []
for tile in territory:
for neighbor in tile.neighbors():
if neighbor not in territory and neighbor not in border:
border.add(neighbor)
Ancak bu yavaş ve daha iyi bir şey istiyorum. Bölge üzerinde bir O (n) döngü var, tüm komşular üzerinde başka bir döngü (kısa bir, ama yine de), ve sonra bir tanesi n boyutunda olan iki liste üzerinde üyelik kontrol etmek zorunda. Bu korkunç bir O (n ^ 2) ölçeklendirmesi verir. Üyelik kontrolü hızlı olmak için sınır ve bölge listeleri yerine kümeleri kullanarak bunu O (n) değerine düşürebilirim, ancak yine de harika değil. Bölgenin büyük, ancak sınırın basit bir alan vs çizgi ölçeklendirmesi nedeniyle küçük olduğu birçok durum olmasını bekliyorum. Örneğin, bölge 5 yarıçapı altılıksa, 91 büyüklüğündedir, ancak sınır yalnızca 36 büyüklüğündedir.
Herkes daha iyi bir şey önerebilir mi?
Düzenle:
Aşağıdaki soruları cevaplamak için. Bölgenin büyüklüğü yaklaşık 20 ila 100 arasında değişebilir. Bölgeyi oluşturan karolar kümesi bir nesnenin özniteliğidir ve tüm sınır döşemelerinden oluşan bir kümeye ihtiyaç duyan bu nesnedir.
Başlangıçta bölge bir blok olarak oluşturulur ve daha sonra çoğunlukla teker teker karo kazanır. Bu durumda, en hızlı yolun sadece bir sınır kümesini korumak ve sadece kazanılan karoda güncellemek olduğu doğrudur. Bazen bölgede büyük bir değişiklik olabilir - bu yüzden o zaman tam olarak yeniden hesaplanması gerekecektir.
Şimdi basit bir sınır bulma algoritması yapmanın en iyi çözüm olduğunu düşünüyorum. Bunun ortaya çıkardığı tek ek karmaşıklık, sınırın olması gereken her seferinde yeniden hesaplanmasını sağlamaktır, ancak bundan daha fazlasını değil. Bunun mevcut çerçevemde güvenilir bir şekilde yapılabileceğinden oldukça eminim.
Zamanlama gelince, mevcut kodumda bölgenin her bir karo kontrol etmek gerekir bazı rutinleri var. Her dönüşte değil, yaratılışta ve bazen de sonrasında. Bu, tam programın çok küçük bir parçası olmasına rağmen test kodumun çalışma süresinin% 50'sinden fazlasını alıyor. Bu nedenle tekrarları en aza indirmeye istekliydim. ANCAK, test kodu programın (doğal olarak) normal bir çalışma daha çok daha fazla nesne oluşturma içerir, bu yüzden bunun çok ilgili olmayabilir.