Агентно-ориентированное программирование





Тема дипломной работы в университете была «Многоагентные системы для обработки баз знаний». Подключение многоагентной системы Jade к базе знаний Protege не составило труда и диплом готов. Теперь можно моделировать абстрактные учебные задачи, рои агентов, и так далее и тому подобное. Но возник вопрос, а как применить на деле полученные знания? Случай завершить НИОКР подвернулся при работе над системой «умный дом». Потребовалось небольшое многопоточное приложение для передачи данных от «умного дома» стороннему разработчику веб-интерфейсов. Вот прекрасная возможность применить Агентно-ориентированное программирование. В результате была успешно создана многоагентная система для параллельного программирования.



Ключевые классы многоагентной системы (Java)



Для наилучшего понимания основную идею можно сформулировать следующим образом: ментальная модель системы — это агенты работающие в потоках.

Класс Agent



Кстати можно делать своих агентов наследуя их от AbstractAgent.

import java.lang.reflect.Method; 

import java.util.HashMap; 

import java.util.concurrent.ConcurrentLinkedQueue; 

  

//один из типов агентов 

public class Agent extends AbstractAgent{ 

        

    Agent () {codeName = "DefaultAgent";} 

    //детали операции 

    public MissionDetails missionDetails; 

    //результаты операции 

    public AgentReport agentReport; 

     

    //мессенджер агентов 

    public ConcurrentLinkedQueue<AgentMessage> messages = new ConcurrentLinkedQueue<>(); 

     

    @Override 

    public AgentMessage ReadMessage() {return messages.poll();}; 

    @Override 

    public void AddMessage(AgentMessage message) {messages.offer(message);}; 

     

    //у каждого агента свои методы работы ... 

    public HashMap<String, Method>  agentMethods = new HashMap<> ();  

     

    //паттерн инструменты  агента 

    Replicator tools = new Replicator(); 

} 



Класс Agency



Это справочник агентов. Кроме того, здесь можно хранить общие данные для потоков.

import java.util.concurrent.ConcurrentHashMap; 

  

//агенты через этот класс найдут друг друга (даже если они в разных потоках) 

public class Agency { 

String agencyName = "defaultAgencyName"; 

//справочник агентов     

public ConcurrentHashMap<String, AbstractAgent>  agentReference = new ConcurrentHashMap<> ();  

}


Класс AgentThread



В этом классе-потоке запускаются сценарии, внутри которых и работают агенты. Общаются друг с другом даже если они работают в разных потоках. Схожее решение предоставляет нам MPI. Кстати, в один поток можно отправить на работу сразу несколько агентов.

import java.lang.reflect.InvocationTargetException; 

import java.util.concurrent.LinkedBlockingQueue; 

import java.util.logging.Level; 

import java.util.logging.Logger; 

  

//один из типов потоков: очередь агентов с разовыми заданиями 

public class AgentThread extends AbstractAgentThread { 

  

    //очередь заданий 

    public LinkedBlockingQueue<MissionCard> missionCards = new LinkedBlockingQueue<>(); 

  

    @Override 

    public void run() { 

  

        MissionCard missionCard = null; 

        Scenarios scenario = new Scenarios(); 

        Agent agent = null; 

        Agency agency = null; 

  

        while (true) { 

            try { 

                sleep(1000); 

            } catch (InterruptedException ex) { 

                Logger.getLogger(AgentThread.class.getName()).log(Level.SEVERE, null, ex); 

            } 

            System.out.println("Сценарий запущен."); 

            missionCard = missionCards.poll(); 

            if (missionCard != null) { 

                agent = (Agent) missionCard.agent; 

                agency = missionCard.agency; 

                 

                //запуск сценария 

                try { 

                    missionCard.mission.invoke(scenario, agent, agency); 

                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 

                    Logger.getLogger(AgentThread.class.getName()).log(Level.SEVERE, null, ex); 

                } 

            } 

             

            //уничтожение потока 

            if (agent.missionDetails.details.equals("kill"))  

            {System.out.println("Thread "+ this.threadName + " killed"); 

                break;} 

        } 

    } 

  

    //добавить пришедшую задачу в очередь 

    @Override 

    public void AddMissionCardTask(MissionCard missionCard) { 

        try { 

            missionCards.put(missionCard); 

        } catch (InterruptedException ex) { 

            Logger.getLogger(AgentThread.class.getName()).log(Level.SEVERE, null, ex); 

        } 

    } 

}


Исходный код системы



По ссылке в конце статьи можно получить исходный код системы. Сам код представляет собой каркас (FrameWork) который можно расширять, создавая своих агентов, проектируя новые потоки. Для управления потоками реализован класс AgentThreadPool.java. Использованы lock-free структуры данных для Java-системы. Для C++ каркаса вы можете вставить свои lock-free структуры. Также присутствуют тестовые примеры работы системы. По моему опыту скажу, что удобно работать со сторонним кодом. Загружаем его в сценарий и отправляем в поток, а агент по ходу выполнения стороннего кода вносит в него свои коррективы. Так например можно реализовать сервер TCP/IP. Скачиваем, пишем параллельные программы и забываем о прокрустовом ложе шаблона producer-consumer.

Исходный код системы Social-Intelligence.

Комментарии (3)


  1. PqDn
    18.05.2018 11:34

    Было бы неплохо увидеть какую именно проблему вы решали при помощи своей дипломной работы.
    Многоагентная система это всего лишь средство для достижения конкретной цели…


  1. Ryppka
    18.05.2018 13:19

    Не увидел C++, плохо смотрел?


    1. myxo
      18.05.2018 14:41

      Я даже статьи не увидел. Видимо тоже плохо смотрел.