Объекты модели.
Имитационная модель деятельности транспортной компании
Переменной min присваивается порядковый номер транспортного средства, а min_value значение параметра character данного грузовика. А так как все это происходит в цикле, то будет выбран грузовик с наименьшим значением character. Именно ссылка на это транспортное средство будет передана в переменную tr, которая является возвращаемым значением. Таким образом, для каждого заказа будет подобрано… Читать ещё >
Объекты модели. Имитационная модель деятельности транспортной компании (реферат, курсовая, диплом, контрольная)
Объект Main.
Это агент верхнего уровня. На нем располагаются все другие агенты модели. Представляет из себя Гис-карту, которая иллюстрирует эксперимент. На карте отмечены гис-точки, которые являются местами доставки. Кроме того, на агент Main вынесены коллекции reject, success, TimeOut, которые хранят в себе количество отклоненных, успешно доставленных, и не доставленных в срок заказов. На основе этих данных строятся графики, иллюстрирующие изменение данных показателей в динамике.
Рис. 10 агент main
Что касается маршрута, проделываемого автомобильным транспортом, то он строится, используя сервер AnyLogic. Так как речь идет о движении грузового автомобильного транспорта, то выбрана автомобильная сеть дорог.
Рис. 11 Настройка построения маршрутов
При запуске модели выполняется следующий код:
for (int i=0;i.
for (int j=0;j.
department.get (i).product_stock.put (product.get (j).name, uniform_discr (0, 200));
}.
}.
В результате, при запуске модели каждый склад наполняется товарами, каждого продукта может иметься от 0 до 200 штук, число генерируется согласно равномерному дискретному распределению.
Агент Product.
Имеет параметр name. Названия продуктов подгружаются из внешней базы данных. По указанным критериям.
Рис. 12 Свойства агента product
Такой способ обращения к информации используются для обеспечения большей гибкости системы, так как в реальности товары могут изменяться. В данном случае базу данных представляет собой обычный Excel-файл, который можно редактировать, не открывая AnyLogic. Тем не менее, благодаря настройкам внутри имитационного пакета, значения, участвующие в модели, будут обновляться каждый раз перед ее запуском.
Объект Delivery.
Данный агент является пунктом доставки. Именно здесь формируется заказ.
Рис. 14 Представление агента Delivery
Изначально рассматривается, что общее количество людей 100 000. Однако далеко не все люди обратятся в компанию. Поэтому вводится динамическая переменная Demand, отвечающая за спрос. Спрос является не постоянной величиной, он носит сезонный характер и может колебаться. Поэтому вводится функция, описывающая его 1000+A*Math.sin (PI/2*t), где Aслучайное число находится в промежутке [-40;40]. Однако это общий спрос на транспортные услуги всех компаний. По этой причине вводится переменная omega, представляющая вероятность обращения в данную компанию, в основе которой заложено нормальное распределение. Таким образом, что вероятность их обращения колеблется от 0,7 до 2%.
Произведение данной переменной на спрос формирует поток людей-peopleFlow, которые представляют из себя категорию потенциальных клиентовPotentialClients. Далее начинается процесс формирования клиентов. Потенциальные клиенты могут обратится самостоятельно с вероятностью от 2,5 до 5%, заданную также нормальным распределением переменной selfProb.
Произведение этой переменной на количество потенциальных клиентов задает переменную.
selfServ=PotentialClients*selfProb.
Кроме этого на потенциальных клиентов оказывает влияние маркетинг. Переменная marketEff вычисляется по формуле.
delay (Clients/PotentialClients, 1,0.8).
Которая означает, что переменная вычисляется как отношения числа клиентов к потенциальным клиентам с задержкой 1 модального времени, а в первый момент времени значение переменной равно 0,8. Динамическая переменная adInfluence= PotentialClients*marketEff формирует объем людей, привлеченных рекламой.
Поток clientsFlow от накопителя PotentialClients к Clients формируется формулой.
(int)(adInfluence + selfServ).
Что означает суммирование факторов самостоятельного обращения и воздействия маркетинга. Так как клиенты приходят или под влиянием первого, или под влиянием второго фактора. Далее на клиентов оказывают влияние логистический и юридический отделы, эффект рассчитывается по следующей формуле:
sumEff =(Clients*lawEff*logEff).
Данный показатель определяет поток signedFlow, который заполняет накопитель SignedClients. От каждого накопителя уходят обратные потоки. Они (peopleReturn, clientsReturn) определяются разницей значения в накопители и выходящего потока.
peopleReturn=(int)(PotentialClients-clientsFlow);
clientsReturn=(int)(Clients-signedFlow).
А возратный поток signedReturn определятся следующим образом:
delay (eff*signedFlow, timeToNext).
Переменная timeToNext является промежутком перед повторным обращением клиента, подписавшего контракт и она имеет вид: normal (50, 60). Что говорит о том, что в среднем этот период составит 60 дней, однако возможно отклонение в 50 дней от указанного среднего. Параметр Eff определяется же отношением числа подписавших контракт клиентов к числу клиентов. Окончательный накопитель TotalClients формируется за счет переменной diff, которая рассчитывается как разница накопителя SignedClients и значения этого же накопителя только в более ранний момент времени. Именно различие этого накопителя характеризует количество новых заказов.
Кроме того, переменная diff является условием для создания заказа. Как только она становится положительной отрабатывает событие createOrder.
В данном событии происходит следующее:
int k = uniform_discr (1, main.product.size ());
Map map = new LinkedHashMap ();
ArrayList productCode = new ArrayList ();
ArrayList goodDepart = new ArrayList ();
int t = uniform_discr (30, 300);
for (int i=0; i.
productCode.add (new Integer (i));
}.
Collections.shuffle (productCode);
for (int i=0;i.
String nextProduct = main.product.get (productCode.get (i)).name;
map.put (nextProduct, uniform_discr (1, 20));
}.
Происходит заполнение заказа позициями из возможных продуктов. Количество самих позиций выбирается рандомно. Затем каждому из выбранных продуктов формируется их количество от 1 до 20, с помощью равномерного дискретного распределения.
boolean check = true;
for (Department d: main. department) {.
for (Map.Entry e: map. entrySet ()) {.
String prod=(String)e.getKey ();
int quant=(int)e.getValue ();
if (d.product_stock.get (prod).
check = false;
break;
}.
}.
if (check) {.
goodDepart.add (d);
}.
}.
После этого происходит проверка складов на которых имеется достаточное количество товара. Формируется список таких складов.
if (goodDepart.size ()>0) {.
Department depart = getNearestAgentByRoute (goodDepart);
for (Map.Entry e: map. entrySet ()) {.
String prod=(String)e.getKey ();
int quant=(int)e.getValue ();
depart.product_stock.put (prod, depart. product_stock.get (prod)-quant);
}.
Затем, имея список складов с необходимым числом товара, в нем начинается поиск ближайшего по расстоянию. И имеющееся количество товара на складе уменьшается на указанное в заказе.
Order order = main. add_order (this, depart, map, t, time (), 1, null);
Truck tr = order. findTruck ();
tr.orderList.add (order);
Создается новый агент типа order с параметром delivery соответствующему данному месту (логика формирования заказа определенна именно в агенте, который является местом доставки). Параметр depart определился на предыдущем шаге как ближайший с нужным количеством товара. Кроме того, в агенте order запускается метод findTruck, который будет подробно описан позднее. И для найденного, таким образом, грузовика в его список заказов, который он должен доставить добавляется еще один.
} else {.
Order order = main. add_order (this, null, map, t, time (), 0, null);
main.reject.add (order);
}.
Если ж не нашлось складов с достаточным количеством товара, то заказ добавляется в список reject.
Агент Order.
Для реализации логики этого агента была выбрана диаграмма действий.
Рис. 15 Агент Order
Основной задачей, которую решает данная диаграмма является поиск подходящего транспортного средства.
Изначально описываются переменные, которые в последующем будут участвовать в цикле поиска. Первая переменная tr, которая и будет являться конечным возвращаемым значением, хранит в себе значение искомого экземпляра класса Truck. Следующая переменная queue является массивом типа int размерности main.truck.size () и хранит количество заказов, ожидающих доставки для каждого отдельного грузовика. distance массив типа double с размерностью также равному количеству грузовиков. Хранит в себе значения расстояний от каждого грузовика до склада. Переменная stat хранит значение статуса, определяемого в какой точки маршрута, находится грузовик. character, тип double[main.truck.size ()], служит для присвоения каждому транспортному средству характеристики, по которой будет производиться сравнение. Переменная min имеет целочисленный тип и хранит порядковый номер грузовика, в результате прохождения цикла. Min_value тип double хранит характеристику выбранного грузовика.
Цикл for проходит по всем элементам класса Truck.
Внутри цикла располагается элемент code, который имеет следующее содержание:
queue[t.getIndex ()]=t.orderList.size ();
Переменная queue приравнивается количеству заказов.
distance[t.getIndex ()]=t.distanceByRoute (order_department)/1000;
Distance становится равна расстоянию до склада в км.
if (t.inState (Truck.AtDepartment)||t.inState (Truck.Unpacking_dep)) {.
stat[t.getIndex ()]=1;
Если грузовик находится на складе, либо происходит распаковка заказа, в случае, когда после его упаковки было обнаружено, что заказ не будет доставлен вовремя, то статусу присваивается значение 1.
} else if (t.inState (Truck.MovingToDepartment)) {.
stat[t.getIndex ()]=2;
Если же грузовик после распаковки возвращается на склад, то ему приписывается статус 2.
} else if (t.inState (Truck.Unpacking)) {.
stat[t.getIndex ()]=3;
Статус становится равным 3, в случае распаковки заказа для покупателя.
} else {.
stat[t.getIndex ()]=4;
}.
Во всех прочих расположениях грузовика: когда он движется от текущего склада, к нужному, где имеется товар, когда грузовик находится в состояние упаковки товара, когда он движется к месту доставкистатус равен 4.
character[t.getIndex ()] = distance[t.getIndex ()] + queue[t.getIndex ()] + stat[t.getIndex ()];
После этого грузовику присваивается характеристика равная сумме дистанции очереди и статусу заказа.
Далее выставляется условие: character[t.getIndex ()].
Сравнивающее характеристику с минимальным значением, если оно верно, то выполняются следующие действия:
min=t.getIndex ();
min_value=character[t.getIndex ()];
Переменной min присваивается порядковый номер транспортного средства, а min_value значение параметра character данного грузовика. А так как все это происходит в цикле, то будет выбран грузовик с наименьшим значением character. Именно ссылка на это транспортное средство будет передана в переменную tr, которая является возвращаемым значением. Таким образом, для каждого заказа будет подобрано наиболее оптимальный перевозчик.
Также в объекте заказ присутствует событие, которое контролирует заказы по времени исполнения, условие для срабатывания выглядит следующим образом: (int)(time ()-createTime)>=maxTime, событие носит название timeOut и при срабатывании выполняет:
main.timeOut.add (this);
set_status (2);
То есть, добавляет в коллекцию заказов, не удовлетворяющих временные рамки, на агенте main и меняет статус заказа.
Агент Truck.
Логика данного агента отображена на диаграмме состояний.
Рис. 16 агент Truck
Процесс доставки состоит из последовательности состояний и связей между ними. Началом и концом движения грузовика является его пребывание на складе. Это состояние обозначено как AtDepartment. При выходе из этого состояния происходит следующее:
Tstart=time ();
if (flag==false).
{income=income+1000;
distance=0;}.
flag=false;