Файл: Разработка имитационных моделей управления запасами в цепях поставок Москва 2011 2 Введение.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.12.2023
Просмотров: 91
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
45 create_RetReplenishment(retailer.get(0).retDist/10); truck.get(0).rectangle.setVisible(true); truck.get(0).moveTo(retailer.get(0).getX(),retailer.get
(0).getY());
Создается динамическое событие RetReplenishment с заданными параметрами. Параметр в скобках определяет разницу времени между текущим моментом и наступлением события.
После этого запускается анимация доставки. Метод setVisible делает транспортное средство видимым, метод moveTo(x,y) перемещает транспортное средство в место расположения розничной точки.
Теперь перейдем к редактированию ветви false первого модуля принятия решения «Спрос превышает запас ритейлера?». Добавляем элемент
Код:
Комментарий: Обновление уровня запаса ритейлера, код: retStock-= retailer.get(0).currentDemand;
Запас розничной точки уменьшается на величину потребительского спроса.
Добавляем модуль принятия решения (последний в этой диаграмме действий):
46
Комментарий: Заказ ритейлера меньше порогового уровня и нет заказа в пути?,код: retStock < ROP && truck.get(0).isMoving() == false
Первая часть условия сравнивает уровень запаса с пороговым уровнем, вторая проверяет, находится ли заказ в пути. Для объединения двух условий используется знак «&&», соответствующий логическому знаку «И»
(конъюнкции).[1,p19].
Добавляем код по ветви true принятия решения:
Копируем элемент Обработка заказа дистрибьютором и вставляем его на ветви true.
Теперь алгоритм выглядит следующим образом:
47
Добавим на Временной график пороговый уровень запаса:
Теперь при запуске модели можно отслеживать момент перезаказа на графике.
Запускаем модель:
48
Окно презентации стало содержать анимацию процесса доставки.
Также на графике видно, что спрос варьируется в зависимости от периода.
Начальный уровень запаса retStock меньше порогового уровня запаса. Для того чтобы, начиная с первого периода, система работала в «нормальном» режиме, требуются два условия:
- величина EOQ должна превышать ROP
- начальный уровень запаса retStock должен быть равен EOQ+ROP.
Изменим величину EOQ:600 и добавим инициализацию запаса в модель:
49 retStock=EOQ+ROP;
Учет случаев возникновения дефицита
Добавим в модель элемент Текст, который будет отображать количество случаев дефицита. Расположим его над графиком:
Текст: retShortage
При данных настройках модели за время работы не будет зафиксировано ни одного случая дефицита.
Если поменять параметр
Конечное время на 1000, то получим 7 случаев дефицита:
50
Данный пример демонстрирует важность выбора срока работы модели для оценки вероятности наступления события.
Учет издержек
Издержки на хранение рассчитываются каждый период, издержки на транспортировку – по факту выполнения поставки. Ставка на хранение одной единицы запаса в течение одного периода составляет 5 единиц, ставка на
51 транспортировку зависит от расстояния между дистрибьютором и розничной точкой и составляет 5000 единиц за 10 единиц пройденного расстояния.
Добавим в класс Retailer параметры ставок retholdingrate и rettrrate:
Тип обоих параметров: double. Значения по умолчанию: retholdingrate:5, rettrrate:5000.
Добавим в класс Main переменные для учета текущего уровня издержек:
Тип всех трех переменных double. retHoldingcost – текущие издержки на хранение, retTrcost – текущие транспортные издержки, totalCost – общие издержки.
Отредактируем событие ordering: retHoldingcost+=retStock*retailer.get(0).retholdingrate
; totalCost=retHoldingcost+retTrcost;
52
Таким образом, каждый период сначала рассчитываются издержки на хранение за текущий период, потом рассчитываются общие издержки: суммируются транспортные издержки и издержки на хранение.
Расчет транспортных издержек проведем в Динамическом событии
RetReplenishment. Добавим параметр time, который соответствует сроку доставки:
Добавим код в окно Действие: retTrcost+=time*retailer.get(0).rettrrate;
При создании динамического события параметр указывается после времени, через которое оно должно произойти.
Например,
RetReplenishment(x,y). В данном случае x – разница между модельным временем наступления события и текущим моментом, y – значение параметра time, который был дополнительно добавлен.
53
Отредактируем код генерации динамического события в диаграмме состояний: create_RetReplenishment(retailer.get(0).retDist/10,reta iler.get(0).retDist/10);
Добавление данных на окно презентации
Добавим на окно презентации текстовые поля, отображающие текущий уровень издержек:
Текст:
54
«Издержки на хранение »+round(retHoldingcost)
«Издержки на транспортировку »+ round(retTrcost)
«Общие издержки »+round(totalCost)
В AnyLogic есть возможность комбинировать текст и значения переменных в одной строке. Знак «+» связывает элементы строки, текст в кавычках определяется как статический текст[1,p20].
Добавим подобный
«комментарий» к текстовому полю, отображающему уровень дефицита.
Запустим модель:
Теперь отображаются и динамически обновляются основные параметры производительности модели.
55
Оптимизационный эксперимент
Базовые настройки
Найдем значения ROP и EOQ, при которых общие издержки totalCost минимальны. Для этого создадим оптимизационный эксперимент. Более подробную информацию об оптимизационных экспериментах можно получить в справочной системе программы.
Добавляем оптимизационный эксперимент:
Выбираем Оптимизация:
56
Переходим в режим редактирования оптимизационного эксперимента:
57
Выбираем количество итераций: 10000. В оптимизационном эксперименте класс Main указан как корневой (root), поэтому минимизируем функцию общих издержек root.totalCost.
Далее настраиваем изменяемые параметры:
Меняем Тип каждого из параметров EOQ и ROP на дискретный. Шаг изменения параметров запасов установим равным 50, диапазон изменения параметров:
EOQ: 100…3000
ROP: 100…3000
Одно из ограничений модели: ни у одной розничной точки количество случаев возникновения дефицита не должно превышать 15 раз за 1000 дней
(1,5%).
Перейдем к пункту Ограничения оптимизационного эксперимента:
58
Значение переменной retShortage не должно превышать 15.
Величина оптимального размера заказа не должна быть ниже порогового уровня запаса.
В пункте Репликации выбираем Использовать репликации, Кол-во
репликаций за итерацию:3. Каждое решение будет «прогнано»
(рассчитано) три раза при различных начальных значениях генератора случайных чисел.
Использование репликаций замедляет поиск решения, но увеличивает уровень статистической значимости результата. Следует помнить, что из-за вероятностной структуры спроса при заданных параметрах не всегда будут
59 выполняться ограничения. Чем больше репликаций проведено для каждого набора данных, тем в большем проценте прогонов модели будут выполняться ограничения.
Вернемся к пункту свойств Основные и нажмем кнопку Создать
интерфейс:
Корректируем расположение элементов:
60
После этого запускаем оптимизационный эксперимент:
Поиск оптимального решения представлен в отдельном окне:
Найденные решения EOQ:950, ROP:500.
Уточнение величин параметров
Сузим диапазон поиска и уменьшим шаг изменения параметров. Если учесть, что в эксперименте шаг изменения параметров был 50 единиц, то
61 уточненное оптимальное решение должно находиться в диапазоне 900-
1000 для EOQ и 450-550 для ROP. Поменяем шаг на 10 единиц.
Запустим эксперимент с новыми параметрами:
Общее количество прогонов в данном эксперименте составит 121 итерацию (11*11)
62
В данном случае оптимальные значения составили EOQ:970 и
ROP:470.
При запуске оптимизационного эксперимента используется один и тот же набор случайных значений:
Поменяем настройки: выберем пункт Случайное начальное число
(уникальные «прогоны»).
Запустим оптимизационный эксперимент еще несколько раз. В каждом случае оптиальное решение будет находиться в диапазоне 900…1000 и
450…550, и значение целевой функции также будет немного отличаться.
63
Данный пример иллюстрирует одну из особенностей имитационного моделирования – если с каждым новым запуском используются различные начальные параметры генератора случайных чисел, то значения выходных данных модели (в том числе и целевая функция totalCost) будут варьироваться.
Есть множество субоптимальных значений ROP и EOQ, при которых значение целевой функции издержек изменяется незначительно.
Задания:
1)Рассчитайте аналитически оптимальные параметры управления запасами при помощи формулы EOQ и формулы расчета страхового запаса при
64 вероятностной структуре спроса и сравните с результатом оптимизационного эксперимента.
2)Измените тип распределения спроса на треугольное распределение[3] triangular(0,demandMean*3,demandMean) и проведите оптимизационный эксперимент. Как и почему изменились параметры управления запасами и ожидаемые издержки?
3)Постройте график ожидаемых издержек системы при уровне сервиса 80%,
90%, 95%, 98.5%, 99,5%
1 2 3 4
2.2 Модель с несколькими розничными точками
Описание задачи
Данная задача является расширенной версией предыдущей задачи.
Увеличим количество розничных точек до восьми. Допустим, розничные точки и дистрибьютор расположены в пространстве следующим образом
(координаты дистрибьютора (50,50)):
Расстояние между розничной точкой и дистрибьютором рассчитывается по формуле:
65
Где и координаты розничной точки, а и координаты дистрибьютора.
Ни у одной розничной точки недопустим дефицит более 1,5%.
При транспортировке заказа десять единиц расстояния преодолевается за один день.
Таблица параметров розничных точек:
Параметры розничных точек
Порядковый номер розн. точки
1 2
3 4
5 6
7 8
Координата x
1 10 4
6 9
3 5
8
Координата y
1 5
3 6
10 8
9 6
Спрос, mean
80 90 30 57 73 91 120 91
Спрос, std
18 20 30 12 25 17 34 25
Расстояние до дистрибьютора
6 5
3 2
7 4
4 4
Расстояние до дистрибьютора (в днях пути) округлено в большую сторону, так как спрос генерируется каждый день в самом начале дня
(уровень запаса обновляется один раз в день в начале дня). Спрос задается нормальным распределением. Ставки издержек такие же, как и в предыдущей задаче.
Задачи:
1. смоделировать и отразить на презентации работу цепи поставок;
2. найти оптимальные значения параметров управления запасами.
Модификация класса Main
66
Основное отличие от предыдущей версии – количество розничных точек. При оптимизационном эксперименте требуется найти оптимальные параметры управления запасами для каждой из восьми розничных точек.
Переименуем параметры ROP и EOQ в ROP1 и EOQ1:
Добавим параметры ROP2…ROP8 и EOQ2…EOQ8:
Значения по умолчанию параметров EOQ1...8: 1000, ROP1…8:
500.
Как мы могли убедиться в предыдущем примере, оптимизационный эксперимент работает только с параметрами. Для удобства работы с параметрами создадим массивы переменных, где будут храниться их значения:
67 retEOQ – массив величин EOQ (размер заказа) розничных точек. Тип массива int[]. (Квадратные скобки – обозначение массива)[1,p21]
Начальное значение: new int[]{EOQ1,EOQ2,EOQ3,EOQ4,EOQ5,EOQ6,EOQ7,EOQ8} retROP
– массив величин ROP (пороговый уровень запаса) розничных точек. Тип массива int[].
Начальное значение: new int[]{ROP1,ROP2,ROP3,ROP4,ROP5,ROP6,ROP7,ROP8}
Массивы retEOQ и retROP инициализируются значениями параметров EOQ1..8 и ROP1..8.
Все переменные, которые связаны с розничными точками, в модели будут реализованы в виде массивов: