Файл: Разработка имитационных моделей управления запасами в цепях поставок Москва 2011 2 Введение.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 04.12.2023

Просмотров: 89

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

27 объекта. Нумерация объектов начинается с нуля, поэтому индекс единственного агента retailer – ноль. В дальнейшем нам неоднократно придется обращаться из одного класса модели к элементам другого, используя похожие синтаксические конструкции. Более подробный материал представлен в “Java For AnyLogic Users” [1,p43]
Перенесем все элементы класса Main (кроме графика) в левый квадрант окна редактирования:

28
У графика поменяем параметры расположения и размера – перенесем его в правый нижний угол и уменьшим:
Запускаем модель:
Синий квадрат – это агент Retailer, расположенный на указанных нами координатах (10*4;10*4). Модель работает так же, как и в предыдущей версии. По ходу данного практикума модели будут становиться менее

29 абстрактными. Отображение упрощенной презентации агента-розничной точки – это только первый этап расширения возможностей данной модели.

30
Раздел 2.Модели со стохастическим спросом
В данном разделе практикума модификация моделей (при сохранении преемственности) выполнена, ориентируясь на следующую последовательность этапов:
1)добавление классов объектов
2)добавление переменных и параметров
3)изменение кода инициализации модели
4)изменение кода алгоритма управления запасами
5)изменение кода событий
6)редактирование окна презентации
7)редактирование оптимизационного эксперимента
2.1 Модель линейной цепи поставок со стохастическим спросом
Описание модели
Доработаем модель, завершенную в предыдущем разделе. В случае потребности в запасе розничная точка размещает заказ у дистрибьютора, и заказ транспортируется в розничную точку. Добавим два новых агента
(участника цепи поставок): дистрибьютора и «транспортное средство».
Спрос генерируется нормальным распределением с математическим ожиданием 80 и стандартным отклонением 18. Количество выполненных заказов потребителей должно составлять не менее 98,5%. Розничная точка формирует заказ при достижении определенного порогового уровня запаса.
Срок доставки (Lead Time, LT) зависит от расстояния между дистрибьютором и розничной точкой. Ставка на хранение запаса для розничной точки составляет 1 единицу за хранение единицы товара в течение периода, ставка

31 транспортировки 5 единиц за 10 единиц расстояния между розничной точкой и дистрибьютором. Ставка транспортировки не зависит от объема поставки.
Расстояние между розничной точкой и дистрибьютором рассчитывается по формуле:
Где и координаты розничной точки, а и координаты дистрибьютора.
При транспортировке заказа одна единица расстояния преодолевается за один день. Таким образом, если расстояние составляет 5 единиц, то потребуется пять дней на доставку.
Координаты дистрибьютора: (50;50)
Задачи:
1. смоделировать и отразить в презентации работу цепи поставок;
2. найти оптимальные значения параметров управления запасами.
Добавление классов Distributor и Truck


32
В новой версии модели используются два дополнительных типа объектов: Distributor – дистрибьютор и Truck – транспортное средство.
Добавим данные объекты в модель по аналогии с классом Retailer. Цвет
заливки для прямоугольника презентации Distributor – green, ширина и высота 8, Truck – cyan, ширина и высота 5. Цвет линии для всех объектов: black
Дополнительно для объекта Truck укажем во вкладке свойств Агент параметр движения Скорость, равный 40.
В работе модели задействованы три объекта: розничная точка, дистрибьютор и транспортное средство. Розничная точка и дистрибьютор размещены на презентации в соответствии с координатами, транспортное средство отображается только во время анимации доставки товара по маршруту «дистрибьютор - розничная точка».

Редактирование класса Main
Добавим в класс Main параметры координат дистрибьютора distrCoordx и distrCoord типа int, равные 50 каждый:

33
Отредактируем класс Retailer. Добавим параметр retDist типа double, который будет хранить расстояние между дистрибьютором и розничной точкой.
Меняем тип параметра currentDemand на double.
Добавим в Действие при запуске класса Main код инициализации дистрибьютора:
Distributor b = add_distributor(); b.setXY(4*distrCoordx,4*distrCoordy);
Также рассчитаем значение параметра retDist по геометрической формуле расстояния между двумя точками: a.retDist = sqrt(pow(retailCoordx-distrCoordx,2)+ pow(retailCoordy-distrCoordy,2) );
Функция sqrt используется для взятия квадратного корня, pow – Для возведения числа степень – в данном случае в квадрат[1,p11].

34
Запустим модель:
На презентации появился квадрат зеленого цвета, условно соответствующий дистрибьютору.
Добавим инициализацию агентов класса Truck в Действие при
запуске класса Main:
Truck d = add_truck(); d.setXY(4*distrCoordx,4*distrCoordy); d.rectangle.setVisible(false);
Анимация модели будет организована таким образом, что транспортное средство (ТС) отображается лишь в процессе перемещения от дистрибьютора к розничной точке. Поэтому при запуске модели ТС должно находиться на тех же координатах, что и дистрибьютор, но не быть видимым.

35
Метод d.rectangle.setVisible(false) скрывает объект на презентации.
При заказе транспортное средство, обслуживающее маршрут доставки, становится «видимым» и движется по карте в направлении получателя.
После того, как конечная точка маршрута достигнута, транспортное средство вновь становится «невидимым» и перемещается в начальную точку.
Генерация спроса
В новой версии модели спрос генерируется нормальным распределением. Параметры распределения: normal(18,80)
Добавим в класс Main две переменные параметров спроса: demandStd
– стандартное отклонение (18) и demandMean – математическое ожидание (80) .
Отредактируем событие ordering:

36 retailer.get(0).currentDemand = round( max
(normal(demandStd,demandMean),0));
В данном выражении используются три формулы. Нормальное распределение задается формулой normal(x,y), где x – это стандартное отклонение, y – математическое ожидание. Функция max() используется для сравнения сгенерированного нормальным распределением значения и нуля.
Если убрать данную функцию, то модель иногда будет генерировать отрицательный спрос, что недопустимо. Функция round() используется для округления дробных значений. Таким образом, можно считать, что спрос рассчитывается как целые неотрицательные числа, сгенерированные нормальным распределением.
Модификация алгоритма управления запасами
В модель были добавлены два важных фактора:
1.учет времени выполнения заказа (LT);
2.вероятностная структура спроса.
Эти факторы требуют более сложной логики для корректной работы модели. Существующий алгоритм будет работать некорректно. В нынешней версии перезаказ выполняется при уровне запаса, равном нулю. Если спрос генерируется нормальным распределением, то, например, при запасе 60 может быть сгенерировано значение спроса 130, и тогда запас составит -70, и перезаказ выполнен не будет. Кроме того, отрицательный уровень запаса в модели недопустим. Поэтому внесем изменения в событие ordering. Учет


37 вероятностных факторов во многих случаях заставляет пересматривать работу алгоритма.
При вероятностном типе спроса нужно делать заказ при достижении порогового уровня ROP (Reorder Point). Тогда будет некоторый диапазон значений между ROP и нулем, когда следует выполнить заказ. Добавим в класс Main переменную для данного параметра управления запасами. Тип переменной int, значение по умолчанию: 500.

38
Спрос генерируется ежедневно. Сначала проверяется условие, может ли заказ быть выполнен. Если спрос превышает запас, то записываются данные о дефиците. Проверяется условие, что заказ не находится в пути.
Если оно выполняется, формируется заказ дистрибьютору в размере величины EOQ. Если запас позволяет обслужить спрос, то величина запаса уменьшается на величину спроса. После этого проверяется условие, не достигнут ли пороговый уровень запаса ROP. Если текущий запас ниже величины ROP и заказ уже не находится в пути, формируется новый заказ в размере величины EOQ. Проверка нахождения заказа в пути нужна потому, что срок доставки заказа больше (5,65), чем интервал между генерациями спроса (1).
Для реализации этого значительно более сложного алгоритма используем средства графического моделирования в AnyLogic. Опишем алгоритм в виде диаграммы действий actionChart().
Удалим старый алгоритм:

39
Добавим новую строку: actionChart();
Строка actionChart() это вызов функции передачи дальнейшей обработки события в диаграмму действий. Диаграмма действий это инструмент для более удобного визуального представления алгоритмов.
Модули диаграммы действий реализованы в рамках нотации языка графического описания UML. В рассматриваемой нами модели алгоритм обработки материального потока достаточно сложный, поэтому для большей наглядности реализуем его в диаграмме действий. Нет никакой разницы в обработке кода написанного внутри и кода, реализованного с помощью actionChart().
Диаграмма действий
Создадим диаграмму действий для класса Main:

40
Оставляем все параметры по умолчанию:
Если бы мы решили сменить имя диаграммы действий, то ссылку на него следовало бы поменять и в событии ordering. Чтобы при смене имени оно изменялось во всех участках кода, используется комбинация клавиш
Ctrl+Enter [1,p12].
Сначала проверяется условие, может ли быть обслужен текущий спрос.
Добавляем модуль принятия решения:


41
Свойства: комментарий: Спрос превышает запас ритейлера?, условие: retailer.get(0).currentDemand > retStock
Сравниваются величины текущего спроса и текущего уровня запаса.
Дефицит возможен по причине того, что спрос генерируется нормальным распределением, и во время доставки заказа спрос может превысить запас. Добавим в класс Main переменную для учета случаев возникновения дефицита. Назовем еѐ retShortage, тип: int:
Добавляем элемент Код панели Диаграмма действий по ветви true:
Свойства: комментарий: Обновление дефицита, код: retShortage++;
Переменная retShortage увеличивается на единицу.

42
Продолжаем движение по ветви true. Добавляем еще один модуль принятия решения:
Свойства: комментарий: Нет заказа в пути?, условие: truck.get(0).isMoving() == false
Чтобы проверять, находится ли заказ в пути, можно создать логическую переменную, но мы будем отслеживать перемещение транспортных средств. Если заказ обрабатывается, то «транспортное средство», его обслуживающее, будет перемещаться на презентации модели.
Метод isMoving() возвращает значение false, если объект не движется
(ситуация 2) (движение задается методом moveTo()) и true в противном случае (ситуация 1).
Транспортное средство находится в пути:

43
Транспортное средство не находится в пути:
Работа с динамическими событиями в диаграмме действия
Время выполнения доставки заказа от дистрибьютора до розничной точки определяется расстоянием между ними. За один день транспортное средство преодолевает 10 единиц расстояния, поэтому время от момента заказа до выполнения доставки рассчитывается как Расстояние между
отправителем и получателем/10. Для планирования подобных событий используется элемент Динамическое событие (Dynamic Event). Добавим его в окно редактирования модели:

44 retStock+=EOQ; truck.get(0).jumpTo(distributor.get(0).getX(),distribut or.get(0).getY()); truck.get(0).rectangle.setVisible(false);
В момент наступления события уровень запаса розничной точки увеличивается на величину EOQ, транспортное средство перестает отображаться на презентации и мгновенно перемещается к дистрибьютору методом jumpTo().
Возвращаемся к редактированию диаграммы действий:
Добавляем Код, продолжая движение по ветви true:
Свойства: комментарий: Обработка заказа дистрибьютором, код: