Оба эти вида архитектуры м огут использовать преи м у щ ества агентов, поскольку агенты представ л яют собой са м одостаточные, автоно м ные и рациональные программные структуры. Рациональность агентов зак л ючается в том, что им известно их назначение. И обычные объекты имеют це л ь, но агенты «знают», какова эта цель. Идентификация наз н аче н ия каждого аспекта ПО — вполне естественный процесс. На этане проектирования нетрудно продумать цель отдельной части ПО, и поэтому простейшая форма декомпозиции ПО состоит в том, чтобы назначить агенту его цель. Затем приходит черед понять, агентов какого класса лучше всего уполномочивать на выполнение той или иной работы. Поскольку агент— это единица модульности в агентно-ориентированной программе (agent-oriented program — АОР), то проблема распределения сводится к поиску средств взаимодействия множества агентов. Процесс проектирования исходного класса агента вбирает в себя все то, что необходимо для идентификации отдельных составных частей распределенной программы. Справившись с созданием агентов как действительно рациональных объектов, мы сможем воспользоваться преимуществами CORBA-спецификации для разработки действительно распределенных мультиагентных систем. CORBA скрадывает сложность распределенного программирования и взаимодействия посредством сетей (intranet Hlnternet). Обзор средств распределенного программирования с использованием CORBA-сиецификации приведен в главе 8. Поскольку агенты являются объектами, этот обзор CORBA-средств имеет силу и для агентов. В главе 6 рассмотрена система PVM (Parallel Virtual Machine — параллельнал виртуальная машина). Систему PVM также можно использовать для значительного упрощения взаимодействия между агентами, существующими в различных процессах или на разных компьютерах. Агенты можно реализовать как CORBA-объекты, либо их можно назначить отдельным PVM-процессам. В обоих случалх взаимодействие агентов упрощается в значительной степени. Если в одном приложении задействовано несколько агентов, то такое приложение представляет собой мультиагентную систему. Если агенты расположены на одном компьютере, то для взаимодействия между собой они могут использовать CORBA-, PVM- или MPI-средства (Message Passing Interface). Агенты в различных процессах также могут использовать такие традиционные методы межпроцессного взаимодействия (IPC), как FIFO-структуры, разделяемую память и каналы. В распределенном программировании есть три основные проблемы.
1. Идентификация декомпозиции ПО распределенного решения.
2. Реализация эффективного и рационального взаимодействия между распределенными компонентами.
3. Обработка исключительных ситуаций, ошибок и частичных отказов.
Несмотря на то что для реализации п. 2 в понятии класса агента нет ничего такого, что было бы свойственно только агентам, смысл п. 1 и 3 почти подразумевается в самой сути агента. Рациональность каждого агента определяет его назначение, а следовательно, и роль, которую он будет играть в решении ПО. Поскольку агенты самодостаточны и автономны, то хорошо продуманный класс агента должен включать необходимые меры по обеспечению их отказоустойчивости.
Агенты и параллельное программирование
При размещении агентов в среде с несколькими процессорами или параллельно выполняющимися потоками вы получаете такие же преимущества, как и при распределенном программировании, но с той лишь разницей, что сотрудничество между агентами программировать в этом случае гораздо проще. Для передачи сообщений между агентами, которые коллективно решают задачи некоторого вида, также можно использовать PVM- и MPI-среды. И снова-таки, рациональность агентов облегчает понимание, как следует провести декомпозицию работ для параллелизма. В параллельном программировании, как правило, встречаются такие проблемы.
1. Эффективное и рациональное разделение работы между несколькими компонентами.
2. Координация параллельно выполняющихся программных компонентов.
3. Разработка соответствующего взаимодействия (когда это необходимо) между компонентами.
4. Обработка исключительных ситуаций, ошибок и частичных отказов (если агенты функционируют на отдельных компьютерах).
Мультиагентные параллельные архитектуры часто характеризуются как слабосвязанные, т.е. им присущ минимум взаимодействия и взаимозависимости. Каждый агент знает свою цель и обладает методами для ее достижения. В то время как п. 3 не подвластен классу агента, п. 1, 2 и 4 можно легко управлять с помощью классов агентов. Например, при использовании агентов влияние п. 2 уменьшается, поскольку каждый агент рационален, имеет цель, а также способы и средства ее достижения. Поэтому вся ответственность смещается с алгоритма координации и управления на действия каждого агента. Влияние п. 4 также уменьшается, поскольку агенты самодостаточны, рациональны и автономны, а кроме того, хорошо продуманный класс агента должен включать необходимые меры по обеспечению отказоустойчивости агентов. Поскольку состояние агента инкапсулировано, ответственность за защиту критических разделов в объекте агента целиком воалагается на класс агента. Агент должен приводить в исполнение собственные стратегии доступа к данным. Возможные стратегии доступа, из которых могут выбирать агенты, перечислены в табл. 12.2.
Таблица 12.2. Стратегии доступа
EREW Монопольное чтение, монопольная запись
(Exclusive Read Exclusive Write)
CREW Параллельное чтение, монопольная запись
(Concurrent Read Exclusive Write)
ERCW Монопольное чтение, параллельная запись
(Exclusive Read Concurrent Write)
CRCW Параллельное чтение, параллельная запись
(Concurrent Read Concurrent Write)
Класс каждого агента должен определить, какал именно стратегия доступа приемлема в мультиагентной среде. В ряде случаев реализуются не просто отдельные стратегии доступа, перечисленные в табл. 12.2, а их комбинации. Это позволяетупростить параллельное программирование, поскольку разработчик может работать на более высоком уровне и не беспокоиться о построении мьютексов, семафоров и пр. Мультиагентные решения позволяют разработчику не погружаться в детали координации вызова каждой функции и организации доступа к данным. Каждый агент имеет цель. Каждый агент рационален, а следовательно, обладает определенной логикой для достижения своей цели. Процесс программирования в этом случае больше напоминает делегирование задач, а не координацию задач, которая характерна для традиционного параллельного программирования. Поскольку агентно-ориентированное программирование — это объектно-ориентированное программирование специального вида, применительно к агентам используется более декларативный вид параллельного программирования по сравнению с традиционным процедурно-ориентированным программированием, которое часто реализуется такими языками, как Fortran или С. Разработчик лишь определяет, что нужно сделать и какие агенты должны это сделать, т.е. выходит, что параллелизм практически сам заботится о себе. При этом всегда существует некоторый объем программирования, связанного с координацией и организацией взаимодействия, но агентно-ориентированное программирование сводит этот необходимый объем к минимуму. Однако обо всех этих «плюсах» можно говорить лишь при условии существования классов агентов. Очевидно, кто-то должен спроектировать классы агентов и написать их код. Теперь самое время разобраться в том, что должен содержать класс агента.
Базовые компоненты агентов
Агент объявляется с использованием ключевого слова class. Компоненты агента должны состоять из С++-членов данных и функций-членов. Логическая структура класса агента показана на рис. 12.1.
Класс агента (см. рис. 12.1) определяет типичные методы инициализации, чтения и записи, которые должен иметь практически любой объект. В «джентльменский набор» входят конструкторы, деструкторы, операторы присваивания, обработчики исключений и т.д. Атрибуты этого класса включают переменные состояния, определяющие объект. Если же ограничиться перечнем этих атрибутов и методов, мы получим только традиционный объект. Рациональный компонент создают когнитивные структуры данных и методы рассуждений (логического вывода). А ведь именно рациональный компонент трансформирует «обычный» объект в агент.