Birimler eklendiğinde veya çıkarıldığında dikdörtgen bir oluşumu nasıl koruyabilirim?


18

Sıralar ve sütunlarla dikdörtgen bir formasyonda botlar var. Bir bot formasyon eklendiğinde veya oluşumdan çıkarıldığında bir sorun ortaya çıkar. Bu olduğunda, botlar kendilerini dikdörtgen şeklindeki oluşum hala kabaca aynı en boy oranı olacak ve mümkün olduğunca dikdörtgen olacak şekilde yeniden düzenlemelidir . Bu nasıl yapılır?

Bazı fikirler:

  • Bir bot eklendiğinde veya çıkarıldığında, o en boy oranına en çok uyan formasyonun yeni genişliğini ve yüksekliğini hesaplamak için yeni toplam bot sayısını ve istenen sabit en boy oranını kullanın. Ardından botları yeni boyutlara uyacak şekilde yeniden karıştırın.

  • Bir bot çıkarıldığında, arkasındaki botu yerine taşıyın ve formasyonun sonuna ulaşıncaya kadar devam edin. Daha sonra arka sıradaki botları bir şekilde karıştırmakla mümkün olduğunca arka sıraya çıkın.

  • Tamamen farklı olan bir başka fikir, molekül yapılarının bir arada kalma şeklini taklit etmektir. Her botu en yakın dört botu çekerek ve geri kalanını iterek diğer dört botla çevrelenmek isteyin. Ters kare yasası kullanarak ayrılmayı sağlamak için çok yakın olan tüm botları (dördü de dahil) püskürtün. Ayrıca, tüm yapıyı şekillendirmek için ek bir güce ihtiyacınız olacaktır. Ancak, bu kulağa oldukça pahalı geliyor.

GÜNCELLEME : Yani sarahm'ın cevabına baktığımda, iyi boyutlar veren iyi bir genel fonksiyon buldum.

Önce genişlik ve yükseklik için aşağıdaki eşzamanlı denklemi çözdüm ve sonra cevapları yuvarladım.

width/height=aspect ratio of your choice
width*height=number of bots

Bu size bot sayınız için o en boy oranına en yakın tamsayıyı verir. En yakın dikdörtgen, zamanın yarısı çok büyük ve yarısı da çok küçük olacaktır (elbette bazen doğru olacaktır, ancak kimin umurunda). Dikdörtgenin biraz fazla büyük olduğu durumlarda , hiçbir şey yapılmasına gerek yoktur. Arka sıra hemen hemen dolu olacak, bu da ideal. Dikdörtgenin biraz fazla küçük olduğu durumlarda , sorunlarınız var, çünkü ufacık küçük taşma kendi rütbesine gitmek zorunda kalacak, üzerinde sadece birkaç bot bulunan bir rütbe yarattı, ki bu hoş görünmüyor. Farkın büyük olduğu durumlar da var(genişliğin yarısından daha büyük), bu durumda farkı küçük yapmak için bir sıralama ekleyin veya çıkarın. Ardından, dikdörtgen çok küçük olduğunda, biraz daha büyük yapmak için bir sütun ekleyin. Bunu yaptıktan sonra arka sıra her zaman diğer sıraların en az yarısına sahip olacak gibi görünüyor .

GÜNCELLEME

Boyutları aldıktan sonra, bunları geçerli boyutlarla karşılaştırın. Yeni boyutun cephesi daha büyükse, her rütbe için, aşağıdaki rütbeden botlar açın ve bu rütbedeki bot sayısı cepheye eşit oluncaya kadar mevcut rütbeye itin. Arka sıraya gelene kadar bu algoritmaya devam edin. Bu algoritmayı kullanarak, botlar yeni boyuta verimli bir şekilde uyacak şekilde hareket edecektir. Bundan sonra, yeni eskiyi arka sıraya itiyorum. Algoritma, yeni cephenin daha küçük olduğu durumlar için biraz farklıdır, ancak anlayabilirsiniz!

Bundan sonra iki sorun daha var. Silme ve yeni botların mutlaka arka sıraya atanmadığı, ancak eklendikleri anda kendilerine en yakın konumun atandığı daha esnek bir ekleme yöntemi.


Bir ünitedeki maksimum bot sayısı nedir? Nispeten küçükse, bir oluşumun belirli sayıda bot için kaç satır ve sütuna sahip olduğunu kodlayabilirsiniz.
Exilyth

3
Geçerli ve geçersiz olan oluşumların bir resmini yayınlayabilir misiniz? Neyin peşinde olduğunu anlamakta biraz güçlük çekiyorum. Eksik satırlara / sütunlara izin veriliyor mu?
MichaelHouse

3
Bunun asal sayılar için işe yaramayacağını biliyor musunuz? Örneğin 7 bot ile, arkada tek bir bot bulunan 3x2'lik bir birim yapmanız gerekir.
Exilyth

1
Bu utanç verici. Asal sayıları tamamen unuttum. Sonra belki bir sonraki en iyi şey sadece ALMOST dolu satırlara ve sütunlara izin vermek olacaktır. Bir satırdaki bir Bot doğru görünmüyor, ancak bir satırdaki bir Bot daha kötü görünmüyordu.
Tiby312

3
Asıl sayılar sorun yaratacak tek sayı değildir - faktoring ile oluşum boyutunu seçmek size makul olmayan derecede uzun ve sıska oluşumlar verebilir. Örneğin, 14 botunuz varsa, tek mükemmel dikdörtgen formasyon 7x2'dir, ekstra 2 botluk bir 3x4 formasyonuna sahip olmak daha iyi görünebilir .
Nathan Reed

Yanıtlar:


16

Başka bir teknik, Napolyon taburları tarafından kullanılanı taklit etmektir (ve muhtemelen daha fazla değilse Yunan falankslarına kadar).

Cephe genellikle sabit tutulur ve bir adam düştükçe (sırt hariç herhangi bir rütbede) yerini doğrudan ileriye doğru adım atan adam alır. Arka sıra, her bir kanadın en ucunda birkaç adam sağlamak ve aksi takdirde eşit olarak doldurmak için NCO'lar tarafından karıştırılır.

Ön cephe sadece arka sıra önceden belirlenmiş yoğunlukların altına düştüğünde azalır. Benzer şekilde, arka sıra aşırı olduğunda ekstralar önce her iki kanattan ek bir sıra doldurmaya başlar ve sonra cephe artar.

Ön cepheyi değiştirirken, ön cepheyi arttırırken botlarınızın arka sıradan her iki flanşa da dosyalanmasını ve cepheyi azaltırken her iki flanştan arka sıraya dosyalanmasını öneriyorum.

Eğer bir "askeri" izlenim arıyorsanız ve bot organizasyonlarınızın falanks gibi görünmesini sağlıyorsam, bu düzenli yeniden düzenlemenin bu amaca ulaşmak için daha iyi bir yol olduğuna inanıyorum.

Güncelleme :
Arka sırayı yönetmenin basit bir yolu, arka sıra birimlerini üç mangaya bölmektir: her bir kanatta birer merkezde diğeri. Cephenin tek veya çift olmasına ve arka sıra birimlerinin sayısının 0,1 veya 2 mod 3'e uygun olup olmadığına bağlı olarak, yönetilmesi gereken altı vaka vardır.

Yukarıdakilere bir gelişme olarak, dolgu bir eşiğin altına düştüğünde her bir arka sıra ekibinin son birimlerini
aralamayı düşünün , örneğin: xxx.x .... x.xxx.x .... x. xxx
veya bu:
xx.xx..x.xxx.x ... xxxx
Daha da iyi bir görünüm için biraz daha fazla iş.

Güncelleme # 2 :
Formasyon derinliği hakkında ek bir düşünce. Voleybolu ateşin etkisi, modern süngü ile birleştiğinde, 18. veya 19. yüzyılın başında 3 veya 4 derinliği yeterli hale getirdi. (İngilizler , popüler inanışın aksine, savaşın sonuna kadar nadiren 2 sırada savaştı; biri için, çizgilerini hızlı bir şekilde kare oluşturmak için çok uzattı.) Bundan önce, belki de 8'e kadar daha büyük derinliklere sahip olmak yaygındı. veya Sarissa ile donatılmış bir Yunan falanks için 10. İstediğiniz izlenimi yaratan bir derinlik seçin.

Gerçek hayattaki ordular, artan bir birim kırılganlığı pahasına, birim cephesini mümkün olduğunca uzun süre korumaya çalışırlar, çünkü bu bir savaş alanını düzenlemeyi kolaylaştırır. Pharsalus'taki Sezar, Pompey'in kuvvetlerine uyacak şekilde cepheyi artırmak için birim derinliğini kasten azalttı. Alıntı olarak: "Bugün kazanıyoruz ya da ölüyoruz; Pompey'in adamlarının başka seçenekleri var." (Sezar'ın elbette akıllı ve dikkatli bir şekilde temin ettiği).


Bu çok daha şık bir çözüm gibi geliyor. Asal sayılar veya en boy oranları hakkında tartışmalara gerek yoktur ve yine de üzerinde olağandışı düşük sayıda bot bulunan herhangi bir satırdan kaçınır ve kontrol edilmesi gereken tek koşul, backrank'in ne kadar dolu olduğudur!
Tiby312

Ama durun. Arka sıralamanın sadece 3 botu olduğunu ve sütun 1, 2 ve 3'te olduğunu varsayalım. Birini ön taraftaki 5. sütundan çıkarıyorum. 5 sütununda ikinci satır son satırında yer almak için arkasında hiçbir bot olmadan ücretsiz bir nokta ile sona erecekti. Bu yeri kim doldurmalı?
Tiby312

Muhtemelen, arka sıradaki en yakın bot (yani sütun 3'teki) onu doldurmak için çalışmalıdır. Ya da her bir adım bir sütun yukarı, boşluğu sütun 3'e taşıyarak ikinci ve son rütbenin 3. ve 4. sütunlarında bulunan botlara sahip olmak ve ardından 3. sütunda botu doldurmak için biraz zaman kazanabilirsiniz. o. (IMO, en "doğal" görünümlü strateji muhtemelen ikisinin sezgisel bir kombinasyonu olabilir, muhtemelen bazı rasgelelikler atılır.)
Ilmari Karonen

1
Arka sıralamanın çok az üyesi varsa (diğer safların% 50'sinden daha azını söyleyin) ve cepheyi artırırsanız, bu sorunu düzeltmek için garantili mi yoksa art arda sıralamanın hala çok az üyesi olması mümkün mü? tekrarlanmasını gerektiren cephe falan?
Tiby312

1
@ Tiby312: Aşırı düşündüğüne inanıyorum. Daha sonra her zaman ayarlayabileceğinizi bilerek bir deneyin
Pieter Geerkens

7

Bir birimin, botların doğrusal bir veri yapısı (örneğin bir listesi ) olduğunu varsaymak.

İlk olarak, veri yapısına / yapısına bot eklemeniz / çıkarmanız ve ünitedeki yeni bot sayısını belirlemeniz gerekir.

Ardından, https://en.wikipedia.org/wiki/Integer_factorization öğesini kullanarak yeni satır ve sütun miktarını belirlemeniz gerekir .

Tabii ki, asal sayılar nedeniyle bu her zaman mümkün değildir . Yeni birim boyutu asal bir sayı olduğunda, bir sonraki daha büyük birim boyutunu kullanmanız gerekir.

Ardından, veri yapısı üzerinde tekrarlayın, satırlara ve sütunlara botlar atayın.

Botları yerleştirmek için sadece veri yapısı üzerinde tekrarlayın, her bir botu, botun içinde bulunduğu satır ve sütun tarafından belirlenen bir miktarda birim konumundan sapan bir pozisyon atayın (veya o noktayı botların hareketi için bir hedef olarak ayarlayın).

Merkezi bir köşede olan bir ünite yapmak için , bir botun konumu

unitPosition + heading * columnNumber * botSeparationDistance + rightVector * rowNumber * botSeparationDistance

Merkezi ortada olan bir ünite yapmak için , bir botun konumu

unitPosition + heading * (columnNumber * unitSeparationDistance - 0,5 * (numberOfColumns * botSeparationDistance) + rightVector * rowNumber * botSeparationDistance - 0,5 * (numberOfRows * botSeparationDistance)

burada başlık birimi bakan ve doğrultuda bir vektör işaret olan rightVector ortogonal bir vektördür başlığı .

botSeparationDistance, botların birbirine daha yakın veya daha yakın durması için değiştirilebilir.

Hissine fantezi Eğer varsa, ofset olabilir botlara son satırını tarafından rightVector için - (actualNumberOfBotsInRow numberOfColumns) * 0.5 * ortalamak onları oluşumu üzerinde .


Bu aradığım şeylere çok yakın! Benim tek rezervasyon, yeni pozisyonlar atarken, bir satırın en sağında bir Bot, yeni dikdörtgenin bir sonraki satırının en soluna atanabilir, böylece Bot uzun bir mesafeye ve süreçlere sahip olur kendi yeni atanmış pozisyonlarına ulaşmaya çalışan diğer botlara engel olmak. Bir bot eklendiğinde veya kaldırıldığında, tüm oluşumun Botların koşuşturması ve karmaşasının uzaktaki hedeflerine ulaşması için bir karışıklık olacağından endişe ediyorum.
Tiby312

2
Her zaman yeni konumları hesaplayabilir, ardından en yakın botu doğrusal bir yineleme yapmak yerine o konuma taşıyabilirsiniz.
Exilyth

Kare bir hesaplama ile bitmeden bunu nasıl yapabilirim? Eğer doğru anlıyorsam, her Bot için 2d dizisindeki mevcut konumlarından 2d dizisindeki en yakın konumu bulmak zorunda kalacaktım.
Tiby312

Her yinelemede, bir birim atanır (ve bu nedenle başka yinelemelerde dikkate alınması gerekmez), dolayısıyla çalışma zamanı O (n!) Olur. Bu hala çok iyi değil. Sonra tekrar, bir [seçim optimizasyon yapısı] oluşturmak ve n aralık sorguları yapmak hızlı değildir. Şu anda aklıma gelen tek şey arka arkaya son botları arkaya taşımak ya da arka arkaya son sıraları arkaya botlarla doldurmak.
Exilyth

Buna ne dersin. Yeni formasyonun daha küçük satır boyutuna sahip olduğunu varsayalım. Sonra her sırada ekstra bir bot var. Bu botu bir aşağı ve bir sola atarsınız. Sonra bir sonraki satırda, yeriniz olmayan iki Botunuz var. Bu ikisini bir aşağı ve bir sola atarsınız. Sonra yer olmadan 3 bot var. Altta fazladan bir satır olana kadar devam edin. Ben sadece burada tükürüyorum. Tüm yol boyunca düşünmedim, ama işe yarayacak gibi görünüyor ve hızlı.
Tiby312

2

Olası pozisyonları daha büyük değerlerin daha küçük dikdörtgenler olduğu bir grafikte saklıyorum.

[4][3][2][1]
[3][3][2][1]
[2][2][2][1]
[1][1][1][1]

Her robot kaldırıldığında diğer tüm robotları ara ve en küçük değere sahip bir düğümde bul. A * ya da BST algoritmasını kullanarak en küçük değerden boş alana doğru bir yol bulabilirsiniz. Kaldırılandan daha küçük bir değere sahip bir robot yoksa hiçbir şey yapmayın.

Ayrıca, dikdörtgenin bunu nasıl bozduğunu da kontrol edebilmelisiniz. Örneğin, aşağıdaki grafikte bir robot alttan bir yandan çıktığında yerini dolduracaktır.

[4.9][3.8][2.7][1.0]
[4.8][3.7][2.6][1.0]
[3.9][3.6][2.5][1.0]
[3.5][3.4][2.4][1.0]
[2.9][2.8][2.3][1.0]
[2.0][2.1][2.2][1.0]
[1.9][1.8][1.7][1.0]
[1.6][1.5][1.4][1.0]

Burada 3.8'deki olan kaldırılır, böylece 2.5'teki olan gelir ve yerini doldurur.

[o][x][o][ ]
[o][o][o][ ]
[o][o][r][ ]
[o][o][ ][ ]
[o][o][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

Başka bir örnek. Burada 2.8 çıkarılır, böylece en küçük düğüm 2.2 yerini doldurur.

[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][x][r][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

Büyük olasılıkla, yol bulma algoritmanızın deliği bulması için dışarıda hiç doldurmadığınız 0 değerine sahip bir düğüm halkası istiyorsunuz.

[0.0][0.0][0.0][0.0][0.0][0.0]
[0.0][4.9][3.8][2.7][1.0][0.0]
[0.0][4.8][3.7][2.6][1.0][0.0]
[0.0][3.9][3.6][2.5][1.0][0.0]
[0.0][3.5][3.4][2.4][1.0][0.0]
[0.0][2.9][2.8][2.3][1.0][0.0]
[0.0][2.0][2.1][2.2][1.0][0.0]
[0.0][1.9][1.8][1.7][1.0][0.0]
[0.0][1.6][1.5][1.4][1.0][0.0]
[0.0][0.0][0.0][0.0][0.0][0.0]

A * hakkında iyi bir eğitim burada bulunabilir .


Bu tatlı bir fikir, ama bunu doğru anlıyorsam, mükemmel dikdörtgenler olmayan oluşumlara izin veriyorsunuz. Kenarlıklardaki satırlar ve sütunlar dolu olmayabilir. Bunu her zaman dikdörtgen bir kenarlığa sahip olacak şekilde yapabileceğimi ve bunun yerine satır ve sütun sayısını değiştirerek bu gereksinimi karşılamak için en boy oranını biraz değiştirebileceğimi düşünüyordum. Bunu başaracak yeni genişlik ve yüksekliği zaten hesaplayabilirim, ancak daha sonra botları en yakın noktaya yeniden atamanın karmaşık bir yolu var ... sanırım.
Tiby312

@ Tiby312 7 robot ile nasıl mükemmel bir dikdörtgen yapmayı planlıyorsunuz?
ClassicThunder

ASLA Asal sayıları unuttum. Afedersiniz. Ama yine de satır ve sütun sayısını ayarlamanın, sıra dışı düşük sayıda botu olan bir satır veya sütundan kaçınabileceğini düşünüyorum.
Tiby312

@ Tiby312 Her zaman mükemmel bir dikdörtgen yapmaya çalışmak yerine tutarlı bir en boy oranı (her zaman 4: 3 veya 8: 5) hedeflemekten daha iyi olduğunu düşünüyorum.
corsiKa
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.