МИНОБРНАУКИ РОССИИ
Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования.
«Московский государственный технический университет радиотехники, электроники и автоматики»
(МГТУ МИРЭА)
Факультет Информационных технологий (ИТ)
Кафедра Вычислительной техники (ВТ)
Дисциплина
«Системы искусственного интеллекта»
Лабораторная работа №1
Тема: «Разработка многоагентной системы в среде Jason»
Преподаватель: Смирнов С.С.
Студент группы ИТВ-1-08
Оленин А.А.
2012
Оглавление
Постановка задачи 3
Концептуальный анализ 3
Листинг многоагентной системы 6
Тестирование многоагентной системы 14
Постановка задачи
Необходимо разработать многоагентную систему, эмулирующую работу начальника с подчиненными. Начальник должен давать задания трем отделам, сотрудники этих отделов должны выполнять данную им работу. После того, как сотрудники освобождаются, начальник дает новую работу. Сотрудники разделяются по квалификации: низкая, средняя и высокая. Сотрудник не может выполнить работу за другой отдел. Время выполнения работы зависит от сложности задания и от квалификации сотрудника. Присутствует вероятность того, что сотрудник может не справиться с работой.
Концептуальный анализ
Для того, чтобы организовать взаимодействие начальника, подчиненных и отделов, необходимо определить так называемый стек работ. В него будут помещаться задания, которые выдаются начальством. Сотрудники просматривают этот стек (отдельный для каждого отдела) и берут работу оттуда. Было решено установить ограничение на максимальное количество работ в стеке в размере 5 для каждого отдела. Таким образом, выдача работ боссом в отдел будет описываться следующей схемой:
Босс выдает задания отделу до тех пор, пока в стеке не появится 5 работ. Подчиненные, тем временем, мониторят стек. Когда в нем появляется новая работа, один из подчиненных отдела берет ее на себя и оповещает об этом начальника. Так это выглядит на схеме:
Далее сотрудник приступает к выполнению работы. Он может ее выполнить успешно или не справиться с ней. Схемы для этих ситуаций представлены ниже.
О своем результате выполнения работы агент «Сотрудник» выводит сообщение в лог.
Листинг многоагентной системы
Агент «Начальник» выглядит следующим образом:
+type1StackHavePlaces(X) : X > 0 <- placeType1Eat.
+type2StackHavePlaces(X) : X > 0 <- placeType2Eat.
+type3StackHavePlaces(X) : X > 0 <- placeType3Eat.
При определении того, что в стеке работ каждого отдела есть места, он добавляет туда еще одну работу.
Агенты типа «Сотрудник» выглядят однотипно. Отличается лишь время выполнения работы в зависимости от квалификации и то, из какого стека берет работу сотрудник.
Агент «Неквалифицированный сотрудник отдела 1»:
@l[atomic]
+type1StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*20 + 2000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Среднеквалифицированный сотрудник отдела 1»:
@l[atomic]
+type1StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*15 + 1500);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Высококвалифицированный сотрудник отдела 1»:
@l[atomic]
+type1StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*10 + 1000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Неквалифицированный сотрудник отдела 2»:
@l[atomic]
+type2StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*20 + 2000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Среднеквалифицированный сотрудник отдела 2»:
@l[atomic]
+type2StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*15 + 1500);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Высококвалифицированный сотрудник отдела 2»:
@l[atomic]
+type2StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*10 + 1000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Неквалифицированный сотрудник отдела 3»:
@l[atomic]
+type3StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*20 + 2000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Среднеквалифицированный сотрудник отдела 3»:
@l[atomic]
+type3StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*15 + 1500);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Агент «Высококвалифицированный сотрудник отдела 3»:
@l[atomic]
+type3StackHaveEats(X) : X > 0 <-
prepare;
?distance(D);
-distance(D);
.print("Distance: ", D);
.wait(D*10 + 1000);
if(math.random(100) < 85) {
deliverEat;
} else {
.print("Sorry, work failed");
}.
Принцип работы так же основан на просмотре соответствующего агенту стеку работ. Если в нем имеются работы, сотрудник берет ее на себя. Потом, в зависимости от сложности и своей квалификации, за определенное время выполняет работу успешно или с провалом.
Взаимодействие агентов и установка начальных убеждений производится через среду. Исходный код среды:
import jason.asSyntax.*;
import jason.environment.*;
import java.util.LinkedList;
import java.util.Random;
public class DeliverymansEnvironment extends Environment {
LinkedList type1Eats = new LinkedList<Integer>();
LinkedList type2Eats = new LinkedList<Integer>();
LinkedList type3Eats = new LinkedList<Integer>();
Random random = new Random();
final int MAX_TYPE1_EATS = 5;
final int MAX_TYPE2_EATS = 5;
final int MAX_TYPE3_EATS = 5;
@Override
public void init(String[] args) {
Literal emptyType1Stack = Literal.parseLiteral("type1StackHavePlaces(" + MAX_TYPE1_EATS + ")");
Literal type1EatCount = Literal.parseLiteral("type1StackHaveEats(0)");
Literal emptyType2Stack = Literal.parseLiteral("type2StackHavePlaces(" + MAX_TYPE2_EATS + ")");
Literal type2EatCount = Literal.parseLiteral("type2StackHaveEats(0)");
Literal emptyType3Stack = Literal.parseLiteral("type3StackHavePlaces(" + MAX_TYPE3_EATS + ")");
Literal type3EatCount = Literal.parseLiteral("type3StackHaveEats(0)");
addPercept(emptyType1Stack);
addPercept(type1EatCount);
addPercept(emptyType2Stack);
addPercept(type2EatCount);
addPercept(emptyType3Stack);
addPercept(type3EatCount);
}
@Override
public boolean executeAction(String ag, Structure act) {
clearPercepts();
if (act.getFunctor().equals("prepare")) {
System.out.println("Агент " + ag + " получил работу");
if (ag.contains("Type1")) {
Literal type1EatDistance = Literal.parseLiteral("distance(" + type1Eats.getLast() + ")");
addPercept(ag, type1EatDistance);
type1Eats.removeLast();
}
if (ag.contains("Type2")) {
Literal type2EatDistance = Literal.parseLiteral("distance(" + type1Eats.getLast() + ")");
addPercept(ag, type2EatDistance);
type2Eats.removeLast();
}
if (ag.contains("Type3")) {
Literal type3EatDistance = Literal.parseLiteral("distance(" + type1Eats.getLast() + ")");
addPercept(ag, type3EatDistance);
type3Eats.removeLast();
}
}
if (act.getFunctor().equals("placeType1Eat")) {
System.out.println("Босс отправил работу в отдел 1");
type1Eats.add(1 + random.nextInt(99));
}
if (act.getFunctor().equals("placeType2Eat")) {
System.out.println("Босс отправил работу в отдел 2");
type2Eats.add(1 + random.nextInt(99));
}
if (act.getFunctor().equals("placeType3Eat")) {
System.out.println("Босс отправил работу в отдел 3");
type3Eats.add(1 + random.nextInt(99));
}
if (act.getFunctor().equals("makeEat")) {
System.out.println("Агент " + ag + " выполнил работу");
}
Literal type1StackStatus = Literal.parseLiteral("type1StackHavePlaces(" + (MAX_TYPE1_EATS - type1Eats.size()) + ")");
Literal type1EatCount = Literal.parseLiteral("type1StackHaveEats(" + type1Eats + ")");
Literal type2StackStatus = Literal.parseLiteral("type2StackHavePlaces(" + (MAX_TYPE2_EATS - type2Eats.size()) + ")");
Literal type2EatCount = Literal.parseLiteral("type2StackHaveEats(" + type2Eats + ")");
Literal type3StackStatus = Literal.parseLiteral("type3StackHavePlaces(" + (MAX_TYPE3_EATS - type3Eats.size()) + ")");
Literal type3EatCount = Literal.parseLiteral("type3StackHaveEats(" + type3Eats + ")");
addPercept(type1StackStatus);
addPercept(type1EatCount);
addPercept(type2StackStatus);
addPercept(type2EatCount);
addPercept(type3StackStatus);
addPercept(type3EatCount);
return true;
}
}
Объединение всех этих компонент системы в единое целое описано в файле проекта. Исходный код файла проекта:
MAS workers {
infrastructure: Centralised
environment: DeliverymansEnvironment
agents:
boss;
stupidType1Worker;
stupidType2Worker;
stupidType3Worker;
normalType1Worker;
normalType2Worker;
normalType3Worker;
smartType1Worker;
smartType2Worker;
smartType3Worker;
}