Читайте данную работу прямо на сайте или скачайте
Курсовая. Имитационное моделирование правление запасами
ФГОУ СПО «Волгоградский технологический коледж»
«Проект защитил
с оценкой »
.И. Сухинин
30.05.05
Имитационное моделирование системы правления запасами с неудовлетворенным спросом
Курсовой проект
КП 11. 230105. 51. 0247 ПЗ
Разработчик А.И. Сухинин
30.05.05
Рук.проекта А.А. Теткин
30.05.05
Содержание
1. Введение
2. Понятие моделирования
3. Системы и модели правления запасами
4.1 Модельное время
4.2 Классы и объекты
4.3 События и методы
5. Реализация программы
6. Анализ результатов
7. Заключение
8. Список использованной литературы
ЕСЛИ НУЖНА ПРОГРАММА НА С++ ОБРАЩАЙТЕСЬ: saneek93@mail.ru
Оформление и правка возможна
1. Введение
Неизбежная рассогласованность ритма производства поставщиков и потребителей, дискретность процесса поставок, возможность случайных колебаний в интенсивности потребления или длительности интервалов между поставками относительно среднего (расчетного) ровня вынуждают создавать в системах снабжения запасы. Проблема совершенствования правления во всех звеньях народного хозяйства очень важна. Хозяйственные организации представляют собой сложные системы. Эффективность систем зависит от качества организационного правления ими. Возросшая интенсивность производства и взаимозависимость большого числа предприятий величивают экономический щерб от просчетов в планировании и предъявляют повышенные требования к качеству правления.
При решении широкого круга задач оптимизации управляющих решений по-лезны методы теории правления запасами. правление запасами в общем случае состоит во взаимодействии на соотношение между двумя основными факторами – пополнением и расходом запасов. Ясно, что чрезмерно большой запас приводит к избытку материальных ценностей и требует больших затрат на хранение, недостаточный запас может привести к перебоям в работе. Цель правления – оптимизация некоторого критерия, зависящего от расходов на хранение запасов, стоимости поставок, затрат, связанных с пополнением, штрафов и т. д.
Под запасами можно понимать выпускаемую некоторым предприятием продукцию (пополнение), которая поставляется потребителем определенными партиями (расход). При этом спрос на продукцию может быть детерминированным или случайным. правление запасами здесь состоит в определении размеров необходимого выпуска продукции для довлетворения данного спроса при словии минимизации суммарных затрат на хранение и пополнение запасов.
Под запасами можно понимать также запасы сырья или других материалов, поставляемые дискретными партиями (пополнение) и обеспечивающие непрерывное потребление в процессе производства (расход). Критерием оптимальности могут служить суммарные затраты на поставки и хранение запасов.Запасами могут быть товары, поставляемые в торговую сеть определенными партиями и предназначенные для довлетворения непрерывного случайного спроса. Критерий оптимизации – суммарные затраты на поставки, хранение запасов и изменение производственного ритма в связи с вариациями спроса.Запасы – это и сезонные товары, сохраняющиеся на складе ограниченной емкости. Их можно покупать и продавать в различных количествах по ценам, меняющимся во времени. Задача состоит в определении политики покупок и продаж, обеспечивающих максимум суммарной прибыли. Капитал тоже может рассматриваться как запас, причем цена его хранения определяется темпом инфляции.
Существует несколько причин относительно необходимости создания запасов. Согласно одной из них наличие запасов позволяет быстро довлетворять запросы
потребителей. Согласно другой наличие запасов позволяет поставщику нейтрализовать колебания спроса в словиях неравномерного потребления.
Весьма важной причиной, особенно для нашей страны, является сезонность производства многих важнейших видов продовольствия зерна, овощей, фруктов, и связанная с этим необходимость создания весьма больших запасов этих видов продовольствия. Весомой причиной является также даленность многих мест потребления той или иной продукции от мест ее производства. Сравнительно большие транспортные издержки на доставку этой продукции вынуждает доставлять ее большими партиями, тем самым создавать запасы. К созданию запасов вынуждает иногда необходимость отправлять произведенную продукцию (или сырье, полуфабрикаты и т. п., т. е. запасы) сравнительно большими партиями (по требованию транспортных организаций или по другим причинам).
Создание запасов требует больших затрат:
- запасы нужно где-то хранить, для этого нужно строить соответствующие складские помещения, а они довольно дороги и окупаются не очень быстро;
- значительные запасы ведут к омертвлению вложенных в них средств;
- как правило, хранение запасов ведет к худшению их характеристик, к их моральному старе нию.
Нельзя не согласиться с Ю. А. Беляевым в том, что «без запасов никто и ничто
существовать не может: ни машина, ни человек, ни государство, ни вселенная. Без запаса прочности мост разрушиться, парашют прорвется при малейшей перегрузке. Надежность технической системы создается запасом прочности конструкций, дублированием элементов, приданием запчастей. Портфель заказов редакции обеспечивает равномерную загрузку сотрудников и работу типографии. Запас мудрости руководителей позволяет им предвидеть будущие заботы и разглядеть пророков в своем отечестве; оценить неординарные идеи и справедливую критику; понять пользу плюрализма мнений и гражданских свобод. Запасы скудоумия, инерции, профессиональной неграмотности могут привести к не менее поразительным результатам».
Избыточные запасы были причиной многих неудач в бизнесе, оказывали дестабилизирующее влияние при кризисах. Излишние запасы являются тормозом на пути научно-технического прогресса. Переход на новый вид продукции обычно сдерживается требованием выработки всех именных запасов или дорогостоящим списанием их. Все эти проблемы обострились в связи с скорением научно-технического прогресса, диверсификацией спроса и индивидуализацией производства, сокращением сроков морального старения техники. Возросли сложность решаемых задач и цена ошибочных решений. Сложившаяся ситуация вызвала необходимость разработки разнообразныхсистем управлений запасами.
Целью данной курсовой работы является разработкамодели системы правления запасами. Основой для разработки модели в данной курсовой работе является метод имитационного моделирования. Так же курсовая работа предполагает создание программы на языке C++, обеспечивающей ввод исходной информации, ее обработку, реализацию алгоритма имитации процесса и выдачу необходимой информации.
2. Понятие моделирования
Модель – это любой образ, аналог, мысленный или становленный, изображение, описание, схема, чертеж, и т.п. какого-либо объекта, процесса или явления, который в процессе познания (изучения) замещает оригинал, сохраняя некоторые важные для данного исследования типичные свойства.
Моделирование - это исследование какого-либо объекта или системы объектов путем построения и изучения их моделей. А также – это использование моделей для определения или точнения характеристик и рационализации способов построения вновь конструируемых объектов.
Модель является средством для изучения сложных систем.
В общем случае сложная система представляется как многоуровневая конструкция из взаимодействующих элементов, объединяемых в подсистемы различных ровней. К сложным системам, в т.ч., относятся информационные системы. Проектирование таких сложных систем осуществляется в два этапа.
1). Внешнее проектирование.
На этом этапе проводят выбор структуры системы, основных ее элементов, организации взаимодействия между элементами, чет воздействия внешней среды, оценка показателей эффективности системы.
2). Внутреннее проектирование – проектирование отдельных элементов системы.
Типичным методом исследования сложных систем на первом этапе является моделирование их на ЭВМ. В результате моделирования получаются зависимости, характеризующие влияние структуры и параметров системы на ее эффективность, надежность и другие свойства. Эти зависимости используются для получения оптимальной структуры и параметров системы.
Модель, сформулированная на языке математики с использованием математических методов называется математической моделью.
Имитационное моделирование – воспроизведение на компьютере (имитация) процесса функционирования исследуемой системы. Для него не требуется приведение математической модели к виду, разрешимому относительно искомых величин.
Для имитационного моделирования характерно воспроизведение явлений, описываемых математической моделью, с сохранением их логической структуры, последовательности чередования во времени. Для оценки искомых величин может быть использована любая подходящая информация, циркулирующая в модели, если только она доступна для регистрации и последующей обработке.
Искомые величины при исследовании процессов методом имитационного моделирования обычно определяют как средние значения по данным большого числа реализаций процесса. Если число реализаций N, используемых для оценки искомых величин, достаточно велико, то в силу закона больших чисел получаемые оценки приобретают статистическую стойчивость и с достаточной для практики точностью могут быть приняты в качестве приближенных значений искомых величин.
3. Системы и модели правления запасами
Возникновение теории правления запасами можно связать с работами Ф.Эджуорта и Ф. Харриса, появившимися в конце XIX – начале XX вв., в которых исследовалась простая оптимизационная модель определении экономичного размера партии поставки для складской системы с постоянным равномерным расходом и периодическим поступлением хранимого продукта.
Запасами называется любой ресурс на складе, который используется для довлетворения будущих нужд. Примерами запасов могут служить полуфабрикаты, готовые изделия, материалы, различные товары, также такие специфические товары, как денежная наличность, находящаяся в хранилище. Большинство организаций имеют примерно один тип системы планирования и контроля запасов. В банке используются методы контроля за количеством наличности, в больнице применяются методы контроля поставки различных медицинских препаратов.
Простейшая схема системы правления запасами выглядит следующим образом (рис 1):
Рис. 1. Система правления запасами
Существуют причины, побуждающие организации создавать запасы:
- дискретность поставок при непрерывном потреблении;
- упущенная прибыль;
- случайные колебания:
- в спросе за период между поставками;
- в объеме поставок;
- в длительности интервала между поставками;
- предполагаемые изменения конъюнктуры:
- сезонность спроса;
- сезонность производства;
- ожидаемое повышение цен.
Имеются также причины, побуждающие предприятия стремиться к минимизации запасов на складе:
- плата за физическое хранение запаса;
- потери в количестве запаса;
- моральный износ продукта.
Рассмотрим определяющие понятия теории правления запасами.
Издержки выполнения заказа (издержки заказа) - накладные расходы, связанные с реализацией заказа. В промышленности такими издержками являются затраты на подготовительно-заготовочные операции.
Издержки хранения – расходы, связанные с физическим содержанием товаров на складе, плюс возможные проценты на капитал, вложенный в запасы. Обычно они выражаются или в абсолютных единицах, или в процентах от закупочной цены и связываются с определенным промежутком времени.
Упущенная прибыль – издержки, связанные с неудовлетворительным спросом, возникающим в результате отсутствия продукта на складе.
Совокупные издержки за период представляют собой сумму издержек заказа, издержек хранения и пущенного дохода. Иногда к ним прибавляются издержки на покупку товаров.
Срок выполнения заказов – срок между заказом и его выполнением.
Точка восстановления – ровень запаса, при котором делается новый заказ.
Основные модели правления запасами:
1.Модель оптимального размера заказа.
Предпосылки:
- темп спроса на товар известен и постоянен;
- получение заказа мгновенно;
- отсутствуют количественные скидки при закупке больших партий товара;
- единственные меняющиеся параметры – издержки заказа и хранения;
- исключается дефицит в случае своевременного заказа.
Исходные данные: темп спроса; издержки заказа и хранения.
Результат: оптимальный размер заказа; время между заказами и их количество за период.
2. Модель оптимального размера заказа в предположении, что получение заказа не мгновенно. Следовательно, нужно найти объем запасов, при котором необходимо делать новый заказ.
Исходные данные: темп спроса; издержки заказа и хранения; время выполнения заказа.
Результат: оптимальный размер заказа; время между заказами; точка восстановления запаса.
3. Модель оптимального размера заказа в предположении, что допускается дефицит продукта и связанная с ним пущенная прибыль. Необходимо найти точку восстановления.
Исходные данные: темп спроса; издержки заказа и хранения; пущенная прибыль.
Результат: оптимальный размер заказа; время между заказами; точка восстановления запаса.
4. Модель с четом производства (в сочетании с словиями 1 – 3). Необходимо рассматривать ровень ежедневного производства и ровень ежедневного спроса.
Исходные данные: темп спроса; издержки заказа и хранения; пущенная прибыль; темп производства.
Результат: оптимальный ровень запасов (точка восстановления)
5. Модель с количественными скидками. Появляется возможность количественных скидок в зависимости от размера заказа. Рассматривается зависимость издержек хранения от цены товара. Оптимальный ровень заказа определяется исходя из словия минимизации общих издержек дл каждого вида скидок.
4. Описание системы
В большом нивермаге планируется ввести систему правления запасами рдиоприемников. Время между поступлениями запросов покупателей на покупку ра-
диоприемника распределено экспоненциально с математическим ожиданием
0,2 недели. Если покупателю потребовался радиоприемник, его нет в запасе,
покупатель в 80% случаев отправляется в ближайший магазин, представляя со-
бой тем самым несостоявшуюся для данного нивермага продажу. В 20% таких
случаев делается повторный заказ, и покупатели ждут поступления следующей
партии товара. Магазин использует периодическую систему просмотра состоя-
ния запасов, в которой запас просматривается каждые 4 недели и принимается
решение о необходимости осуществления (размещения) заказа на новую партию
товара. Стратегия принятия решения состоит в размещении заказа, доводящего
запас до контрольного ровня — 72 радиоприемников. Текущее состояние запаса
определяется как наличный запас плюс заказанные ранее нивермагом радио-
приемники минус неудовлетворенный спрос, под которым понимаются помя-
нутые ранее 20% покупателей. Если текущее состояние запаса меньше или равно
18 радиоприемникам (точка заказа), заказ размещается. Время доставки заказа
(между его размещением и получением) постоянно и составляет 3 недели.
Необходимо смоделировать систему правления запасами за 6 лет (312 недель)
для получения статистических данных о следующих величинах:
- числе радиоприемников в запасе;
- неудовлетворенном спросе;
- количестве несостоявшихся продаж и времени между ними.
Начальные словия для имитации: состояние запаса — 72 радиоприемника, не-
удовлетворенного спроса нет. Чтобы меньшить смещение статистических дан-
ных из-за начальных словий, все статистические данные, накопленные к концу
первого года шестилетнего периода имитации, должны очищаться (обнуляться).
4.1 Модельное время
В качестве единицы модельного времени принимаем 1 ч. В самом деле, если пе-
ресчитать 0,2 недели в днях, получим среднее время между поступлениями за-
просов на покупку радиоприемника, равное 1,4. Следовательно, день — слишком
грубая единица времени, потому что при округлении экспоненциальной случай-
ной величины со средним 1,4 до ближайшего целого нам придется отбрасывать
дробные части, сравнимые с самой случайной величиной. 1,4 дня составляет
33,6 ч, поэтому интенсивность входного потока равна 1/33,6 ≈ 0,03 — ее мы и
подставим в качестве параметра экспоненциального распределения. Тогда общая
продолжительность моделирования составит 312 • 7 • 24 = 52 416 ч — тактов мо-
дельного времени. Значения же постоянных промежутком времени (4 недели и
3 недели) представим в программе в днях (соответственно, 28 и 21). При инициализации объекта Супермаркет (Supermarket) разыгрываем время, остав-
шееся до очередного просмотра состояния запасов, как целочисленную случай-
ную величину, равномерно распределенную на временном отрезке 4 недели.
Если этот отрезок выразить в часах, то выражение, вычисляющее случайную ве-
личину, должно быть таким: rand( )%672+l; если в днях -(rand( )%28+l)*24. Второе
выражение реализует равномерное распределение точнее. Дело в том, что функ-
ция rand( ) возвращает целочисленную случайную величину, равномерно распре-
деленную на отрезке от 0 до 32 767. Если необходимо снизить верхнюю границу
интервала до некоторого числа К, то конструкция rand( )%K обеспечит равномер-
ное распределение только в том случае, если 32 768 делится на К без остатка.
В противном случае некоторые значения будут более вероятны, другие — менее.
Нетрудно заметить, что нарушение равномерности распределения будет тем
больше, чем больше К. Например, для К = 3 различиями можно пренебречь,
а для К = 32 767 значение 0 будет в два раза вероятнее всех остальных. Поэтому
при генерации равномерной случайной величины мы снижаем значение делите-
ля, затем результат множаем на 24. Этим мы нисколько не нарушаем логику
моделирования. Да и с точки зрения здравого смысла, любой человек в описан-
ной в задаче ситуации на вопрос: «Сколько времени осталось до проверки?» —
даст ответ в днях, не в часах.
4.2 Классы и объекты
Данная задача по сути представляет собой сложненный вариант процесса слу-
чайного блуждания, где в качестве случайной величины выступает теку-
щий запас товара. Система является открытой, количество заявок в ней — пе-
ременной величиной без фиксированной верхней границы. Определяющую роль
в системе играет объект Супермаркет, для которого нужно, разумеется, создать
класс. Чтобы накапливать статистику о среднем времени ожидания товара теми
клиентами, которые при первом обращении не получили его и дали повторный
запрос, необходимо создать класс Клиент (Client) и хранить информацию о них в
объектах этого класса. В самом деле, клиенты, сразу получившие товар, в систе-
ме не задерживаются, и объекты для них создавать не нужно. То же самое отно-
сится и к клиентам, которые, не получив товар, не пожелали ждать. Те же клиен-
ты, которые согласились ждать прибытия очередной партии товара, остаются в
системе, и вплоть до момента получения ими товара информацию о них нужно
отслеживать, именно: вести чет времени ожидания. Для объекта Радиоприемник, тоже частвующего в работе системы, класс создавать нет необходимости, по-
скольку на всем протяжении моделирования мы работаем только с количества-
ми радиоприемников и никакая статистика по отдельно взятым единицам этого
товара не требуется.
Итак, с классом Клиент все ясно — его полями данных являются никальный
идентификатор и время, которое он к данному моменту провел в системе, ожи-
дая исполнения заказа. Опишем, какие поля данных должен иметь класс Супер-
маркет (SuperMarket).
Неизменяемые поля:
- интенсивность поступления клиентских запросов (0,03 заявок в час);
- периодичность проверок состояния запаса (28 дней);
- время исполнения заказа (21 день);
- нижний предел количества товара, при выходе за который делается заказ (18);
- уровень наличия товара, исходя из которого рассчитывается объем заказа (72);
- процент заявок, покинувших систему, из числа тех, которые не застали товар в наличии (80).
Изменяемые поля:
- время, оставшееся до прибытия следующего покупательского запроса на радиоприемник;
- время, оставшееся до получения заказа; в случае, если в данный момент мыне ждем заказа, значение равно -1;
- время, оставшееся до начала следующей проверки;
- объем заказа, получение которого ожидается; в случае отсутствия заказа равен 0;
- текущее количество товара;
- список казателей на объекты класса Client,ожидающие получения товара.В данном случае именно список, не массив, так как»длина очереди не имеет верхней границы;
- текущая длина очереди, может быть вычислена но списку казателей.
4.3 События и методы
Событий, меняющих состояние объекта Супермаркет, всего три: поступление кли-ентского запроса, проверка состояния запаса и прибытие заказа. Оформление заказа не является отдельным событием, входит в алгоритм проверки состояния
запаса. Каждому из этих трех событий соответствуют методы, алгоритмическая
реализация которых совершенно очевидна, не содержит никаких программных
ухищрений и очевидным образом кодирует словесное описание задачи. Объекты
класса Client не являются активными частниками процесса моделирования,
так как все действия по их созданию, обработке и далению происходят внутри
методов класса SuperMarket. Поэтому метода гип() у класса Client нет.
С какой целью задано словие сброса накопленной статистики по истечении
первого года? Дело в том, что если существует стационарный режим, случайный
процесс достигает его вне зависимости от начальных словий. Но за какое время
это произойдет, заранее ответить невозможно. Поэтому, если целью моделирова-
ния является получение стационарных характеристик, влияние начальных сло-
вий на результаты надо каким-то образом нивелировать. Сделать это можно двумя
способами: моделировать в течение длительного времени, так что соотношение
времен, проведенных в стационарном и переходном режимах, будет таким боль-
шим, что влиянием переходного режима можно пренебречь; в течение некоторого времени моделировать «вхолостую» и только затем, считая, что стационарный
режим же достигнут, включать режим сбора статистики. Ни один из способов,
разумеется, не дает стопроцентной гарантии, поскольку заранее ничего нельзя
сказать о длительности схождения процесса к стационарному режиму.
Условие «чернового» прогона в течение одного года с промежуточным сбросом
статистики реализовано в функции main( ). Здесь важно честь
следующее принципиальное обстоятельство. После сброса статистики возобнов-
ление моделирования происходит же не с того состояния объекта, с которого
оно начиналось. Поэтому очень важно, чтобы корректность работы методов не
зависела от начального состояния объекта. Чтобы проиллюстрировать эту
мысль, мы специально не стали вводить в число глобальных стачистических пе-
ременных счетчик числа заявок, покидающих очередь, который необходим для
подсчета среднего времени ожидания. Опасность подстерегает нас в случае, если
значение этого счетчика подсчитывать косвенно:
entered-rejected-satisfied-q_length+l.
где entered — счетчик всех запросов;
rejected — счетчик потерянных запросов;
satisfied — счетчик немедленно обслуженных запросов;
q_length — текущая длина очереди.
Казалось бы, все логично: после всех вычитаний остаются только те
заявки, которые побывали в очереди и же покинули ее. Здесь необходимо, од-
нако, соблюдение одного словия: в момент начала сбора статистики очередь
должна быть пуста. Иначе мы получим абсурдный результат в виде отрицатель-
ного значения счетчика (например, в начальный момент времени -q_length), что
приведет к некорректному подсчету среднего времени ожидания. Это затрудне-
ние преодолено следующим образом. Для классаSuperMarket вводится дополни-
тельное поле данных q_extra, которое инициализируется текущей длиной очереди
в момент завершения «чернового» прогона. Тогда в методе Supertterket: :complete(),
имитирующем поступление заказа и довлетворение за счет этого заявок, ожи-
дающих в очереди, порядковый номер довлетворенной заявки в выходном по-
токе можно рассчитать по формуле:
c=entered-rejected-satisfied-q_length*q_extra+l
Величина 1/с затем используется в качестве средняющего множителя для рас-
чета среднего времени пребывания заявки в системе.
5. Реализация программы
Для моделирования системы управления запасами (с неудолетворенным запросом) был выбран язык программирования C++ и написана программа на этом языке, позволяющая в полной мере отразить функционирование системы.
Листинг программы файл 1.h. Описание протоколов классов
#include
#include
#include
#include
using namespace std;
#include "random.h"
#include "List.h"
FILE *sojourn; //файл для сбора статистики о времени ожидания
//товара
FILE *que; //файл для сбора статистики о длине очереди;
//пополняется один раз в неделю
long int entered=0L; //счетчик общего числа заявок на товар
long int rejected=0L; //счетчик числа заявок, сразу покинувших систему
long int satisfied=0L; //счетчик числа заявок, немедленно довлетворенных
int num_orders=0; //счетчик числа сделанных заказов
float soj_ave=0; //переменная для подсчета среднего времени ожидания
float que_ave=0; //переменная для подсчета средней длины очереди
long int total; //счетчик тактов модельного времени (количество
//часов)
//Протокол класса Client
class Client
{
long int id; //уникальный идентификатор клиента
int hours; //время, проведенное клиентом в системе
public:
friend class SuperMarket;
Client() //метод-конструктор
{
//Вычисляем, какая это по счету заявка, поставленная в очередь,
//от момента начала моделирования, и назначаем ей идентификатор
id=entered-rejected-satisfied+1;
hours=0;
}
void Print();
long int getId();
int getTime();
};
//Вывод содержимого объекта
void Client::Print()
{
//168 - количество часов в неделе
printf("id=%ldn ждет исполнения заказа %d недельn", id, hours/168);
}
//Чтение идентификатора заявки
long int Client::getId()
{
return(id);
}
//Чтение проведенного в системе времени
int Client::getTime()
{
return(hours);
}
//Протокол класса Супермаркет
class SuperMarket
{
int to_arrival; //время до прибытия следующей заявки
int to_order; //время до исполнения заказа
int order; //объем ожидаемого заказа
int to_check; //время до следующей проверки
int q_length; //текущая длина очереди
int exist; //текущее количество товара
ListNode *queue; //очередь ожидающих заявок
//Описание неизменяемых полей данных
const static int mu=3;
const static int checking=28;
const static int ordering=21;
const static int level1=18;
const static int level2=72;
const static int percentage=80;
public:
SuperMarket(int i);
void run();
void arrival();
void complete();
void check();
void Print();
int getLength();
int q_extra; //переменная для хранения начальной длины очереди
};
//Метод-конструктор. Параметр - исходное количество товара
SuperMarket::SuperMarket(int i)
{
q_length=0;
q_extra=0;
queue=NULL;
to_arrival=(int)(get_exp((float)mu/100));
//"Насильственно" станавливаем экспоненциальную случайную величину
//в единицу, если после округления до целого она обратилась в ноль.
//Вероятность такой ситуации тем меньше, чем с большим коэффициентом
//промасштабировано время. В данном случае она равна
//1-exp(-0.03 * 0.5) = 0,015.
if (to_arrival==0) to_arrival=1;
to_order=-1;
order=0;
exist=i;
//Время до ближайшей проверки станавливается случайным образом
to_check=(rand()%checking+1)*24;
}
int SuperMarket::getLength()
{
return(q_length);
}
void SuperMarket::Print()
{
printf("Следующая заявка поступит через %d часовn", to_arrival);
if (to_order>0) {
printf("Заказ прибудет через %d дней, он составляет %d единиц товараn", to_order/24, order);
}
else
printf("Заказа нетn");
printf("Следующая проверка запасов состоится через %d днейn", to_check/24);
printf("Ждут довлетворения запроса %d клиентовn", q_length);
printf("Имеется %d единиц товараn", exist);
}
//Моделирование прибытия нового запроса
void SuperMarket::arrival()
{
//int i;
Client *p=NULL;
//Разыгрываем новый интервал между прибытиями
to_arrival=(int)(get_exp((float)mu/100));
if (to_arrival==0) to_arrival=1;
entered++; //инкремент общего счетчика запросов
if (exist>0) //товар есть
{
exist--; //декремент количества товара
satisfied++; //инкремент счетчика сразу довлетворенных
//запросов
}
else //товара нет
{
if (rand()%100
{
rejected++; //инкремент счетчика потерянных клиентов
return;
}
//Создаем новый объект класса Client и новый элемент списка
p=new Client();
ListNode *ptr=new ListNode(p,NULL);
//Очереди нет. Новый элемент становится головой списка
if (q_length==0) queue=ptr;
//Добавляем новый элемент в хвост списка
else ListAdd(queue,ptr);
q_length++; //инкремент длины очереди
}
return;
}
//Имитация прибытия заказа
void SuperMarket::complete()
{
int mi, i, b, c;
to_order=-1;
exist+=order;
order=0;
if (q_length==0) return;
//Определяем, сколько единиц товара будет продано немедленно
if (exist
for(i=0;i
{
//Отпускаем товар клиенту, находящемуся в голове списка
b=queue->Data()->getTime();
//Время ожидания записываем в файл (в днях)
fprintf(sojourn,"%.2fn", ((float)b)/24);
//Определяем, каким по счету из покинувших очередь с момента начала
//моделирования является этот клиент. учитывается начальная длина очереди.
c=entered-rejected-satisfied-q_length+q_extra+1;
soj_ave=soj_ave*(1-1.0/c)+(float)b/c; //пересчет среднего времени
//ожидания
//Удаляем элемент из головы списка
ListNode *ptr=queue;
queue=queue->Next();
delete ptr;
q_length--; //декремент длины очереди
exist--; //декремент количества товара
}
}
//Имитация проверки состояния запаса
void SuperMarket::check()
{
int a;
to_check=checking*24;
//Вычисление текущего состояния запаса
a=exist+order-q_length;
if (a>=level1) return; //заказ делать не нужно
//Заказ делать нужно
to_order=ordering*24;
//вычисление объема заказа
order=level2-a;
num_orders++; //инкремент количества заказов
}
//Метод-диспетчер
void SuperMarket::run()
{
//int i;
//float a;
ListNode *ptr;
to_arrival--;
if (to_arrival==0) arrival();
if (to_order>0) to_order--;
if (to_order==0) complete();
to_check--;
if (to_check==0) check();
//Инкремент текущего времени пребывания для всех клиентов, ожидающих //исполнения заказа
if (queue!=NULL)
{
ptr=queue;
while(ptr!=NULL)
{
((ptr->Data())->hours)++;
ptr=ptr->Next();
}
}
//Еженедельная запись в файл текущей длины очереди
if (total%7==0) fprintf(que,"%dn", q_length);
//Пересчет средней длины очереди
que_ave=que_ave*(1-1.0/(total+1))+((float)q_length)/(total+1);
return;
}
Листинг программы файл random.h
#include
#include
#include
float get_exp(float mu) //генератор случайных чисел, распределенных
//экспоненциально
{
int r_num; float root, right;
r_num=rand(); /*получение случайного целого
/числа*/
right=((float)r_num)/(RAND_MAX+1); /*проекция на интервал (0;1)*/
root=-log(1-right)/mu; /*вычисление значения обратной
/функции*/
return(root);
}
int get_uniform(int a, int b)
{ //Генерация равномерно распределенной величины a+b
int x, y;
x=rand()%(b+1);
y=rand()%2;
if (y==0) return(a-x);
return(a+x);
}
float get_triangle(float A, float B, float C)
{
int r_num; float root, right;
r_num=rand(); //получение случайного целого
//числа
right=((float)r_num)/(RAND_MAX+1); //проекция на интервал (0;1).
//Константа RAND_MAX=32767 (215-1) определена в cstdlib
if (right<(C-A)/(B-A)) root=A+sqrt(right*(B-A)*(C-A));
else root=B-sqrt((1-right)*(B-A)*(B-C));
return(root);
}
float get_pareto(float A, float B)
{
int r_num; float root, right;
r_num=rand(); /*получение случайного целого числа*/
right=(float)r_num/RAND_MAX+1; /*проекция на интервал (0;1)*/
root=A/(pow(1-right, (float)1.0/B)); /*вычисление значения обратной функции*/
return(root);
}
Листинг программы файл List.h
template //это постоянная «заставка»
//к класам и функциям
//c парметризированным типом
class ListNode {
private:
ListNode *next; //указатель на следующий элемент списка
Type *data; //указатель на данные хранящиеся в элементе списка
public:
ListNode(Type *d, ListNode *n); //конструктор
~ListNode(); //деструктор
Type *Data(); //метод для чтения данных
ListNode *Next(); //метод для чтения казателя
//на следующий элемент
void PutNext(ListNode *n); //метод для записи казателя
//на следующий элемент
void Print(); //печать содержимого элемента списка
};
template
ListNode::ListNode(Type *d, ListNode *n) : next(n), data(d)
{
}
template
ListNode::~ListNode()
{
delete data;
}
template
Type *ListNode::Data()
{
return data;
}
template
ListNode *ListNode::Next()
{
return next;
}
template
void ListNode::PutNext(ListNode *n)
{
next=n;
}
template
void ListNode::Print()
{
data->Print(); //предпологается наличие метода Print() для класса
//имя которого будет подставленно в пользовательском коде
}
//Описание класса-шаблона завершено, далее идут функции-шаблона, работающие
//не с отдельным элементом, со всеми списком
template
void ListAdd(ListNode *head, ListNode *li)
//добавление нового элемента li в хвост списка с головой head
{
ListNode *old, *v;
//ищем внешний хвост списка
for (v=head; v!=NULL; v=v->Next())
old=v;
old->PutNext(li); //добавляем в след за найденым хвостом новый элемент списка
}
template
ListNode *ListDelete(ListNode *head, ListNode *li)
//удаление элемента li из списка с голоыой head
//функция возвращает казатель на голову нового списка
{
//int j;
ListNode *old, *o1;
if (li==head) //удаляемый элемент может быть головой списка
//в этом случае голова у списка меняется
{
o1=head->Next();
delete li;
return o1;
}
//Удаляемый элемент не являеться головой списка. Голова остаеться прежняя
for (ListNode* v=head; v!=li; v=v->Next())
//поиск элемента предшедствующего даляемому
old=v;
o1=li->Next();
old->PutNext(o1);
//предшествующий элеиент теперь «видит» элемент стоящий в списке вслед
//за даленным
delete li;
return head;
}
//печать всех элементов списка с головой head
template
void ListPrint(ListNode *head)
{
for (ListNode* v=head; v!=NULL; v=v->Next())
v->Print(); //подсчет количества элементов в списке с головой head
}
template
int ListCount(ListNode *head)
{
int i; i=0;
for (ListNode* v=head; v!=NULL; v=v->Next())
{
v->Print();
i++;
}
return i;
}
Листинг программы функция main()
#include "stdafx.h"
#include "iostream"
#include "4.h"
#define N 52416 // общее время моделирования
using namespace std;
int main(){
//Открытие файлов для сбора статистики
que=fopen("que1", "wt");
sojourn=fopen("sojourn", "wt");
//Инициализация генератора случайных чисел
srand((unsigned)time(0));
SuperMarket s(72);
//"Черновой" прогон в течение года. 8760 - количество часов в году
for(total=0L;total<8760;total++) {
s.run();
}
fclose(que);
fclose(sojourn);
//сброс статистики
que=fopen("que1", "wt");
sojourn=fopen("sojourn", "wt");
entered=0L;
rejected=0L;
satisfied=0L;
num_orders=0;
soj_ave=0;
que_ave=0;
//Запись текущей длины очереди в поле данных q_extra перед началом сбора //статистики
s.q_extra=s.getLength();
//Основной моделирующий цикл
for(total=0L;total
s.run();
}
fclose(sojourn);
fclose(que);
setlocale(LC_ALL, "Russian");
//Вывод на печать результатов имитационного эксперимента
cout << "Всего поступило заявок " << entered << endl;
cout << "Доля потерянных заявок " << ((float)rejected)/entered << endl;
cout << "Доля немедленно обслуженных заявок " << ((float)satisfied)/entered << endl;
cout << "Количество заказов " << num_orders << endl;
cout << "Среднее время ожидания " << soj_ave/24 << " дней" << endl;
cout << "Средняя длина очереди " << que_ave << endl;
_gettch();
6. Анализ результатов
Многократный прогон модели в течение 6 лет дал следующие результаты:
Рис. 2. Снимок работы программы
- количество заявок — 1567;
- доля потерянных заявок — 0,088;
- доля немедленно довлетворенных заявок — 0,89;
- количество заказов — 22;
- среднее время ожидания — 8,2 дней;
- средняя длина очереди — 0,109.
Более интересны другие зависимости. Предположим, что мы не можем ни величить скорость выполнения заказа, ни снизить требовательность клиентов, ни
расширить складские площади для хранения более 72 единиц товара. Тогда по-
лучается, что мы можем правлять только периодичностью проверки запасов
(она не может быть менее трех недель — срока исполнения заказа) и нижним по-
рогом заказа (он не может превышать 72). В числе показателей эффективности
функционирования оставим три: долю потерянных заявок, количество заказов,
среднее время ожидания.
На рис. 3-5 приведены зависимости этих показателей от периодичности проверки, все времена измерены в днях. Мы видим, что зависимости эти отнюдь
не монотонны, хотя общие тенденции к росту или меньшению все же сохраня-
ются.
Рис. 3. Зависимость доли потерянных заявок от периодичности проверки запасов
Рис. 4. Зависимость количества заказов от периодичности проверки запасов
Рис. 5. Зависимость среднего времени ожидания от периодичности проверки запасов
Суть его в том, что для данной задачи небольшое величение периодичности
проверки запасов совсем не обязательно, как это ни странно, приводит к худше-
нию показателей, может, наоборот, значительно их лучшить. Все зависит от
того, в какой момент мы «поймаем» проверкой запасов ситуацию, когда текущий
запас меньшился до 18. Предположим, что в момент времени T дней он стал
равен 17. Если периодичность проверки такова, что проверка произошла на
(Т - 1)-й день, то эта ситуация очень нехороша, так как то, что запас меньше
критического значения, будет обнаружено очень нескоро, соответственно, неско-
ро произойдет и пополнение. Если же величить периодичность таким образом,
что проверка произойдет на несколько дней позже, чемТ, ситуация значительно
улучшится, так как время от меньшения запаса до его пополнения сократится.
Таким образом, если мы, к примеру, хотим обеспечить долю потерянных заявок
не более 0,2, периодичность проверки либо должна быть менее 62 дней, либо ле-
жать в интервале приблизительно от 92 до 122 дней (условие задачи этому огра-
ничению как раз довлетворяет — проверка запасов выполняется раз в 28 дней).
Этой же цели, как следует из графика, изображенного на рис. 5, можно до-
стичь, становив нижний ровень заказа не более 5.
Монотонный характер зависимостей, изображенных на рис. 6-8, легко объясним. В процессе работы супермаркета запас товара неуклонно меньшается,
и чем раньше мы начнем «бить тревогу» (то есть сделаем заказ на его пополне-
ние), тем качественнее обслужим своих клиентов.
Рис. 6. Зависимость доли потерянных заявок от нижнего ровня заказа
Рис. 7. Зависимость количества заказов от нижнего ровня заказа
Рис. 8. Зависимость среднего времени ожидания от нижнего ровня заказа
Можно поставить еще одну интересную задачу. Как видно из приведенных на
рисунках графиков, меньшение доли потерянных заявок и среднего времени
ожидания сопровождается величением количества сделанных заказов, каждый
из которых может сопровождаться определенными накладными расходами вне
зависимости от объема заказанного товара. Если степень «дискомфорта», кото-
рый доставляет нам единица каждой из этих величин, количественно выразить
весовыми коэффициентами с1, с2, с3, то возникает задача минимизации целевой
функции:
F(P) = с1 • Lost + с2 • Orders + с3 • Tср
или
F(L) = с1 • Lose + с2 • Orders + с3 • Tср,
где— периодичность проверки;
Lost — доля потерянных заявок;
Orders — количество заказов;
Tср — среднее время ожидания;
L — нижний ровень заказа.
Весовым коэффициентам можно придать вполне реальный смысл, если предположить, что за каждую потерянную заявку, за каждый день ожидания клиента и за каждый заказ мы платим определенную сумму и нужно минимизировать общие
расходы. Чтобы приблизительно выровнять значения слагаемых, примем с1 = 15,
с2 = 1, Сз = 0,35.
Рис. 9. Зависимость значения критерия от периодичности проверки
Все это реально, так как ход клиента без покупки, да еще с намерением большев этот супермаркет не возвращаться — тяжелая потеря для торговой организа-
ции.
Согласно графику, приведенному на рис. 9, минимум критерия достигается
при= 59, на значение минимума в этой точке — 26,3 — ненамного отличается
от значения в другой точке локального минимума (Р = 36), равного 26,6. Видимо,
лучше все-таки принять периодичность проверки, равную 36 дням.
Проверим, можно ли лучшить решение за счет варьирования нижнего ровня
заказа (сохраняя Р = 28 дней). График на рис. 10показывает, что минимум кри-
терия достигается при L = 8 и равен приблизительно 25,8, то есть он немного
меньше минимума по параметру Р. Следовательно, формулируем вывод: мень-
шение запаса до значения 18 — еще не повод бить тревогу. Следует сохранять
терпение и выдержку и оформлять заказ на пополнение запаса только тогда, ко-
гда запас меньшится до 8.
Рис. 9. Зависимость значения критерия от нижнего ровня заказа
Разумеется, при иных значениях весовых коэффициентов оптимальное решение
тоже будет иным. Задание этих коэффициентов близкими к реальным зависит
исключительно от опыта и квалификации эксперта, например главного бухгал-
тера или коммерческого директора супермаркета.
7. Заключение
В результате выполнения курсовой работы были достигнуты следующие результаты:
- изучены метод имитационного моделирования экономических объектов;
- получены навыки проведения численных экспериментов на имитационных моделях экономических систем;
- приобретен опыт проведения анализа по результатам данных экспериментов на имитационной модели;
8. Список использованной литературы
- Труб И. И. «Объектно-ориентированное моделирование на С++»: учебный курс.-Пб.:Питер, 2006.-411с.:ил.
- Речкалов Системы и модели правления запасами. Режим доступа: ссылка более недоступна2007/fvti/toichkina/library/invest7.htm
- Сиситемы правления запасами: Режим доступа:
ссылка более недоступнаs/Sistemy_upravleniya_zapasami.html
4. Кельтон В., Лоу А. Имитационное моделирование. – Пб: Питер, 2004. – 848 с
5. Вентцель Е.С. «Теория вероятностей», М.: Высшая школа, 1г., 576 стр.
- 6. Федосеева В.В. «Экономико-математические методы и прикладные модели»,
под ред., Москва «Юнити» 2001 г.
7. Гинзбург А.И. Экономический анализ: Предмет и методы. Моделирование ситуаций. Оценка правленческих решений: учебное пособие. –Пб.: Питер, 2003. -622 с.
8. Грабовый П.Г. Риски в современном бизнесе. –М.: Финансы и статистика, 2. -200 с.
- Дубров А.М., Лагоша Б.А., Хрусталев Е.Ю. Моделирование рискованных ситуаций в экономике и бизнесе. –М.: Финансы и статистика, 2004. -224 с.
- Князевская Н.В., Князевский В.С. Принятие рискованных решений в экономике и бизнесе. –М.: Контур, 1998. -160 с.
- Кремер Н.Ш. Исследование операций в экономике. –М.: Банки и биржи, 2003. -407 с.
- Шикин Е.В. Математические методы и модели в правлении. –М.: Финансы и статистика, 2002. -430 с.
- Эддоус М., Стэнсфилд Р. Методы принятия решений. – М.: ЮНИТИ, 1997. -425 с.