Мультиагентные системы или «Как завалить мамонта, имея толпу тупых неандертальцев». Часть 1

Нахождение обратной матрицы

Для начала, ответим на вопрос: «А в чем вообще новизна мультиагентных систем? Почему нам не решать задачи классическими методами искусственного интеллекта?».

Большинство существующих подходов к созданию искусственного интеллекта тем или иным образом пытаются спроектировать «Сверхмозг», «Божественный объект», который как бравый голливудский супергерой в одиночку перебьет все стоящие перед ним задачи. Он и столяр, и плотник, и на мышей охотник. Однако, как мы знаем в реальности такое происходит не часто, и большая универсальность означает слабые умения во всех областях, или огромные затраты на обучение или проектировку такого чуда.

Что же предлагает нам мультиагентная система? Она предлагает нам, вместо одного гения использовать тысячу «идиотов», которые умеют работать в вот такой узенькой-узенькой области, но зато знают свое дело хорошо. Этот народ, объединяется в коллективы, распадается, пересобирается в другие, общается с другими агентами, меняет профессии, получает профит за успешную работу, или терпит «пощечину» за неудачную. То есть происходит моделирование динамических социальных отношений в мирке агентов.

Что же это нам дает? Как показывает практика, и народная мудрость – «Одна голова хорошо, а две – лучше», конкатенация не очень умных агентов позволяет решать задачи гораздо более сложные, которые даже не снились самому умному агенту в системе.

Ну что же, хватит слов. Давайте попробуем написать каркас для построения простенькой мультиагентной системы. Писать будем на языке C#. В данной статье мы покажем основную структуру агентов, без рассмотрения взаимодействий между ними.

В начале опишем общий вид агентов:

interface IAgent { bool isStarted { get; set; } Guid Id { get; set; } IRealObject RealObject{get;set;} void start(); void stop(); void onMessage(); void action(); }

Этот минимум агента содержит следующие свойства и методы:

  • isStarted – показывает, является ли программный агент активным;
  • Id – уникальный идентификатор агента;
  • RealObject – ссылка на связанный с агентом объект, описывающий свойства моделируемого объекта реального мира;
  • Start () – активирование агента;
  • Stop () – деактивирование агента;
  • onMessage () – обработка принятых сообщений;
  • action () – действия агента.

Действия агента и обработка сообщений делегируется объекту поведения:

interface IBehavior { void Action(MAS.RealObjects.IRealObject realObject); void OnMessage(MAS.RealObjects.IRealObject realObject); }

Интерфейс IRealObject описывает общую структуру, присущую всем объектам, описывающих моделируемые объекты. В данном случае интерфейс весьма краток:

interface IRealObject { Guid Id { get; set; } }

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

class Chief:IRealObject { public enum ChiefCondition { Headhunter, Manager } public ChiefCondition Condition { get; set; } public Guid Id { get; set; } public string Name { get; set; } public Chief(Guid id, ChiefCondition condition) { Id = id; Condition = condition; } }

У вождя есть два состояния – когда он созывает народ на охоту, и когда он, собственно, управляет охотниками. В зависимости от своего состояния, вождь действует по-разному. Это отражается в написании классов поведений для каждого состояния. Реализация поведений и обработки сообщений для простоты опустим, но уже здесь можно видеть, роль особого типа агентов – координатора, который в основном только координирует действия агентов, путем коммуникации, но сам не проводит никаких активных действий к решению задачи.

class ManagerBehavior:IBehavior { public void Action(MAS.RealObjects.IRealObject chief) { Console.WriteLine("Бьем мамонтов! Ты – иди копай. Вы – гоните мамонта к яме!"); }
public void OnMessage(MAS.RealObjects.IRealObject chief) { //Обработка сообщений от рабочих о текущей ситуации } }
class HeadhunterBehavior:IBehavior { public void Action(MAS.RealObjects.IRealObject chief) { Console.WriteLine("Кто идет на мамонтов? Мне нужен лучник, метатель копей, копатель ям, закидыватель камнями."); } public void OnMessage(MAS.RealObjects.IRealObject chief) { //Обработка ответов кандидатов, и выбор подходящих } }

Наконец, опишем самого агента:

class ChiefAgent:IAgent { public bool isStarted { get; set; } public Guid Id { get; set; } public IRealObject RealObject { get; set; }
public ChiefAgent(Guid id, Chief realObject) { Id = id; RealObject = realObject; }
public void start() { isStarted = true; }
public void stop() { isStarted = false; }
public void onMessage() { if (isStarted) { switch ((RealObject as Chief).Condition) { case Chief.ChiefCondition.Headhunter: { new MAS.Behaviors.ChiefsBehavior.HeadhunterBehavior().OnMessage(RealObject); break; }
case Chief.ChiefCondition.Manager: { new MAS.Behaviors.ChiefsBehavior.ManagerBehavior().OnMessage(RealObject); break; } } } } public void action() { if (isStarted) { switch ((RealObject as Chief).Condition) { case Chief.ChiefCondition.Headhunter: { new MAS.Behaviors.ChiefsBehavior.HeadhunterBehavior().Action(RealObject); break; } case Chief.ChiefCondition.Manager: { new MAS.Behaviors.ChiefsBehavior.ManagerBehavior().Action(RealObject); break; } } } } }

На этом моменте закончим первую статью из цикла. Пока ничего особенного, однако, самое интересное еще впереди, Товарищ.

Автор: Multinodus.
Свои комментарии по содержанию статьи отправляйте непосредственно автору материала на почту: multinodus@gmail.com.

Прокрутить вверх