Коллеги, спасибо за очень информативный и полезный курс. Прошёл три лекции. Столкнулся с проблемой, что обе модели не могут закончить расчёт по причине ограничения бесплатной версии "создано максимально допустимое число динамически создаваемых агентов (50000)". По скриншотам Лекции 2 видно, что да, модель создает гораздо больше 50000 агентов. В принципе, мне то и диплом не особо нужен. Но хотелось бы выполнить практические работы. Нет ли возможности откорректировать эту проблему? Или может я чего не так делаю? Еще раз спасибо за прекрасный курс! |
Модель функционирования сети связи
Построение событийной части сегмента
Событийная часть сегмента, назовём её блок Абонент1, предназначена для имитации отправителя-получателя сообщений, поступления сообщений через случайные интервалы времени, розыгрыша параметров сообщений и счёта количества всего отправленных-полученных сообщений по категориям и абонентам, запоминания времени поступления каждого сообщения, используемого в последующем для расчёта минимального, максимального и среднего времени передачи одного сообщения.
Алгоритм блока Абонент1 приведен на Рис. 4.7, а его реализация средствами AnyLogic - на Рис. 4.8.
- Из палитры Презентация перетащите элемент Прямоугольник.
- На странице Местоположение и размер панели Свойства введите в поля X: 10, Y: 50, Ширина: 450, Высота: 380.
- Перетащите элемент text и в поле Текст: введите Абонент1.
- Перетащите из Библиотеки моделирования процессов объект source. Поместите его так же, как на Рис. 4.8. Остальные объекты блока Абонент1 вы будете перетаскивать и размещать по мере необходимости.
При построении модели нам придётся воспользоваться Java-кодом, в котором потребуются дополнительные поля сообщений. Для этого мы должны создать нестандартный тип заявки с дополнительными полями для записи и хранения параметров, о которых мы упоминали ранее (см. п. 4.1.4).
Создайте класс заявки Message.
- Выделите объект source.
- В панели Проект щёлкните правой кнопкой мыши элемент модели верхнего уровня дерева и выберите Создать/Java класс.
- Появится диалоговое окно Новый Java класс. В поле Имя: введите имя нового класса: Message.
- В поле Базовый класс: выберите из выпадающего списка Entity . Щёлкните кнопку Далее.
- Появится вторая страница Мастера создания Java класса. Добавьте поля Java класса, показанные на Рис. 4.9.
- Оставьте флажки Создать конструктор и Создать метод toString (). Щёлкните Готово. Закройте редактор кода.
- Щёлкните правой кнопкой мыши в панели Проект только что созданный Java класс и в контекстном меню выберите Преобразовать Java класс в тип агента. Закройте окно с параметрами.
Продолжим построение блока Абонент1.
- Выделите объект source. На странице Основные панели Свойства установите следующие свойства:
- Тип заявки: Message
- Прибывают согласно Времени между прибытиями
- Время между прибытиями exponential(1/timeAbonent)
- Новая заявка Message
-
Действия При выходе:
double a=0; double b=kolAbonent; // Розыгрыш номера получателя сообщения a=uniform(); for (int i=1; i<(kolAbonent+1); i++) {if (a<=((1/kolAbonent)*b)) entity.numAbPol=i; b=b-1;} entity.timeOtpr=time(); entity.numAbOtpr=numAbonent;
Объект source будет генерировать сообщения с интервалами времени, распределёнными по экспоненциальному закону. Принято, что сообщения от данного абонента-отправителя с равной вероятностью могут быть отправлены любому абоненту сети. Поэтому разыгрывается номер абонента-получателя сообщения, и заносится в numAbPol. В поле timeOtpr заносится время отправления сообщения.
- Перетащите объект selectOutput. Соедините его вход с выходом объекта source. Объект selectOutput выделяет и направляет объекту sink на уничтожение сообщения, адресованные абоненту-отправителю, то есть самому себе. Перетащите объект sink. Его вход соедините с выходом T объекта selectOutput.
- Перетащите объект selectOutput5. Данный объект предназначен для розыгрыша категорий отправляемых сообщений. Его вход соедините с выходом F объекта selectOutput. На панели Свойства установите свойства согласно Табл. 4.4. Эти свойства являются кодом. Код предназначен для счёта отправленных сообщений за сеть связи в целом и по категориям сообщений, определения количества отправленных сообщений за один прогон, розыгрыша длин сообщений по категориям, вывода расчётов по каждому абоненту, а также за сеть связи в целом.
- Перетащите два объекта selectOutput5 (имена selectOutput1 и selectOutput2). Объекты предназначены для разделения и счёта отправляемых сообщений по абонентам.
- Перетащите объект queue. Укажите его свойства: Имя: Буфер. Тип заявки: Message. Вместимость 100. Соедините выходы 1…4 selectOutput1 с входом элемента Буфер (см. Рис. 4.8).
- Соедините выход по умолчанию selectOutput1 с входом selectOutput2. Через этот выход будут проходить на selectOutput2 сообщения, адресованные абонентам 5 и 6.
Таблица 4.4. Свойство selectOutput Тип заявки: Message Выход true выбирается При выполнении условия Условие entity.numAbPol==numAbonent Тип заявки: Message Использовать: Условия Действия При входе: a=uniform(); f++; kolOtpr=f/kolProg; editbox5.setText(kolOtpr, true); main.f++; main.всегоОтпр=main.f/kolProg; main.editbox5.setText(main.всегоОтпр, true); Условие 1 a<=verKat.get(1) Действия При выходе 1 entity.numKat=1; b=normal(dlKatO.get(entity.numKat), dlKat.get(entity.numKat)); entity.dlina=(int)(b); d1++; kolOtprKat1=d1/kolProg; editbox6.setText(kolOtprKat1, true); main.d1++; main.всегоОтпрКат1=main.d1/kolProg; main.editbox6.setText(main.всегоОтпрКат1, true); Условие 2 a<=ver verKat.get(2) Действия При выходе 2 entity.numKat=2; b=normal(dlKatO.get(entity.numKat), dlKat.get(entity.numKat)); entity.dlina = (int)(b); d2++; kolOtprKat2=d2/kolProg; editbox7.setText(kolOtprKat2, true); main.d2++; main.всегоОтпрКат2=main.d2/kolProg; main.editbox7.setText(main.всегоОтпрКат2, true); Условие 3 a<=verKat.get(3) Действия При выходе 3 entity.numKat=3; b=normal(dlKatO.get(entity.numKat), dlKat.get(entity.numKat)); entity.dlina=(int)(b); d3++; kolOtprKat3=d3/kolProg; editbox8.setText(kolOtprKat3, true); main.d3++; main.всегоОтпрКат3=main.d3/ kolProg; main.editbox8.setText(main.всегоОтпрКат3, true); Условие 4 a<=verKat.get(4) Действия При выходе 4 entity.numKat=4; b=normal(dlKatO.get(entity.numKat), dlKat.get(entity.numKat)); entity.dlina=(int)(b); d4++; kolOtprKat4=d4/kolProg; editbox9.setText(kolOtprKat4, true); main.d4++; main.всегоОтпрКат4=main.d4/kolProg; main.editbox9.setText(main.всегоОтпрКат4, true); Свойство selectOutput1 Тип заявки: Message Использовать: Условия Условие 1 entity.numAbPol==1 Условие 2 entity.numAbPol==2 Действия При выходе 2 отпрАб2++; main.отпр12=отпрАб2; Условие 3 entity.numAbPol==3 Действия При выходе 3 отпрАб3++; main.отпр13=отпрАб3; Условие 4 entity.numAbOtpr==4 Действия При выходе 4 отпрАб4++; main.отпр14=отпрАб4; Свойство selectOutput2 Тип заявки: Message Использовать: Условия Условие 1 entity.numAbPol==5 Действия При выходе 1 отпрАб5++; main.отпр15=отпрАб5; Условие 2 entity.numAbPol==6 Действия При выходе 2 отпрАб6++; main.отпр16=отпрАб6; - Выделите selectOutput2 и установите значения свойств, указанных также в Табл. 4.4. Соедините все выходы selectOutput2 с входом элемента Буфер.
Отправляемое сообщение поступило в буфер. Дальше оно должно попасть в канал связи. Создайте порты для отправления и приёма сообщений.
- Из палитры Презентация перетащите элемент Скруглённый прямоугольник.
- На странице Местоположение и размер панели Свойства введите в поля X: 210, Y: 100, Ширина: 65, Высота: 60.
- Из палитры Основная перетащите два элемента порт. Разместите их как на Рис. 4.8. В поле Имя: замените предложенное системой на вх и вых.
- Обратите внимание на то, чтобы у элементов Скруглённый прямоугольник и порт был установлен флажок На верхнем уровне. У остальных элементов сегмента Абонент1 этот флажок должен быть сброшенным. В противном случае вы обнаружите их также на верхнем уровне - на диаграмме Main.
Итак, отправляемое сообщение поступило в канал связи, подключённый к порту вых.
Через порт вх сообщения поступают из канала связи. Продолжим построение блока Абонент1.
- Перетащите объект selectOutput (имя selectOutput3). Он предназначен для контроля текущей ёмкости входного буфера. В случае заполнения буфера, сообщения теряются.
- Соедините порт вх с входом объекта selectOutput3.
- Перетащите объект sink (имя sink1). Его вход соедините с выходом F объекта selectOutput3.
- Выделите объект selectOutput3 и установите его свойства:
- Тип заявки: Message
- Выход true выбирается При выполнении условия
- Условие emkBuferVx-tekEmkBuferVx>=entity.dlina
- Перетащите объект queue. Укажите его свойства:
- Имя: БуферВх
- Тип заявки: Message
- Вместимость emkBuferVx
- Действие при входе tekEmkBuferVx+=entity.dlina;
- Действия При выходе tekEmkBuferVx-=entity.dlina;
Соедините его вход с выходом Т объекта selectOutput3.
- Перетащите selectOutput5 (имя selectOutput4). Он необходим для разделения потока полученных сообщений по категориям.
- На страницах панели Свойства установите свойства согласно Табл. 4.5. Эти свойства также являются кодом. Код предназначен для:
- счёта полученных сообщений за сеть связи в целом и по категориям сообщений,
- определения числа полученных сообщений за один прогон,
- вывода расчётов за каждого абонента, а также за сеть связи в целом.
- Соедините выход элемента БуферВх с выходом объекта selectOutput4.
- Перетащите два объекта selectOutput5 (имена selectOutput5 и selectOutput6). Объекты предназначены для разделения и счёта получаемых сообщений по абонентам. Значения свойств установите также согласно Табл. 4.5. Выход по умолчанию объекта selectOutput5 соедините с входом объекта selectOutput6.
Таблица 4.5. Свойство selectOutput4 Тип заявки: Message Условия Использовать: g++; Действия При входе: kolPol=g/kolProg; editbox.setText(kolPol, true); main.g++; main.всегоПол=main.g/kolProg; main.editbox.setText(main.всегоПол, true); Условие 1 entity.numKat==1 Действия При выходе 1 k1++; kolPolKat1=k1/kolProg; editbox1.setText(kolPolKat1, true); main.k1++; main.всегоПолКат1=main.k1/kolProg; main.editbox1.setText(main.всегоПолКат1, true); Условие 2 entity.numKat==2 Действия При выходе 2 k2++; kolPolKat2=k2/kolProg; editbox2.setText(kolPolKat2, true); main.k2++; main.всегоПолКат2=main.k2/kolProg; main.editbox2.setText(main.всегоПолКат2, true); Условие 3 entity.numKat==3 Действия При выходе 3 k3++; kolPolKat3=k3/kolProg; editbox3.setText(kolPolKat3, true); main.k3++; main.всегоПолКат3=main.k3/kolProg; main.editbox3.setText(main.всегоПолКат3, true); Условие 4 entity.numKat==4 Действия При выходе 4 k4++; kolPolKat4=k4/kolProg; editbox4.setText(kolPolKat4, true); main.k4++; main.всегоПолКат4=main.k4/kolProg; main.editbox4.setText(main.всегоПолКат4, true); Свойство selectOutput5 Тип заявки: Message Использовать: Условия Условие 1 entity.numAbOtpr==1 Условие 2 entity.numAbOtpr==2 Действия При выходе 2 отАб2++; main.кПрСп21=отАб2/main.отпр21; main.КПрСп21.setText(main.кПрСп21, true); Условие 3 entity.numAbOtpr==3 Действия При выходе 3 отАб3++; main.кПрСп31=отАб3/main.отпр31; main.КПрСп31.setText(main.кПрСп31, true); Условие 4 entity.numAbOtpr==4 Действия При выходе 4 отАб4++; main.кПрСп41=отАб4/main.отпр41; main.КПрСп41.setText(main.кПрСп41, true); Свойство selectOutput6 Тип заявки: Message Использовать: Условия Условие 1 entity.numAbOtpr==5 Действия При выходе 1 отАб5++; main.кПрСп51=отАб5/main. отпр51; main.КПрСп51.setText(main.кПрСп51, true); Условие 2 entity.numAbOtpr==6 Действия При выходе 2 отАб6++; main.кПрСп61=отАб6/main.отпр61; main.КПрСп61.setText(main.кПрСп61, true); - Перетащите объект sink2. Его вход соедините с выходами 1…4 объекта selectOutput5 и выходами объекта selectOutput6.
- Установите свойства объекта sink2 согласно Табл. 4.6. Код предназначен для расчёта коэффициента пропускной способности сети связи и времени передачи одного сообщения.
Свойство | sink2 |
---|---|
Тип заявки: | Message |
Действия При входе: | врПередачи.add(time()-entity.timeOtpr); |
editbox11.setText(врПередачи.mean(), true); | |
editbox12.setText(врПередачи.max(), true); | |
editbox13.setText(врПередачи.min(), true); | |
main.коэфПропСпособ=main.всегоПол/main.всегоОтпр; | |
main.editbox10.setText(main.коэфПропСпособ, true); | |
main.врПередСооб.add(time()-entity.timeOtpr); | |
main.editbox11.setText(main.врПередСооб.mean(), true); | |
main.editbox12.setText(main.врПередСооб.max(), true); | |
main.editbox13.setText(main.врПередСооб.min(), true); |
Приступим к построению сегмента Маршрутизатор.
Сегмент Маршрутизатор
Исходные данные
- Откройте тип агента Маршрутизатор.
- Перейдите на область просмотра viewData.
- Перетащите из палитры Презентация элемент Скругленный прямоугольник. На странице Основные в поле Имя: оставьте имя, предложенное системой.
- На странице Местоположение и размер панели Свойства введите в поля X: 10, Y: 600, Ширина: 314, Высота: 190.
- Перетащите элемент text и в поле Текст: введите Исходные данные (Рис. 4.9.).
- Перетащите элементы Параметр и Переменная. Разместите их и дайте имена согласно Рис. 4.10.
- Значения по умолчанию элементов Параметр установите согласно Табл. 4.7.
- Тип timeOtkBK, timeVosstBK, proizvod установите double, остальных параметров и простых переменных - int.