3D voksel tabanlı bir odanın verimli bir şekilde mühürlenip mühürlenmediğini belirleme


10

Ben büyük odalar voksel tabanlı bir 3D odalarda mühürlü olup olmadığını verimli bir şekilde belirlemek ile bazı sorunlar yaşıyorum. Yardım istemeden sorunu çözmek için elimden gelenin en iyisini yapmaya çalıştığım bir noktadayım, ama vazgeçecek kadar denemedim, bu yüzden yardım istiyorum.

Açıklığa kavuşturmak için, mühürlü, odada delik olmamasıdır. Odanın sızdırmazlığını kontrol eden oksijen sızdırmazlıkları vardır ve oksijen giriş seviyesine bağlı olarak sızdırmazdır.

Şu anda böyle yapıyorum:

  • Sızdırmazlık döşemesinin üzerindeki bloktan başlayarak (havalandırma, sızdırmazlık maddesinin üst yüzündedir), bitişik 6 yönün tamamında tekrar tekrar döngü
  • Bitişik karo dolu, vakumlu olmayan bir karo ise, döngüden devam edin
  • Bitişik döşeme dolu değilse veya vakumlu bir döşemeyse, bitişik blokların yinelemeli olup olmadığını kontrol edin.
  • Bir kutucuğun her kontrolünde bir sayacı azaltın
  • Sayım sıfıra ulaşırsa, son blok bir vakumlu karoya bitişikse, alanın mühürsüz olduğuna geri dönün
  • Sayım sıfıra isabet ederse ve son blok bir vakum döşemesi değilse veya sayaç sıfırdan önce yinelemeli döngü sona ererse (vakum döşemesi kalmaz), alan mühürlenir

Alan kapatılmazsa, döngüyü bazı değişikliklerle tekrar çalıştırın:

  • Bitişik bloklarda vakumlu karo yerine "hava alabilir" karo olup olmadığını kontrol etme
  • Azalan bir sayaç kullanmak yerine, bitişik "solunabilir hava" fayansları bulunana kadar devam edin.
  • Döngü bittiğinde, kontrol edilen her bloğu bir vakum döşemesine ayarlayın.

İşte kullanıyorum kodu: http://pastebin.com/NimyKncC

Sorun:

Bu kontrolü her 3 saniyede bir çalıştırıyorum, bazen bir mühürleyen yüzlerce blok arasında döngü yapmak zorunda kalacak ve birçok oksijen sızdırmazlığı olan büyük bir dünya, birkaç saniyede bir bu çoklu tekrarlayan döngüler CPU'da çok zor olabilir.

Optimizasyon konusunda daha fazla deneyimi olan birinin bana yardım edip edemeyeceğini veya en azından beni doğru yöne yönlendirip yönlendiremeyeceğini merak ediyordum. Çok teşekkürler.


Sadece bir şeyin değiştiğini kontrol etmek bir başlangıç ​​olur. Her üç saniyede bir kontrol aşırıya kaçmaya benziyor, çünkü mührü kırabilecek voksellerin ne zaman değiştiğini biliyorsunuz. Kapalı bir odayı oluşturan bir voksel değiştirilirse, o odayı tekrar kontrol edilecek şekilde işaretleyebilirsiniz, aksi takdirde rahatsız etmeyin.
MichaelHouse

Bu 3 saniyelik zaman diliminde yüzlerce voksel değişebileceğinden, yakınlarda bir şeylerin değişip değişmediğini kontrol etmek yerine, periyodik olarak yapmanın daha verimli olacağını düşündüm. Bununla birlikte deney yapacağım.
NigelMan1010

Oh, 3 saniyelik bir zaman dilimi içinde yüzlerce voksel değişebilirse, muhtemelen performansla ilgili bir takım sorunlarınız olacaktır. Verimsizlikleri bulmak için kodunuzu oluşturmaya başlayın. İyi şanslar!
MichaelHouse

Yanıtlar:


3

En iyi çözüm, beklenen oda büyüklüğü gibi birçok faktöre dayanacaktır.

  1. Bunu sadece bir şey değiştiğinde kontrol edin.

Yaklaşım 1:

Havalandırma deliğinden havalandırma / havalandırma deliğinin üstündeki karoya veya vakum olarak bilinen bir karoya giden bir yol bulmak için bir A * kullanabilirsiniz. Yol bulunursa, oda mühürsüzdür. Bu, mevcut yaklaşımınızdan çok farklı değil, ancak daha hızlı olmalı. Bir kez, fayans vakum olarak ayarlamak için bir "sel dolgu" yapın.

Yaklaşım 2:

Belki dış yapınız daha az komples - odaların altında bir yüzey olduğu düşünüldüğünde, 6 yönde hareket etmenize gerek yoktur, bu yüzden yüzey boyunca seyahat etmeli, her karo u seyahat ettiğiniz vakum olarak işaretlenmelidir.


0

Özyinelemeli aramanızı yaparken, aynı vokseli birden çok kez kontrol etmediğinizden emin misiniz? Algoritmanızı tanımladığınız yoldan anlayamadım, ancak bir vokseli özyinelemeli olarak genişletip genişletmediğinizi belirtmek için bir tür bayrağınız olmalı, bu yüzden bir kereden fazla yapmıyorsunuz.

Byte56'nın dediği gibi, sızıntı olup olmadığını sadece işler değiştiğinde kontrol etmelisiniz. Bu, değişikliklerin ne sıklıkta gerçekleştiğine bağlı olarak yaptığınız iş miktarını büyük ölçüde en aza indirebilir. Hatta algoritmaya yapılan ardışık çağrılar arasındaki bilgileri önbelleğe alabilirsiniz, bu da ilk çağrıdan sonra yaptığınız hesaplama miktarını önemsiz hale getirebilir.

Düzenle:

Bazı kodlarınıza baktım. İlk paragrafımda olduğu gibi, bir vokselin zaten kontrol edilip edilmediğini belirtmek için LinkedList kullanıyorsunuz gibi görünüyor. Bunun için LinkedList dışında bir şey kullanırsanız daha iyi sonuçlar alabilirsiniz. Belki de bir HashSet falan deneyin. Bu, kontrol yönteminizin karmaşıklığını O (n) 'den O (1)' e düşürmelidir.


Evet, bunu "işaretli" adlı bir LinkedList'e ekliyorum ve ardından bu listenin denetlemeden önce konumu içerip içermediğini kontrol ediyorum. Bir şeyin değişip değişmediğini kontrol etmenin aşırı derecede CPU-yoğun olacağını düşünmüştüm, çünkü o 3 saniyelik süre içinde yüzlerce voksel değişmiş olabilir. Bu durumda bir hashsetin bağlantılı listeyle nasıl karşılaştırıldığını göreceğim, teşekkürler.
NigelMan1010
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.