Як я можу підтримувати прямокутну формацію, коли додаються чи вилучаються одиниці?


18

У мене є боти прямокутної формації з рядками та стовпцями. Проблема виникає при додаванні або видаленні бота з формації. Коли це трапляється, боти повинні переставляти себе так, щоб прямокутне утворення все ще було приблизно таким же співвідношенням сторін і було максимально прямокутним. Як це зробити?

Деякі ідеї:

  • Коли бот додається чи видаляється, використовуйте нову загальну кількість ботів та бажане постійне співвідношення сторін, щоб обчислити нову ширину та висоту формації, що найбільш відповідає цьому співвідношенню сторін. Потім якось переставляйте ботів, щоб відповідати новим розмірам.

  • Коли бот буде видалений, перемістіть бота, який був за ним, на його місце, і продовжуйте, поки не досягнете кінця формування. Тоді навіть вийдіть із задніх рангів якомога більше, якось переміщуючи ботів у задньому ранзі.

  • Інша ідея, зовсім інша - це імітувати спосіб молекулярних структур залишатися разом. Зробіть так, щоб кожен бот захотів оточити чотирьох інших ботів, залучаючи чотири найближчих бота, а решту відштовхуючи. Відкажіть усі боти (включаючи чотирьох), які є занадто близькими, щоб забезпечити розділення, використовуючи зворотний закон прямокутника. Вам також знадобиться додаткова сила для формування всієї конструкції. Але це звучить обчислювально дуже дорого.

ОНОВЛЕННЯ : Отже, вивчаючи відповідь сарама, я придумав гарну загальну функцію, яка дає хороші виміри.

Спочатку я розв’язував нижченаведене одночасне рівняння для ширини та висоти, а потім округлював відповіді.

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

Це дає вам найближчий цілочисельний прямокутник до цього співвідношення для вашої кількості ботів. Найближчий прямокутник буде в половині часу занадто великим, а половина - занадто малим (звичайно, іноді це буде саме правильно, але кого це хвилює). У випадках, коли прямокутник трохи завеликий, нічого не потрібно робити. Задній ранг просто закінчиться майже повним, що ідеально. У випадках, коли прямокутник трохи замалий, у вас виникли проблеми, тому що для цього маленького крихітного переливу доведеться перейти до власного рангу, створивши рейтинг із кількома ботами на ньому, що виглядає не дуже сильно. Бувають також випадки, коли різниця велика(більша, ніж половина ширини), у цьому випадку додайте або віднімайте одне ранг, щоб зробити різницю невеликою. Потім, коли прямокутник занадто малий, додайте один стовпчик, щоб зробити його трохи більшим. Після цього схоже, що у задніх рангів завжди буде щонайменше половина більшої кількості ботів, ніж у інших рангів.

ОНОВЛЕННЯ

Після отримання розмірів порівняйте їх із поточними розмірами. Якщо фронтація нового виміру більша, для кожного рангу поп-ботів із нижнього рангу і натисніть їх на поточний ранг до тих пір, поки кількість ботів цього рангу не буде дорівнює фронтації. Продовжуйте цей алгоритм, поки ви не дістанетесь до зворотного рейтингу. Використовуючи цей алгоритм, боти перемістяться, щоб ефективно вписатись у новий вимір. Після цього я просто натискаю нову стару на задній ранг. Алгоритм дещо відрізняється для тих випадків, коли новий фасад менше, але ви можете це зрозуміти!

Наступні ще дві проблеми. Видалення та більш гнучкий метод додавання, коли нові боти не обов'язково присвоюються до задніх рангів, але те, яке положення є найближчим до них на момент додавання.


Яка максимальна кількість ботів в одиниці? Якщо він порівняно невеликий, ви можете жорстко кодувати, скільки рядків і стовпців має формація для певної кількості ботів.
Exilyth

3
Чи можете ви опублікувати зображення формацій, які є дійсними проти недійсних? У мене виникають невеликі проблеми з розумінням того, що ти хочеш. Чи дозволені неповні рядки / стовпці?
MichaelHouse

3
Ви розумієте, що це не буде працювати для простих чисел? наприклад, із 7 ботів, вам доведеться зробити 3x2 одиницю з одним ботом на спині.
Exilyth

1
Ну це бентежить. Я повністю забув про прості числа. Тоді, можливо, наступним найкращим моментом буде дозволити лише рядки та стовпці, які заповнені ЗАМЕЧНО. Один Bot у ряду не виглядає правильно, але один менше Bot у ряду не виглядатиме погано.
Tiby312

3
Прості номери - не єдині, що створюватимуть проблеми - вибір розміру формату шляхом факторингу може дати вам необґрунтовано довгі та худі утворення. Наприклад, якщо у вас 14 ботів, єдине ідеальне прямокутне утворення - це 7x2, тоді як може виглядати краще формування 3x4 з додатковим рядом у 2 боти.
Натан Рід

Відповіді:


16

Інша техніка - це імітувати те, що застосовувалося наполеонівськими батальйонами (і, мабуть, аж до грецьких фалангів, якщо не далі).

Лицьовий фронт, як правило, підтримується постійним, і коли людина падає (в будь-якому званні, крім спини), його заміняє чоловік безпосередньо за ним, крокуючи вперед. Задній ранг переміщується офіцерами НСО, щоб забезпечити декількох чоловіків на крайній частині кожного флангу і в іншому випадку заповнити рівномірно.

Лицьова сторона зменшується лише тоді, коли тильний рядок опускається нижче заздалегідь заданої щільності. Так само, коли зворотний ранг переповнюється, макси спочатку починають заповнювати додатковий ранг з обох флангів, а потім фронт збільшують.

Під час зміни фронтації я пропоную вашим ботам вивести файл із зворотного рангу на обидва боки при збільшенні фронтажу та подавати з обох флангів на задній ранг при зменшенні фронтації.

Якщо я вірно вважаю, що ви шукаєте «військове» враження, і якщо ваші ботові організації виглядають як фаланги, я вважаю, що це впорядкована перестановка - кращий спосіб досягти цієї мети.

Оновлення .
Один з простих способів управління заднім рядом - поділити одиниці заднього ряду на три загони: по одному на кожному фланзі та по одному в центрі. Залежно від того, чи фронтація непарна або парна, і чи кількість одиниць заднього ряду збігається з 0,1, або 2 мод 3, потрібно керувати рівно шістьма випадками.

Як доповнення до вищезазначеного, розгляньте пробіл останньої одиниці кожного загону, коли заповнення опуститься нижче порогового рівня, як-от так:
xxx.x .... x.xxx.x .... x. xxx
або це:
xx.xx..x.xxx.x ... xxxx
Трохи більше роботи для ще кращого вигляду.

Оновлення №2 :
додаткова думка про глибину формування. Вплив вогневого вогню в поєднанні з сучасним багнетом зробив глибину 3 або 4 адекватною в кінці 18 - на початку 19 століття. (Британці рідко воювали в 2 ряди, всупереч поширеній думці, до пізнього бою; для одного вони робили їхні лінії занадто довгими, щоб швидко утворювати квадрат.) До цього звичайно було великі глибини, можливо, до 8 або 10 для грецької фаланги, оснащеної Саріссою. Виберіть глибину, яка створює враження, якого ви бажаєте.

Армії в реальному житті намагаються зберегти фронтацію підрозділів якомога довше за рахунок посилення крихкості підрозділів, оскільки це полегшує розміщення поля бою. Цезар у Фарсала навмисно зменшив глибину своєї одиниці, щоб збільшити фронт, щоб відповідати силам Помпея. Як свідчить цитата: "Ми сьогодні перемагаємо чи помремо; у чоловіків Помпея є інший вибір". (що, звичайно, Цезар розумно і ретельно забезпечив).


Це звучить як набагато більш елегантне рішення. Немає необхідності суєти про прості числа чи співвідношення сторін, і все-таки він уникає будь-якої рядки, на якій є незвично низька кількість ботів, і єдина умова, яку потрібно перевірити, - наскільки повною є зворотна транзакція!
Tiby312

Але тримайся. Скажіть, у тиловому рейтингу є лише 3 боти, вони містяться в стовпцях 1, 2 і 3. І я вилучаю когось із 5-ї колони, когось біля фронту. Я закінчив би вільне місце на другому до останнього ряду у 5-й колонці, не маючи бота за ним, щоб зайняти це місце. Хто повинен заповнити це місце?
Tiby312

Імовірно, найближчий бот із зворотного рангу (тобто той, що у колонці 3) повинен працювати для його заповнення. Або ви можете заощадити трохи часу, розмістивши ботів у стовпцях 3 та 4 другого та останнього рангу кожен крок по одному стовпчику вгору, переміщуючи пробіл до стовпця 3, а потім отримайте бот у стовпці 3 кроком вперед, щоб заповнити це. (ІМО, найбільш "природно" виглядає стратегія, мабуть, буде якась евристична комбінація двох, можливо, з деякою випадковістю.)
Ільмарі Каронен

1
Якщо заднім чином є занадто мало членів (скажімо, менше 50% від інших рангів), і ви збільшуєте фронт, це гарантовано виправить проблему, чи можливо, що в задньому ранзі все- таки буде занадто мало членів після збільшення фронт, що вимагає його повторення чи щось таке?
Tiby312

1
@ Tiby312: Я вірю, що ти надмірно думаєш про це. Спробуйте, знаючи, що ви завжди можете це налаштувати пізніше
Пітер Геркенс,

7

Припустимо, що одиниця - це лінійна структура даних (наприклад, список ) ботів.

По-перше, ви повинні додати / вилучити бота до / з структури даних та визначити нову кількість ботів у підрозділі.

Потім потрібно визначити нову кількість рядків і стовпців за допомогою https://en.wikipedia.org/wiki/Integer_factorization .

Звичайно, це не завжди можливо через прості числа . Коли новий розмір одиниці є простим числом, вам потрібно використовувати наступний більший розмір одиниці, який не є.

Потім просто повторіть структуру даних, призначивши боти для рядків та стовпців.

Для розміщення ботів просто повторіть структуру даних, призначивши кожному боту зміщення позиції від позиції одиниць на величину, визначену рядком і стовпцем, в якому знаходиться бот (або встановіть цю точку як ціль руху ботів).

Щоб скласти одиницю з центром в одному куті , позиція бота задається знаком

unitPosition + заголовок * ColumnNumber * botSeparationDistance + rightVector * ROWNUMBER * botSeparationDistance

Щоб скласти одиницю з центром посередині , положення бота задається знаком

unitPosition + заголовок * (* ColumnNumber unitSeparationDistance - 0,5 * (numberOfColumns * botSeparationDistance) + rightVector * ROWNUMBER * botSeparationDistance - 0,5 * (* numberOfRows botSeparationDistance)

де заголовок являє собою вектор , який вказує в напрямку блок стикається і rightVector є вектором , перпендикулярним до статті .

botSeparationDistance можна налаштувати, щоб боти стояли далі один від одного або ближче один до одного.

Якщо ви відчуваєте фантазії, ви можете компенсувати останній рядок бот на rightVector * 0,5 * (numberOfColumns - actualNumberOfBotsInRow) до центру їх на формуванні .


Це дуже близько до того, що я шукаю! Єдине моє застереження - це те, що при призначенні нових позицій бот, що знаходиться праворуч від одного ряду, може бути призначений в лівій частині наступного ряду в новому прямокутнику, в результаті чого Бот мав проїзд на велику відстань і в процесі перешкоджаючи іншим ботам, які намагаються досягти своєї власної призначеної позиції. Я переживаю, що коли бот буде доданий або видалений, все формування буде невдалим, коли Боти метушаться, щоб дістатися до свого далекого місця призначення.
Tiby312

2
Ви завжди можете обчислити нові позиції, а потім перемістити найближчий бот до цієї позиції, а не робити лінійну ітерацію.
Exilyth

Як це зробити, не закінчуючи обчисленням у квадраті? Мені доведеться знайти найближче положення в 2d масиві від їх поточного положення в 2d масиві для кожного Bot, якщо я правильно це розумію.
Tiby312

У кожній ітерації призначатиметься одна одиниця (і, таким чином, не потрібно розглядати її при подальшій ітерації), таким чином час виконання буде O (n!). Що все-таки не дуже добре. Знову ж таки, побудова [оптимізаційної структури вибору] та виконання n діапазонів запитів також не швидко. Єдине, про що я зараз можу подумати - це переміщення останніх ботів підряд на задню частину або заповнення останніх місць підряд ботами ззаду.
Exilyth

Як щодо цього. Скажімо, новоутворення має менший розмір рядків. Потім у кожному ряду у вас є додатковий бот. Ви присвоюєте цього бота одним униз, а одним ліворуч. Потім у наступному ряду вниз у вас є два боти без місця. Ви призначаєте ці дві вниз, а одну вліво. Тоді ви отримали 3 бота без місця. Продовжуйте, поки у вас внизу зайвий рядок. Я просто плюю куля. Я не думав, що це все наскрізь, але це здається, що це буде працювати і швидко.
Tiby312

2

Я б зберігав можливі позиції у графіку з більшими значеннями, меншими прямокутниками.

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

Кожен раз, коли робот видаляється, шукайте, хоча всі інші роботи знаходять його у вузлі з найменшим значенням. Використовуйте алгоритм A * або BST, щоб знайти його шлях від найменшого значення до вільного простору. Якщо робота не має меншого значення, ніж вилучений, нічого не робити.

Ви також повинні мати можливість контролювати, як прямокутник розпадається, роблячи це. Наприклад, на графіку нижче, коли робот залишає нижню частину збоку, зайшов би його місце.

[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]

Тут видаляється той, що на 3.8, тому приходить в 2.5 і заповнює своє місце.

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

Ще один приклад. Тут видаляється 2.8, тому найменший вузол 2.2 заповнює своє місце.

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

Ви, ймовірно, хочете кільце з вузлів зі значенням 0, яке ви ніколи не заповнюєте назовні, щоб ваш алгоритм пошуку маршрутів знаходив отвір.

[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 * можна знайти тут .


Це приємна ідея, але якщо я правильно це розумію, ви дозволяєте формувати, які не мають ідеальних прямокутників. Рядки та стовпці на межах можуть бути не заповненими. Я думав, що можу зробити так, щоб він завжди мав прямокутну межу, і замість цього трохи змінити співвідношення сторін, щоб задовольнити цю вимогу, змінивши кількість рядків і стовпців. Я вже можу обчислити нову ширину та висоту, яка б це досягла, але тоді є якийсь складний спосіб перепризначити ботів до найближчого місця. Я думаю.
Tiby312

@ Tiby312 Як ви плануєте зробити ідеальний прямокутник із скажімо ... 7 роботів?
ClassicThunder

НІКОЛИ Я не забув про прості числа. Вибачте. Але я все ще думаю, що регулюючи кількість рядків і стовпців, можна уникнути ряду чи стовпця, що має на ньому незвично малу кількість ботів.
Tiby312

@ Tiby312 Я думаю, що вам краще прагнути до постійного співвідношення сторін (тобто завжди 4: 3 або 8: 5), ніж намагатися завжди робити його ідеальним прямокутником.
corsiKa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.