Привет, Хабр! Сегодня мы погрузимся в увлекательный мир роевого интеллекта и децентрализованных систем. Я покажу, как простые правила, заложенные в каждый элемент системы, позволяют добиться сложного группового поведения без единого центра управления. В качестве полигона используем виртуальный рой автономных дронов.
*Код и симуляция: Python 3.8+, matplotlib, numpy
Проблема централизованного управления
Представьте, что вам нужно координировать движение 50 дронов. Первое, что приходит в голову — центральный контроллер с нейронной сетью, которая вычисляет оптимальные траектории для каждого аппарата. Но у этого подхода есть фундаментальные недостатки:
Единая точка отказа — выход контроллера из строя парализует всю систему
Вычислительная сложность — задача O(n²) и выше для n агентов
Низкая отказоустойчивость — потеря связи с одним дроном может нарушить весь план
Плохая масштабируемость
Альтернатива? Децентрализованное управление, где каждый дрон принимает решения самостоятельно, основываясь лишь на информации от ближайших соседей.
Три кита роевого интеллекта
В основе нашего подхода лежат три простых правила, вдохновленных поведением стай птиц и косяков рыб:
1. Избегание столкновений
Самый приоритетный rule: не врезаться в соседей.
# Упрощенная логика отталкивания
if dist < self.desired_distance:
repulsion = True
k = (self.desired_distance / dist)**3
dx = drone.x - n.x
dy = drone.y - n.y
repulsion_x += (dx / dist) * k
repulsion_y += (dy / dist) * k
Обратите внимание на кубическую зависимость (**3) — чем ближе сосед, тем сильнее отталкивание. Это создает "буфер безопасности" вокруг каждого дрона.
2. Сплочение группы
Если соседи слишком далеко — приближаемся к ним, поддерживая целостность группы:
# Упрощенная логика сплолчения группы
if dist > self.desired_distance * 1.2:
k = k * self.desired_distance / (dist - self.desired_distance)
dx = n.x - drone.x
dy = n.y - drone.y
attraction_x += k * dx / dist
attraction_y += k * dy / dist
Ближайшие соседи более приоритетны, что обеспечивается знаменателем коэффициента.
3. Движение к цели
Каждый дрон знает общую цель (в нашем случае — координаты [0,0]) и постепенно смещается к ней:
dist = np.sqrt((drone.x- target.x) ** 2 + (drone.y - target.y) ** 2)
if dist > 0:
striving_x = - drone.x * k
striving_y = - drone.y * k
Архитектура системы
Давайте разберем основные компоненты нашей симуляции:
Класс Drone — кирпичик роя
class Drone:
def __init__(self, id, x=0, y=0):
self.id = id
self.x = x
self.y = y
self.vx = 0
self.vy = 0
self.radius = 0.3
self.active = True
Каждый дрон знает только свою позицию и статус. Никакой информации о глобальной структуре!
Swarm — emergent intelligence
Класс Swarm не управляет дронами напрямую. Вместо этого он обеспечивает среду для их взаимодействия.
Дальность локально взаимодействия дронов ограничена параметром self.neighbor_radius:
def find_neighbors(self, drone):
"""Возвращает список ближайших активных дронов"""
neighbors = []
for d in self.drones:
if d.active and d != drone:
if drone.distance_to(d) < self.neighbor_radius:
neighbors.append(d)
return neighbors
В пределах этого радиуса соседние дроны считаются частью группы.
Эмерджентное поведение в действии
Что удивительно — из простых локальных правил рождается сложное глобальное поведение:
Самоорганизация — изначально случайное расположение быстро структурируется
Адаптивность — при потере дронов система автоматически перестраивается
Устойчивость — даже при выходе 30% дронов из строя группа продолжает движение
В коде выход из строя моделируется простым механизмом отказов:
def simulate_failure(self):
for drone in self.drones:
if drone.active and random.random() < self.failure_rate:
drone.active = False
Визуализация: наблюдаем за происходящим
Класс Visio позволяет в реальном времени наблюдать ход моделирования:
class Visio:
def __init__(self, swarm):
self.swarm = swarm
# Настройка визуализации
self.fig, self.ax = plt.subplots(figsize=(12, 8))
self.ax.set_xlim(-20, 20)
self.ax.set_ylim(-20, 20)
self.ax.set_title("Рой дронов: автономное перестроение")
self.ax.set_xlabel("X")
self.ax.set_ylabel("Y")
self.drone_dots = self.ax.plot([], [], 'bp',
markersize=8,
alpha=0.6,
label='Активные дроны')[0]
self.failed_dots = self.ax.plot([], [], 'ks',
markersize=4,
alpha=0.3,
label='Потерянные дроны')[0]
self.obstacle_dots = self.ax.plot(
[o[0] for o in swarm.obstacles],
[o[1] for o in swarm.obstacles],
'rx', markersize=10, label='Опасный район'
)[0]
self.target_dots = self.ax.plot([0], [0], 'gx',
markersize=10,
label='Целевой район')[0]
self.ax.legend()
self.ani = FuncAnimation(self.fig,
self.animate,
frames=2000,
init_func=self.start,
blit=True,
interval=1)
def start(self):
self.drone_dots.set_data([], [])
self.failed_dots.set_data([], [])
return self.drone_dots, self.failed_dots
def animate(self, frame):
self.swarm.update()
active_x, active_y = [], []
failed_x, failed_y = [], []
for drone in self.swarm.drones:
if drone.active:
active_x.append(drone.x)
active_y.append(drone.y)
else:
failed_x.append(drone.x)
failed_y.append(drone.y)
self.drone_dots.set_data(active_x, active_y)
self.failed_dots.set_data(failed_x, failed_y)
return self.drone_dots, self.failed_dots
self.swarm - объект класса Swarm
self.swarm.update() - метод, реализует логику трех правил, описанных выше.
На анимации вы увидите, как:
Дроны самоорганизуются из хаотичного облака в структурированную группу
Группа обтекает препятствия без централизованного планирования
Потерянные дроны (черные квадраты) остаются на месте, а живые продолжают движение


Практическое применение
Описанный подход не просто академическое упражнение. Он может применяться в:
Сельском хозяйстве — рои дронов для мониторинга полей
Поисково-спасательных операциях — покрытие больших территорий
Логистике — доставка грузов группами дронов
Охрана и наблюдение — наблюдение на объекте с подвижных камер
Что можно улучшить?
Наша симуляция — лишь первый шаг. В реальных системах нужно учитывать:
Коммуникационные задержки — в реальности информация передается не мгновенно
Ограниченный обзор — дроны «видят» не идеально
Энергетические ограничения — время автономной работы
Динамические препятствия — движущиеся объекты
Заключение
Роевой интеллект демонстрирует удивительный принцип: сложное поведение не требует сложного управления. Простые правила, выполняемые на локальном уровне, создают робастные системы, устойчивые к сбоям и адаптивные к изменениям.
Код из статьи — упрощенная иллюстрация, но он позволяет уловить суть подхода. Главное — не конкретные коэффициенты (их нужно подбирать под задачу), а сам принцип децентрализованного управления.
А вы сталкивались с роевыми системами на практике? Делитесь опытом в комментариях!
Комментарии (18)

aax
24.11.2025 07:25Python, при всем его удобстве, да пригоден лишь для симуляции. Но никак для выполнения критичных по времени задач в системах реального времени, тем более с железом в виде типичного одноплатника на дроне.

MAXH0
24.11.2025 07:25Забавное приложение:
«Системы оружия двадцать первого века, или Эволюция вверх ногами»хотя начинать стоит, конечно же с «Непобедимый»
Но я настоятельно рекомендую к прочтению в нынешних реалиях именно "Системы..."

VAF34
24.11.2025 07:25Хотелось бы поиграть на своем ПК, но показаны только фрагменты. Класса Swarm не увидел.

ncix
24.11.2025 07:25сложное поведение не требует сложного управления.
Верно, но сложное поведение само по себе не создает способности к решению сложных задач.

el_mago
24.11.2025 07:25При использовании аттрактора в целевой точке и потенциальных полей можно получить похожие построения. Сложность начинается, например, когда нужно выполнить задание из нескольких целей в неопределенной среде с меняющимся количеством беспилотников, удерживая заданную формацию и состав.

Ekzarx Автор
24.11.2025 07:25Есть способы как реализовать и несколько параллельных и последовательных целей.
Насчёт удержания формации - это как раз противоречит децентрализованному управлению. Формация жёстко не задаётся, в этом и преимущество гибкости. Если всё же нужна жёсткая формация, то наверное надо считать такую группу единичным элементом роя, а не составным.

Germanjon
24.11.2025 07:25Не увидел явного указания "Опасного участка" и не понял, как дроны его "обходят". Понимаю, что если внезапно пропал сосед, то "притяжение" с его стороны ослабнет и все остальные будут "расползаться". Но это не спасает от того, что остальные дроны будут проходить через опасный участок.
По-хорошему, нужно бы добавить паттерн "Если потеряна связь с соседом и потеря продолжается больше Х тактов, то пометить его последние координаты как опасную зону и передать другим коллегам". А дальше - уже вопрос пятый: как обходить опасные зоны, снижать уровень опасности со временем и тд.

Ekzarx Автор
24.11.2025 07:25В данном упрощённом алгоритме опасные зоны заданы заранее и статичны. Визуально отмечены красными крестиками.
Ваша идея с отслеживанием потери связи с соседями - один из возможных путей реализации в реальных задачах.

TDen
24.11.2025 07:25А зачем дронам собираться в кучу, если каждый из них и так знает где конечная цель?
По отдельности они и территорию больше покроют (нет пересекающихся областей наблюдения). Зачем рой?
shlmzl
24.11.2025 07:25А зачем дронам собираться в кучу, если каждый из них и так знает где конечная цель?
Каждый не знает, они знают коллективно, каждый что-то свое, с чем ему повезло больше, чем другим. Например пролетел над сооружением в котором есть телевизор или холодильник, который через вайфай передал ему инфу. А в совокупности т.е. коллективно они уже знают достаточно.

Ekzarx Автор
24.11.2025 07:25В кучу они всё же не сбиваются, а держатся на неком оптимальном расстоянии. Это расстояние можно установить любое.
Если не устанавливать его вовсе (вернее, установить в бесконечность), то элементы роя будут просто бесконечно отдаляться друг от друга. Движение роя в таком случае будет напоминать что-то вроде "взрыва в 2D".

Urmanov_t
24.11.2025 07:25Пружинный алгоритм. 2D. Для того, чтобы понимать принципы - норм.
Но там нет сложного поведения, нет синхронизации дронов по времени. Да и сама формация роя все равно получается как кристаллическая решетка. А это уязвимость к целенаправленному выбиванию узлов этой решётки.
Плюс рекомендую выбивать в симуляции те дроны, которые являются хабами и посмотреть на целость роя.
Проверить робастность к шуму, использовать в симуляции помехи.
Wizard_of_light
Клеточные автоматы на физическом железе.