Фактическая работа, которую агент должен сделать, осуществляется в рамках "поведения" - ‘behaviours’. Поведение представляет собой задачу, которую агент может выполнять и реализуется как объект класса jade.core.behaviours.Behaviour. Поведение(я) должно быть добавлено к агенту посредством метода addBehaviour() класса Agen t. Поведение может быть добавлено в любое время, когда агент запускается (в методе setup()).
Каждый класс расширяющий класс Behaviour должен реализовать два абстрактных метода: action() и done(). action() метод определяет операции, которые должны быть выполнены, когда «поведение исполняется». Метод done() возвращает boolean value, указывающее, была ли завершена работа поведения и должно ли это поведение быть удалено из пула исполняемых агентом поведений (работ).
Агент может выполнять несколько поведений одновременно. Важно учесть то, планировщик поведений не является упреждающим (pre-emptive (as for Java threads)), а является «кооперативным». Это значит, что, когда планировщик ставит поведение на исполнение, его метод action() исполняется до своего окончания. Т.е. программист должен сам определить, когда агент переключится с одного своего поведения на другое. С одной стороны, это создает некоторые трудности,нос другой, появляются и некоторые достоинства:
· поддерживает работу с одним потоком Java для агента (что является весьма важным в условиях ограниченных ресурсов, какими обладают, например, сотовые телефоны);
· обеспечивает более быстрое переключение между режимами работы, чем переключение между потоками Java;
· устраняет проблемы синхронизации параллельных режимов работы для доступа к одним и тем же ресурсам (что ускоряет производительность), т.к. все режимы выполняются одним и тем же потоком Java;
· позволяет сохранять состояние агента в постоянном хранилище для последующего возобновления (сохранность агента) или передачи его другому контейнеру для удаленного исполнения (мобильность агента).
Жизненный цикл агента представлен на Рис 3.3.
При создании агента вызывается метод setup(), в котором происходит инициализация агента. Далее в бесконечном цикле выбирается следующий режим поведения из пула активных и исполняется. Затем, в зависимости от типа режима, он либо удаляется из пула активных, либо остается в нем и выполняется снова, когда до него дойдет очередь. При отсутствии активных «поведений» (например, если агент ждет сообщение) поток агента «засыпает» (что позволяет экономить ресурсы процессора). При удалении агента вызывается метод takeDown().
В соответствии с описанным механизмом планирования, режим, представленный ниже, не позволяет запустить другой режим, т.к. его метод action() никогда не завершается.
public class OverbearingBehaviour extends Behaviour {
public void action() {
while (true) {
// do something}
}
public boolean done() {
return true; } }
Типы поведений агента
Различают три простых типа поведения агентов.
1) Одноразовый (one-shot) режим, у которого метод action () выполняется только один раз, после чего режим становится неактивным. jade.core.behaviours.OneShotBehaviour уже реализует метод done(), возвращающий значение true, и может быть легко модифицирован для реализации одноразового поведения.
public class MyOneShotBehaviour extends OneShotBehaviour {
public void action() {
// perform operation X
}}
Операция Х будет выполнена только один раз.
2) Циклический (сyclic) режим, который никогда не завершается и всегда продолжает оставаться активным. Метод action() выполняет одинаковые операции каждый раз, когда он вызывается. jade.core.behaviours.CyclicBehaviour уже реализует метод done(), возвращающий значение false, и может быть легко модифицирован для реализации циклического поведения.
public class MyCyclicBehaviour extends CyclicBehaviour {
public void action() {
// perform operation Y
} }
Операция Y выполняется многократно, до завершения работы агента, выполняющего циклическое поведение.
3) Общий (generic) режим, который выполняет различные операции в зависимости от значения некоторой переменной. Режим остается активным до тех пор, пока выполняется условие, заданное в методе done().
public class MyThreeStepBehaviour extends Behaviour {
private int step = 0;
public void action() {
switch (step) {
case 0:
// perform operation X
step++;
break;
case 1:
// perform operation Y
step++;
break;
case 2:
// perform operation Z
step++;
break;
}
public boolean done() {
return step == 3;
}}
Операции X, Y и Z выполняются одна за другой, а затем поведение завершается.
JADE предусматривает возможность комбинации простых режимов работы агента для создания более сложных режимов, о них даны некоторые сведения в лекциях.
Планирование операций в заданных временных точках
JADE предлагает два готовых класса (в пакете jade.core.behaviours), с помощью которых можно легко реализовывать режимы работы, выполняющие определенные операции в заданные моменты времени.
1) Режим WakerBehaviour, у которого методы action() и done() реализованы таким образом, что абстрактный метод handleElapsedTimeout() выполняется по истечении заданного интервала времени (указанного в конструкторе). После исполнения метода handleElapsedTimeout() поведение завершается.
public class MyAgent extends Agent {
protected void setup() {
System.out.println(“Adding waker behaviour”);
addBehaviour(new WakerBehaviour(this, 10000) {
protected void handleElapsedTimeout() {
// perform operation X
}
});
}
Операция X выполняется через 10 секунд после вывода на экран сообщения «Adding waker behaviour».
2) Режим TickerBehaviour, у которого методы action() и done() реализованы таким образом, что абстрактный метод onTick() выполняется многократно, через определенный интервал времени (указанный в конструкторе). Режим TickerBehaviour никогда не завершается.
public class MyAgent extends Agent {
protected void setup() {
addBehaviour(new TickerBehaviour(this, 10000) {
protected void onTick() {
// perform operation Y
}
});
}
Операция Y выполняется периодически каждые 10 секунд.
3.6. Режимы работы агентов в приложении «Торговля книгами»
В соответствии с описанием основных типов поведения агентов, проанализируем поведение агентов Book-buyer и Book-seller в приложении «Торговля книгами».
3.6.1. Поведение агента Book-buyer
Агент Book-buyer должен периодически запрашивать у агента продавца книгу, которую ему было поручено купить. Этого можно достичь, если модифицировать режим TickerBehaviour так, что каждый «тик» добавляет другой режим, который фактически выполняет запрос к агенту-продавцу. Метод setup() класса BookBuyerAgent необходимо изменить следующим образом.
protected void setup() {
// Printout a welcome message
System.out.println(“Hello! Buyer-agent “+getAID().getName()+” is ready.”);
// Get the title of the book to buy as a start-up argument
Object[] args = getArguments();
if (args!= null && args.length > 0) {//Если есть название книги
targetBookTitle = (String) args[0];
System.out.println(“Trying to buy “+targetBookTitle);
// добавить TickerBehaviour, которое организует запрос к «продавцу» каждую минуту
addBehaviour(new TickerBehaviour(this, 60000) {
protected void onTick() {
myAgent. addBehaviour(new RequestPerformer());
}
});
}
else {
// Make the agent terminate
System.out.println(“No target book title specified“);
doDelete();
}
Обратите внимание на использование защищенной переменной myAgent: каждый режим (поведение) содержит указатель на агента, который его исполняет. Режим поведения RequestPerformer, фактически выполняющий запрос к агенту-продавцу, будет описан в ЛР№3б - это класс, где будет обсуждаться взаимодействие между агентами.
3.6.2. Поведение агента Book-seller
Каждый агент Book-seller ожидает прихода запросов от агентов покупателей и обслуживает их. Запросы могут быть различных типов:
· Прием заявок от покупателей (OfferRequestsServer).
· Оформление сделки (PurchaseOrdersServer).
· Добавление книги в каталог.
Первые два рассмотрим после изучения взаимодействия агентов.
Для реализации запросов различных типов агенту Book-seller необходимо задать два циклических поведения: одно для обслуживания заявок, а другое для обслуживания заказов.
Кроме того, необходимо задать агенту Book-seller одноразовое поведение, реализующее обновление каталога книг, доступных для продажи в тех случаях, когда пользователь добавляет новую книгу из GUI. Класс BookSellerAgent может быть реализован следующим образом (классы OfferRequestsServer и PurchaseOrdersServer будут описаны в ЛР№3б Класс «взаимодействие между агентами»).
import jade.core.Agent;
import jade.core.behaviours.*;
import java.util.*;
public class BookSellerAgent extends Agent {
// The catalogue of books for sale (maps the title of a book to its price)
private Hashtable catalogue;
// The GUI by means of which the user can add books in the catalogue
private BookSellerGui myGui;
protected void setup()
{
// Create the catalogue
catalogue = new Hashtable();
// Create and show the GUI
myGui = new BookSellerGui(this);
myGui.show();
// Add the behaviour serving requests for offer from buyer agents
addBehaviour(new OfferRequestsServer());
// Add the behaviour serving purchase orders from buyer agents
addBehaviour(new PurchaseOrdersServer());
}
protected void takeDown() {
myGui.dispose();
System.out.println(“Seller-agent “+getAID().getName()+” terminating.”);
}
/**
This is invoked by the GUI when the user adds a new book for sale
*/
public void updateCatalogue(final String title, final int price) {
addBehaviour(new OneShotBehaviour() {
public void action() {
catalogue.put(title, new Integer(price));
}
});
}
Ход работы:
1. Создать новый проект (например, bookTrading), сформировав код в виде 3-х классов: BookSellerAgent, BookByerAgent, BookSellerGui в JADE\src\examples\bookTrading.
2. Скомпилировать и запустить проект, использовав строку: -gui –agents seller:< имя пакета >.BookSellerAgent; byer:<имя пакета >.BookBuyerAgent1(Java_programming)
Примечание: наименования книг в форме создания не должны содержать
пробелов, т.к. система обрезает наименования до первого пробела и, соответственно, искомая книга найдена не будет (хотя агент продавца и позволяет вводить наименования книг с пробелами). Поэтому пробелы должны заменяться в наименовании, например, нижним подчеркиванием.
3. Создайте несколько агентов-продавцов:
На экране появится форма для ввода наименования книги и ее цены, после каждого нажатия на кнопку <ОК> будет создано новое наименование книги с заданными в форме параметрами для агента продавца, имя которого указано в заголовке формы:
Примечание: при закрытии формы агент прекращает работу! Поэтому формы ввода параметров для всех агентов продавцов должны все время быть открытыми!
4. Создайте агента-покупателя книг. Наименование книги, которую хочет купить агент,
указывается в поле Arguments:
Примечание: наименования книг в форме создания не должны содержать пробелов, т.к. система обрезает наименования до первого пробела и, соответственно, искомая книга найдена не будет (хотя агент продавца и позволяет вводить наименования книг с пробелами). Поэтому пробелы должны заменяться в наименовании, например, нижним подчеркиванием.
После создания агент регистрируется в системе и сразу же начинает выполнять матчинг для поиска соответствия наименования требуемой книги и наименований предлагаемых книг. Агент покупателя посылает запросы агентам продавцов периодически через определенный интервал времени.
После регистрации всех агентов покупателей они сразу вступают в процесс матчинга. Каждый агент покупателя находит наиболее подходящего продавца (предлагающего наименьшую цену за искомую книгу) и создает с ним связь.
ЗАДАНИЕ К ЛР№3а
1. Пронаблюдайте результат, в том числе в сниффере.
2. Сделайте выводы.
3. Внимательно изучите код особенно в части поведения агентов.
Лабораторная работа №3б. Средства коммуникации агентов.
Цель: изучить способы взаимодействия агентов на примере мультиагентной системы BookTrading - продавец-покупатель книг.