Мультиагентная среда имитационного моделирования AGNES (AGent NEtwork Simulator).
Автор - к.т.н. Подкорытов Дмитрий Игоревич, ИВМиМГ СО РАН
Среда AGNES, написанная на JAVA c использованием пакета JADE, позволяет создавать имитационные модели систем с дискретными событиями и запускать имитацию этих моделей на кластере ССКЦ СО РАН.
Запуск AGNES
Входными данными для AGNES является XML файл конфигурации модели, который имеет следующую структуру:
  1. корневой элемент AgnesConfig, у которого могут быть два аттрибута:
    • workTime : время работы среды моделирования в секундах.
    • nodesNum : количество контейнеров на который должна работать модель.
  2. Внутри AgnesConfig, могут содержаться несколько блоков Agent, которые определяет классы агентов, входящие в модель. У элемента могут быть следующие атрибуты:
  3. обязательный className — название java класса функционального агента;
  4. логический mainOnly — атрибут означающий, что агенты будут запущены только на главном контейнере.
  5. Каждый элемент Agent может содержать несколько элементов Param, задающие конкретные параметры агентов. В качестве атрибутов обязательным является count— задающий количество агентов данного типа с заданными параметрами, которые будут запущены на каждом контейнере. Остальные атрибуты опциональны и зависят только от конкретного класса функционального агента, они передаются в конструктор агента.
Пример конфигурационного файла:
<?xml version="1.0" encoding="UTF-8"?>
<AgnesConfig workTime="600" nodesNum="1">
<Agent className="Sensor">
<Param count="200" radius="20" />
<Param count="150" radius="17" />
</Agent>
<Agent className="Gate">
<Param count="1" energy="20000" />
<Param count="2" energy="18000" />
</Agent>
<Agent className="Events">
<Param count="100" randomize="true" />
</Agent>
</AgnesConfig>
Для запуска AGNES нужно выполнить команду "java -jar AGNES.jar [options]".
Доступны следующие опции для запуска среды моделирования:
  • path-to-xml-config.xml : путь до XML файла, содержащего описание модели. Если файл явно не указан, то AGNES попытается прочитать файл model.xml в директории приложения.
  • -h hostname : имя или адрес узла где запущен главный контейнер JADE.
  • -p port : порт на котором работает главный контейнер JADE
  • -nm : при распределенном запуске AGNES, флаг указывает на то что следует запустить обычный контейнер и подключить его к главному.
    Пример запуска главного контейнера:
    java -jar AGNES.jar my.xml -h localhost -p 1099
    и подключаемого к нему:
    java -jar AGNES.jar my.xml -h 192.168.0.3 -p 1099 -ng –nm
    -ng : ключ означает запуск программы без графической оболочки. По умолчанию открывается окно RMA агента.
AGNES
Пример создания модели в AGNES
Рассмотрим обычный механизм создания модели работающей в среде AGNES. Возьмем следующую задачу: есть некий граф дорог, на котором расположены автомобили. Каждый автомобиль оборудован устройством для приема-передачи сообщений. На площади так же расположены более мощные стационарные передатчики. Один из автомобилей фиксирует событие, информацию о котором он должен передать выделенной стационарной вышке. Необходимо создать модель распространения сигнала внутри описанной сети.
Для создания агентной модели в качестве атомарной единицы (агента) выберем приемник-передатчик, характеризующийся координатой, дальностью действия, функцией вероятности доставки сообщения. Для создания агентов AGNES необходимо знать JAVA хотя бы на начальном уровне. Рассмотрим пошаговое создание простой реализации агента:
Необходимо отнаследоваться от базового класса AgnesFunctionalAgent;
public class Transmitter extends AgnesFunctionalAgent
У агента-передатчика будет 3 атрибута: координаты X,Y и максимальный радиус действия передатчика. Для того чтобы передать аргументы из конфигурационного файла в конструктор агента используется метод setInitParam. В качестве аргументов передаются два строчных параметра название и значение аргумента. Радиус действия агент будет получать из файла конфигурации, а координаты случайным образом будут устанавливаться в конструкторе setup;
protected Integer coordX;
protected Integer coordY;
protected Integer maxRadius;

// Конструктор агента AGNES
protected void setup() {
super.setup();
coordX = RandomGenerator.getRandomInt(1000);
coordY = RandomGenerator.getRandomInt(1000);
}

// Метод обработки параметров из
// конфигурационного файла
protected void setInitParam(String name, String val){
super.setInitParam(name, val);
if (name.equals("R")) {
maxRadius = Integer.parseInt(val);
}
}
Основным способом взаимодействия между агентами является обмен сообщениями. В нашей модели, агенты будут принимать и обрабатывать сообщение о событии (содержащее только число соответствующее количеству агентов через которые прошло сообщение). В простой модели будем следить за одним сообщением, для этого у каждого агента будет флаг обозначающий, прошла обработка события или нет. Когда агент получает сообщение, он сперва проверяет состояние флага, если сообщение уже получалось, то ничего не делается, если не обрабатывалось, то :
  1. Агент увеличивает счетчик внутри сообщения.
  2. Переправляет новое сообщение своим соседям.
  3. Взводит флаг обработки сообщения.
Для обработки сообщений необходимо реализовать абстрактный метод MessageProcessing, в который приходят 3 параметра:
  1. Имя отправителя.
  2. Текст Сообщение.
  3. Идентификатор агента отправителя.
Код метода:
protected boolean isMessageProcessed = false;
protected void MessageProcessing(String sender,
String mess, AID aidSender) {
if (!isMessageProcessed) {
Integer currentIteration = Integer.parseInt(mess);
currentIteration++;
ResendMessage(currentIteration.toString());
isMessageProcessed = true;
}
}
Для поиска агентами друг друга, используется сервис «желтых страниц» JADE. Агенту-передатчику нужно знать своих соседей, что передавать им сообщения. Для поиска друг друга, агенты должны зарегистрироваться в «желтых страницах» и найти друг друга. при помощи методов registerService и findAllService соответственно. Соседями агента выбираются агенты, находящиеся на расстоянии меньшем радиуса действия передатчика. Для того чтобы считать расстояние расширим сообщения агента. Для получения информации об координатах другого агента будет использоваться сообщение «getCoord», в ответ будет отправляться сообщение вида «myCoord#X#Y». Т.е. в методе MessageProcessing появится следующий код:
if ("getCoord".equals(mess)) {
String message = "myCoord#" + coordX + "#" + coordY;
SendMessage(aidSender, message);
} else if (mess.startsWith("myCoord")) {
String[] coords = mess.split("#");
Integer X = Integer.parseInt(coords[1]);
Integer Y = Integer.parseInt(coords[2]);
Integer R2 = (coordX - X) * (coordX - X)
+ (coordY - Y) * (coordY - Y);
if (maxRadius > Math.sqrt(R2)) {
if (!neighbours.contains(aidSender)) {
neighbours.add(aidSender);
}
}
}
Для синхронизации работы модели агенты должны использовать два метода:
  1. iAmReady должен вызываться когда агент загружен, и сделал все подготовительные работы.
  2. PreRunning вызывается, когда все агенты в моделе готовы к работе.
таким образом, в конструктор нужно передавать метод по регистрации агента в «желтых страницах». А в методе PreRunning нужно найти всех передатчиков и отправить им запрос для получения координат.
protected void setup() {
super.setup();
coordX = RandomGenerator.getRandomInt(1000);
coordY = RandomGenerator.getRandomInt(1000);
registerService("Transmitter");
iAmReady();
}
protected void PreRunning() {
super.PreRunning();
AID[] transmitters = findAllService("Transmitter");
for (int i = 0; i < transmitters.length; i++) {
SendMessage(transmitters[i], "getCoord");
}
}
Последнее что осталось реализовать, для получения первой модели, это сбор данных и инициализирующее сообщения о событии, для передачи его в сети. Чтобы сохранить данные на диск используется метод writeDataOnDisk, принимающий два параметра: название файла и строку с информацией. При получении сообщения о событии агент будет сохранять его вместе со своими координатами в файл. Для инициализации процесса передачи сообщения, после старта модели сделаем так, чтобы 0 агент с 5-тисекундным ожиданием отправлял сообщение о событии своему первому соседу. Для отложенного выполнения действия можно использовать DelayBehaviour поведение. У каждого агента Agnes есть его идентификационный номер, который хранится в атрибуте myIdentificationNumber. Добавим две строки в метод MessageProcessing и расширим метод PreRunning.
protected void MessageProcessing(
...
String result = coordX + ";"
+ coordY + ";" + currentIteration;
writeDataOnDisk("FirstModel.csv", result);
...
}
protected void PreRunning() {
...
if (myIdentificationNumber == 0) {
addBehaviour(new DelayBehaviour(this, 5000) {
protected void mainAction() {
if (neighbours.size() > 0) {
SendMessage(neighbours.get(0), "0");
}
}
});
}
}
Итоговый код агента меньше 100 строк находится ниже. Осталось только запустить модель. Создадим модель из 50-ти передатчиков и запустим её на минуту. Конфигурационный файл модели выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<AgnesConfig workTime="60">
<Agent className="Transmitter">
<Param count="50" R="500"/>
</Agent>
</AgnesConfig>
Свои вопросы и предложения можно отправлять автору по адресу: d.podkorytovmail.ru
Старый сайт