En

Равновесие

Хаос

Сегодня я хочу показать интересную модель хаоса и равновесия. Правила следующие:

  • есть n точек на плоскости.
  • Каждая точка выбирает себе 2 случайные точки, которые будут её лидерами.
  • Каждая точка должна стараться быть всегда равноудалённой от своих лидеров.

Вот пример системы, состоящей из 4 точек:

Simulation screenshot

У зелёной точки лидеры - это 2 красные точки. Красная линия - линия, равноудалённая от лидеров. Цель зелёной точки - попасть и оставаться на красной линии. У всех точек лидеры различны, и их перемещения получаются весьма хаотичными. Но спустя некоторое время всё устаканивается, точки останавливаются, и наступает состояние равновесия. Теперь вопрос: что случится, если мы немного передвинем какую-либо точку? Как много потребуется времени, чтобы система опять пришла в состояние равновесия?

Я не настолько хорошо разбираюсь в математике, чтобы описать систему по-умному, но я всё же программист, так что давайте смоделируем это на Quil! Quil уже поддерживает кложурскрипт, так что скетчи могут быть легко добавлены на веб-страницу. Я не буду приводить исходные код в этом посте, только готовые скетчи. Ссылка на исходники будет в конце поста. Скетчи ориентированы на десктоп, так что вероятно они не будут работать адекватно на мобильных.

Скетч №1

Наведение мышкой на любую точку показывает лидеров этой точки. Так же можно перемещать точки, перетаскивая мышкой. Доступны следующий кейбиндинги:

  • space - пауза/продолжить;
  • r - перегенерировать точки;
  • стрелки вверх и вних - уменьшить/увеличить число точек и перегенерировать точки.

Не забудьте эмпирически получить ответы на вопросы, сформулированные ранее. Так же можно попробовать конфигурацию, состояющую только из 3 точек и увидеть, как она всегда собирается в равносторонний треугольник. Достаточно забавно.

Скетч №2

После какого-то времени скетч надокучивает. Сделаем его более динамичным, добавив постоянную скорость: каждая точка, кроме того, что она движется в сторону равноудаления, также будет постоянно двигаться в определённую сторону. Направление и скорость выбирается случайно. Ещё мы сделаем поверхность тороидальной: если точка выходит за левую границу - она появляется справа, за нижнюю - сверху. Вот скетч №2, которые реализует эти фичи:

Теперь мы наблюдаем вечный хаос: точки в постоянном движении тщетно пытающиеся достичь равновесия.

Скетч №3

До сих пор мы оперировали только точками, скучными чёрными кругами. Как на счёт того, чтобы добавить им хвосты? Хвост - это последние k позиций точки. И сделаем их цветными, потому что чёрные черви, хаотично ползающие по экрану - депрессивное зрелище. Время червей:

Используей левые и правую стрелку, чтобы изменить k - число точек в хвостах. Эти клавиши работают и в предыдущих скетчах тоже, так что можно превратить точки в червей там тоже.

Откуда взялась модель?

Я увидел её на лекции, посвящённой искусственному интеллекту. Моделирование происходило на самой аудитории: n человек собрались в центре комнаты, каждый выбрал себе по 2 лидера и начали движение. После нескольких минут всех наконец остановились. Потом лектор передвинул одного человека и всем пришлось менять свои позиции. Это заняло ещё пару минут. Лектор хотел показать, что окружающая среда ведёт себя подобным образом: если вывести из баланса какую-то его часть, то вся система превратиться в непредсказуемый хаос на какое-то время. Но наша модель показала обратное: если передвинешь точку - она в большинстве случаев быстро возвращается в исходную позицию, в то время как остальные точки не сильно двигаются. Так что в идеальных условиях равновесия достаточно устойчивое.

Детали реализации

Скетчи используют функциональный мод для Quil, так что все обновления состояния обрабатываются Quil'ом (я не вообще не использую атомов!). Ещё одна приятная фича - скетч полностью совместим с кложуром и кложурскриптом: если файл назвать файл equilibrium.clj - можно запускать его на кложуре, переименовать в equilibrium.cljs, скомпилировать и можно запускать в браузере! Но не так всё хорошо. Мне удобно работать над скетчем в кложуре, которые поддерживает перезагрузку на лету и позволяет менять части скетча не останавливая его. Но в конце мне нужно запускать скетч на кложурскрипте, чтобы можно добавить его в пост. И весьма утомительно постоянно копировать clj в cljs, когда поменял любую часть скетча и хочешь проверить в браузере. В результате я остановился на стрёмной комбинации линуксового watch, который копирует clj в cljs каждую секунду, и cljsbuild, который автокомпилирует cljs в js. Это работает, но смотрится достаточно ужасно. Интересно, можно ли как-то иметь один файл, которые будет распознаваться и кложуром и кложурскриптом? Я знаю, что можно использовать cljx для этих целей, но смотрится достаточно тяжело для такой несложной задачи. Или может надо просто нормально настроить emacs/cider + cljx интеграцию.

Исходный код доступен GitHub.

Опубликовано 09 Sep 2014

comments powered by Disqus