Birden çok dikdörtgeni daha az sayıda dikdörtgene “iyileştirme” algoritması mı?


14

resim açıklamasını buraya girin

Diyelim ki farklı şekil ve renklerde dikdörtgenlerden oluşan bir ızgaram var ve aynı renk düzenini temsil etmek için dikdörtgen sayısını azaltmak istiyorum (makul olarak optimale yakın iyidir, optimal gerekli değildir).

Yukarıdaki görüntü çok basitleştirilmiş bir durumdur ve dikdörtgenler arasındaki boşluk sadece görselleştirme içindir - bunlar sıkıca paketlenir.

Bunu yapmama yardımcı olabilecek bir yaklaşım veya algoritma adı (google'dan memnun) nedir?


3
Bize bu dikdörtgenlerin nereden geldiğinden biraz bahseder misiniz? Altta yatan herhangi bir ızgarayla (kabaca) hizalanma veya ortak bir yapı bloğunu veya en küçük "atom" dikdörtgenini paylaşma eğilimi var mı? Döndürülebilirler mi? Bu, en genel durumda çok dikenli olabilecek bir tür soruna benziyor, ancak belirli senaryolarınızdaki bazı kısıtlamalardan veya ortaklıklardan yararlanabilirsek çok daha kolay olabilir.
DMGregory

Altta yatan bir kareler ızgarası vardır (bir dama tahtası gibi) ve her dikdörtgen altta yatan karelerle sınırları paylaşmaktadır. yani her bir dikdörtgenin üst / alt / sol / sağını tanımlamak için bir tamsayı kullanabilirsiniz. Bu nedenle, 90 dereceye bölünemeyen açılarda döndürülemezler. Ayrıca NxM ızgarası tamamen dikdörtgenlerle doldurulur - açık ızgara pozisyonları yoktur.
xaxxon

Sadece yukarıdaki örneğe benzeyen durumdan (renklendirme perspektifinden) kaçınmaya çalışıyorum, ancak 1x1 dikdörtgenden oluşan bir tondan oluşuyor ve birçok alanda alanı işlerken her birini işliyorum daha az çağrı.
xaxxon

Bir tür "sadece bir yerden başlayın ve bir renk sınırına çarpana kadar bir boyutta (dikey olarak söyleyin) daha büyük ve daha büyük dikdörtgenler denemeye devam edin, sonra bir sınıra ulaşıncaya kadar diğer boyutu (yatay olarak) büyütün. O zaman belki sadece kareleri deneyin (çapraz olarak büyür) Ama yukarıdaki 3 olasılıktan en
büyüğünü seçmenin

Sonunda daha az dikdörtgenle sonuçlanırsa, mevcut bir dikdörtgeni bölmek kabul edilebilir mi? Yoksa algoritma sadece birleşmeli mi? Ayrıca, toplam sayı tek kriter midir, yoksa uzun sıska şeritlere / daha küçük dikdörtgenlere göre daha büyük dikdörtgenler mi tercih ediyorsunuz?
DMGregory

Yanıtlar:


15

İlk olarak, girdiyi daha homojen hale getirmek için kaynak dikdörtgenlerinizi alttaki ızgaradaki hücrelere dönüştürebiliriz. (Sorunu etkin bir şekilde rasterleştirmek)

Bu, doğrudan kaynak dikdörtgenlerle çalışırken, özellikle de bunları farklı şekilde yeniden birleştirmek için birden fazla kaynak dikdörtgeninin bölünmesini gerektirdiğinde belirgin olmayabilecek optimizasyonları bulmamıza olanak tanır.

Dikdörtgenleri ızgara hücrelerine ve arkaya dönüştürme örneği

Daha sonra, derinlik-ilk arama veya taşkın doldurma algoritmaları kullanarak aynı renkteki bağlı bölgeleri bulabiliriz. Her bağlantılı bölgeyi (bir poliomino ) tek başına düşünebiliriz - farklı bir bölgeye yaptığımız hiçbir şeyin bu bölgeyi etkilemesi gerekmez.

Etkili bir şekilde bu polyominoyu dikdörtgenlere ayırmanın bir yolunu bulmak istiyoruz (maalesef bulabileceğim literatürün çoğu karşı problemle ilgili: dikdörtgenleri poliominolara ayırmak! Bu, olası satışları araştırmayı zorlaştırıyor ...)

Basit bir yöntem, bitişik karelerin yatay çalışmalarını uzun sıska dikdörtgenlerde birleştirmektir. Daha sonra yukarıdaki satıra kıyasla karşılaşabiliriz ve çalışma başlangıç ​​ve bitişlerimiz eşleşirse birleştirebiliriz - her bir çalışmayı / satırı bitirirken veya her hücrenin geçerli çalışmaya eklenmesini düşündüğümüz gibi.

Bir polyominoyu yatay çalışmalara ayrıştırmak, sonra dikey olarak birleştirmek

Bu yöntemin ne kadar optimum hale geldiğini henüz bilmiyorum. Henüz dikkate almadığı bir satır, şimdiye kadar gördüğü satırlardan farklı bir bölünme önerdiğinde biraz sorun yaşayabilir:

Yukarıdaki yöntemin 4 bulduğu 3-dikdörtgen çözümlü bir durum örneği

Bir çalışma / dikdörtgenin tam olarak yukarıdaki ve altındaki çalışmalarla kapandığını algılamak, sonra bölmek ve birleştirmek bu özel durumu çözecektir, ancak sorunun ne kadar genel olduğunu araştırmadım.

Ayrıca, poliominonun çevresini yürüdüğümüz ve içbükey bir köşeyle karşılaştığımızda her zaman kestiğimiz yöntemlere baktım, ancak bu yaklaşım bana daha fazla hataya eğilimli görünüyor. En iyi sonuçları elde etmek için, iki içbükey köşeyi birleştiren kesimlere öncelik verilmesini gerektiriyor ve oyuk içeren şekiller özel işlem gerektiriyor, bu nedenle satır tarama yönteminin basitlik avantajı var gibi görünüyor.

Baktığım bir yöntem daha üst satırda bulunan ilk koşuyu alıp olabildiğince uzağa uzatmak. Daha sonra, kalanın üst satırındaki ilk koşuyu alın ... Bu, ters T şekillerinde tetiklenir, bu yüzden de optimal değildir.

İdeal bölmeyi bulmak için muhtemelen dinamik programlama kullanmanın bir yolu olduğunu hissediyorum, ancak henüz bulamadım.


Müthiş cevap için teşekkürler! Bu çözüm, birkaç farklı yöne koşabileceğim ve hangisinin en iyi göründüğünü seçebileceğim kadar hızlı görünüyor - yatay sol-> sağ, yatay sağ-> sol ve sonra her iki yönde de dikey.
xaxxon

2
Sorun, algoritmayı her tarama yönünden yanlış yönlendirecek şekiller oluşturabilmemizdir. Bunlar gerçek kullanımda görünmeyebilir, ancak yine de beni rahatsız ediyor. Sanırım henüz basit bir düzeltme var ... Her koşuda, orta ortasında içbükey köşeler olup olmadığını belirtmek gibi bir şey. Ardından, sonraki bir çalışma tam olarak böyle bir noktada sona ererse, yukarıdaki çalışmalarda dikey olarak bölerek geri gideriz. Ancak tüm detayları çözemedim.
DMGregory

1
Ayrıca, taşkın doldurma adımının neden gerekli olduğundan emin değilim. Bir ızgara positino'dan uzun bir sıska dikdörtgene giderken, bu 1xN dikdörtgenleri oluşturmak için ızgaranın tam satırını veya sütununu (hangi yöne giderseniz gidin) yürüyebilirsiniz. Poliminoyu bilmenize gerek yok, değil mi?
xaxxon

Haklısın, sel dolgusu gerekli bir adım değil. Sonraki adımlarda bir kerede yalnızca bir renkli bölgeye odaklanmayı haklı çıkarmak için dahil ettim, ancak satır tarama yöntemini aralıklı olarak yerleştirilmiş birden çok renkli bölgeye kolayca uygulayabilirsiniz. Çevre tabanlı yöntem, her seferinde bir şeklin çevresinde çalışmalıdır.
DMGregory
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.