Что я ищу
У меня есть 300 или менее дисков с одинаковым радиусом на плоскости. В момент 0 каждый диск находится в положении. В момент 1 каждый диск находится в потенциально различном положении. Я ищу, чтобы создать 2D-путь для каждого диска в промежутке времени от 0 до 1, так что диски не пересекаются, и пути, по возможности, относительно эффективны (короткие) и имеют низкую кривизну. (например, прямые линии предпочтительнее squiggly линий)
- Более низкое время вычисления, как правило, более важно, чем точность решения. (например, небольшое пересечение в порядке, и мне не обязательно нужен оптимальный результат)
- Однако диски не должны телепортироваться друг к другу, останавливаться или замедляться внезапно, или резко менять направление - "более гладко", тем лучше. Только исключение - это время 0 и 1.
- Пути могут быть выражены в выборочной форме или кусочно-линейной природе (или лучше) - меня не волнует наличие действительно гладких путей через сплайны. (Я могу аппроксимировать это, если мне так нужно.)
Что я пробовал
Вы можете увидеть демо моей лучшей попытки (через Javascript + WebGL). Будьте осторожны, он будет медленно загружаться на старых компьютерах из-за проведенных вычислений. Он работает в Firefox/Chrome/IE11 под Windows.
В этой демонстрации я представлял каждый диск как "эластичную группу" в 3D (т.е. каждый диск имел позицию в каждый момент времени) и запускал простой движок физики в стиле игры, который устраняет ограничения и обрабатывает каждую точку в время как масса с пружинами в предыдущий/следующий раз. ( "Время" в этом случае является только третьим измерением.)
Это действительно хорошо работает для небольших N (< 20), но в обычных тестовых случаях (например, начинайте с дисков, расположенных по кругу, перемещайте каждый диск в противоположную точку на круге), это не позволяет создать убедительные пути поскольку ограничения и эластичность распространяются медленно по всем пружинам. (например, если я нарезаю время на 100 дискретных уровней, натяжение в эластичных полосах распространяется только на один уровень за каждый цикл моделирования). Для хороших решений требуется много ( > 10000) итераций, и это утомительно медленно для моего приложения. Он также не может разумно разрешить многие случаи N > 40, но это может быть просто потому, что я не могу выполнить достаточно итераций.
Что еще я пробовал
Моя первоначальная попытка - это альпинист, который начинался с линейных дорожек, которые постепенно мутировали. Решения, которые измерялись лучше, чем лучшее в настоящее время решение, заменили лучшее в настоящее время решение. Более высокие измерения были обусловлены количеством пересечений (то есть полностью перекрывающимся, измеренным хуже, чем просто выпасом) и длиной путей (более короткие пути были лучше).
Это произвело некоторые удивительно хорошие результаты, но неудовлетворительно, вероятно, очень часто застревает в локальных минимумах. Это было очень медленно при N > 20. Я попытался применить несколько методов (имитированный отжиг, подход к генетическим алгоритмам и т.д.), Пытаясь обойти проблему локальных минимумов, но у меня никогда не было большого успеха.
Что я пытаюсь
Я оптимизирую модель "эластичной ленты", чтобы растяжение и ограничения распространялись гораздо быстрее в измерении времени. Это во многих случаях сэкономило бы много необходимых итераций, однако в сценариях с высокой степенью ограничения (например, многие диски, пытающиеся пересечь одно и то же место), все равно потребуется несостоятельное количество итераций. Я не разбираюсь в том, как быстрее решать проблемы или распространять пружины (я пробовал прочитать несколько работ по моделированию без растягивания ткани, но я не смог выяснить, применимы ли они), поэтому я бы если у вас есть хороший способ сделать это.
Идеи на столе
- Спектр реализовал очень быстрый алгоритм движения в стиле RTS, который работает превосходно. Он быстрый и элегантный, однако он страдает от проблем стиля RTS-движения: внезапное изменение направления, блоки могут резко остановиться, чтобы разрешить столкновения. Кроме того, юниты не все прибывают в пункт назначения одновременно, что является, по сути, резкой остановкой. Это может быть хорошей эвристикой для создания жизнеспособных негладких путей, после чего пути могут быть повторно отобраны во времени и может быть запущен алгоритм "сглаживания" (как и тот, который используется в моей демонстрации).
- Ашкан Кзме предположил, что проблема может быть связана с сетевыми потоками. Похоже, что проблема минимального расхода потокаможет работать, поскольку пространство и время могут быть подвергнуты критике разумным образом, а время работы может быть уменьшено. Преимущество здесь состоит в том, что он хорошо изучил множество проблем, но внезапные изменения скорости все равно будут проблемой, и может быть желательно какое-то "сглаживание" постэтапов. В камнем преткновения, который у меня сейчас есть, есть решение о сетевом представлении пространства-времени, которое не приведет к телепортации дисков друг через друга.
- Jay Kominek опубликовал ответ, в котором используется нелинейный оптимизатор для оптимизации квадратичных кривых Безье с некоторыми обнадеживающими результатами.