logo

3.2.3. Совершенствование модели парикмахерской

Р

Рис. 3.25. Диалоговое окно таймера

анее мы замечали, что число входящих клиентов оказывалось больше числа выходящих. Постараемся исправить этот недостаток. Увеличим длину репликации до 15 часов и снова просчитаем нашу модель. Теперь в отчёте мы можем заметить, что число входящих клиентов стало равным числу выходящих, т.е. мы слишком рано прервали счёт. В этом можно убедиться ещё следующим образом. Выведем в область модели изображение часов. Для этого на панели инструментов надо нажать кнопку и заполнить диалоговое окно, подобно тому, как это изображено на рис. 3.25. После закрытия диалогового окна надо навести курсор на свободную область окна модели и сделать щелчок левой клавишей мыши, сместить курсор для выделения прямоугольной области и опять щёлкнуть левой клавишей мыши. В результате в выделенной области будут отображаться часы. Запустим модель на счёт и остановим его в момент, когда показание таймера будет примерно соответствовать 10 часам. В пошаговом режиме счёта убедимся, что парикмахер работает после закрытия заведения, пока не обслужит всех клиентов. Таким образом мы можем заключить, что несоответствие числа входящих и выходящих клиентов было результатом того, что мы слишком рано прервали счёт, устанавливая длину репликации, равной времени работы парикмахерской.

На следующем этапе подсчитаем прибыль, которую даёт предприятие. Положим, что мужская стрижка обходится клиенту в 60 р., а женская в 100. Парикмахеру надо заплатить за работу 800 р. в день. Остальные расходы пока учитывать не будем. Усовершенствованная модель представлена на рис. 3.26. Назовём эту модель BarberShop2. Наиболее явным её отличием от исходной модели является наличие новой цепочки блоков Create, Assign3, Record1 и Dispose2. Эта цепочка служит для генерации сигнала расчета прибыли. Этот сигнал появляется по окончании рабочего дня, но до завершения репликации. Например, зададим время появления сигнала – 14 часов, а длину репликации – 15 часов.

Рис. 3.26. Усовершенствованная модель парикмахерской

Образец заполнения диалогового окна блока Create представлен на рис. 3.27. В блоке Assign3 рассчитывается прибыль, обозначенная переменной Profit по формуле:

60NM+100NW-800NRes. (3.1)

В этой формуле переменные NM, NW и NRes обозначают количество клиентов-мужчин, клиентов-женщин и количество парикмахеров соответственно. Образец заполнения диалогового окна этого блока представлен на рис. 3.28.

Рис. 3.27. Образец заполнения блока Create

Рис. 3.28. Образец заполнения диалогового окна блока Assign

Рис. 3.29. Образец заполнения диалогового окна блока Record

Блок Record служит для записи значения переменной Profit в раздел User Specified отчёта. Образец заполнения диалогового окна блока Record представлен на рис. 3.29. В блоках Assign1 и Assign2 добавлены выражения для подсчёта числа клиентов – мужчин и женщин (рис. 3.30).

Рис. 3.30. Заполнение диалоговых окон блоков Assign1 и Assign2

Ещё одним усовершенствованием является то, что мы ввели новую переменную NRes, определяющую число работников парикмахерской. Это нам понадобится для оптимизации процесса. Получить возможность варьировать объём задействованных ресурсов в Arena не очень просто. Для этого в таблице ресурсов надо указать в графе Type – Based on Schedule (рис. 3.31).

Рис. 3.31. Заполнение таблицы ресурсов

Рис. 3.32. Заполнение диалогового окна Schedule

Расписание работы парикмахеров надо заполнить при помощи диалогового окна, как это изображено на рис. 3.32. Чтобы следить за прибылью не обращаясь к отчётам, выведем её значение в свободной области окна модели. Для этого в строке команд надо выбрать пиктограмму , заполнить диалоговое окно (рис. 3.33) и обозначить область вывода значений переменной так, как мы делали это для отображения часов. Поэкспериментировав с этой моделью, вы можете убедиться, что чем больше работников в парикмахерской, тем меньше очередь и меньше прибыль.

Экспериментируя с моделью, можно заметить, что после окончания счёта в системе опять остаются объекты. Это связано с тем, что случай, когда количество доступных ресурсов определяется на основе расписания, отличается от случая с фикс

Рис. 3.33. Диалоговое окно вывода значения переменной

ированным значением. При работе по расписанию возможны три варианта.

1. Моменты изменения количества доступных ресурсов отсчитываются согласно расписанию, но фактически уменьшение количества доступных ресурсов происходит после их высвобождения. Это означает, что работник обязан завершить начатую работу с клиентом, прежде чем он уйдёт на перерыв или закончит свой рабочий день. Таким образом, работник фактически имеет более короткий перерыв и более длительный рабочий день, чем это предписано расписанием.

2. Время завершения работы отсчитывается не согласно расписанию, а после окончания обслуживания клиента. В этом случае работник имеет перерыв определенной расписанием длительности, но начинается и заканчивается он не в установленное время.

3) Сразу с наступлением установленного времени работник прекращает обслуживание клиента и возобновляет его также в установленное время.

Во всех трёх случаях клиенты, ожидающие в очереди, остаются не обслуженными. Такая ситуация не соответствует реальному состоянию дел, по крайней мере, в конце рабочего дня. Чтобы её исправить, необходимо принимать дополнительные меры, на чём мы пока не будем останавливаться. Отметим, что выбор одного из указанных выше трёх вариантов определяется установкой параметра Schedule Rule таблицы ресурсов, принимающего значения Ignore, Wait и Preempt соответственно первому, второму и третьему случаям. По умолчанию в системе устанавливается значение Wait.

Рассмотрим теперь методы ограничения времени работы парикмахерской. Будем считать, что после десяти часов припоздавшие клиенты продолжают прибывать со средней скоростью три человека в час но, увидев, что парикмахерская закрыта, уходят. Для этого сделаем сначала соответствующие установки в блоке Arrival.

Потом модифицируем модель BarberShop1 следующим образом. Введём ещё одну цепочку, состоящую из блоков Create, Assign 3 и Dispose 2 (рис. 3.34). В блоке Create будет вырабатываться единственный сигнал окончания работы (Marker).

Рис. 3.34. Изменения в модели парикмахерской

На рис. 3.35 показан образец заполнения параметров блока Create. В блоке Assign 3 происходит присвоение единичного значения переменной EndofWork (рис. 3.36). В первой цепочке после блока Arrival введём блок Decide 2, в котором будем сравнивать значение EndofWork с единицей. Если EndofWork<1, то клиент запускается в парикмахерскую (рис. 3.37). Назовём эту модель BarberShop3.

Рис. 3.35. Параметры блока Create

Рис. 3.36. Установки блока Assign 3

Рис. 3.37. Установки блока Decide 2

П

Рис. 3.38. Установка параметров вывода значений переменной

роверить правильность работы модели можно следующим способом. Установим на вкладке Replication Parameters время моделирования 15 часов, а на вкладке Run Speed (Скорость счёта) в окне Animation Speed Factor (Time Units Per Frame) (Скорость анимации − это количество единичных интервалов времени между кадрами) − 0.01. Это позволит замедлить процессы в системе и отслеживать движение клиентов. Далее сделаем щелчок левой клавишей мыши на пиктограмме в строке команд (если команда неактивна, то надо активизировать её щелчком левой клавиши мыши в окне модели), это приведёт к появлению диалогового окна, которое мы заполним так, как показано на рис. 3.38. Развернув список параметров Expression, выберем из него EndofWork. В поле Format можно выбрать формат представления переменной. Остальные поля нас пока не интересуют. После закрытия диалогового окна стрелка курсора преобразуется в визир, используя который нарисуем небольшой прямоугольник в свободной области окна модели, затем одним щелчком левой клавишей мыши закрепим левый верхний угол и двойным − правый нижний угол. В результате появится окно, в котором может выводиться текущее значение выбранной переменной. Двойной щелчок левой клавишей мыши на этой области позволяет редактировать параметры вывода. Запустив программу на выполнение, мы можем наблюдать, что при начальном значении переменой EndofWork, равном нулю, происходит обслуживание клиентов, а при значении, равным единице, клиенты уже не обслуживаются. Конечно, в этом можно было бы убедиться и более простым способом – просмотрев отчёт, но нам было важно познакомиться с новым приёмом отладки модели.

Рассмотрим ещё один метод ограничения времени работы. Воспользуемся системной переменной TNOW, которая отображает текущее время. В блоке Decide 2 в поле if выберем параметр Expression, а в поле Value запишем TNOW<10 (рис. 3.39). В окне отображения переменной установим вывод значения TNOW. Дополнительная цепочка блоков модели теперь не используется. Запустив программу на выполнение, можно обнаружить, что получился результат аналогичный предыдущему: до десяти часов клиенты обслуживаются, а после – нет. Таким образом, можно заключить, что одинаковый результат можно получить, решая задачу разными способами. Отметим ещё, что при этом в отчётах будут получаться разные данные. Поэтому, для их корректной интерпретации и использования, надо хорошо представлять себе, как эти данные получаются.

Рис. 3.39. Установки блока Decide 2

Увеличим далее количество парикмахеров. Для этого, активировав модуль Resource в колонке Capacity (Количество, ёмкость) и в ряду Barber, установим значение, например 2. Запустив модель на счёт, увидим, что работа в парикмахерской пошла быстрее, очереди стали меньше. В отчёте можно также обнаружить соответствующие изменения данных. Вместе с тем, можно заметить, что объём отчёта увеличился за счёт включения в него гистограмм, позволяющих провести сравнение характеристик двух входящих в систему объектов – клиентов и метки времени Marker. Так как эти объекты разнородные, то ничего ценного из такого сравнения извлечь нельзя. Поэтому, чтобы зря не загромождать отчёт, из него лучше исключить данные о метках времени. Для этого надо развернув таблицу модуля Entity, снять отметку в столбце Report Statistics напротив объекта Marker.

На следующем этапе введём некоторые индивидуальные характеристики работы парикмахеров, а именно: предоставим каждому парикмахеру индивидуальное расписание с перерывом на обед в течение часа и продолжительностью рабочего дня восемь часов (без учёта перерыва). Предположим, что парикмахеров двое. Преобразуем сначала параметры блока Hair Cutting следующим образом. В окне Resources в поле Type установим значение Set (Группа), в поле Set Name (Название группы) – Barbers (Па­рикмахеры), в поле Quantity (Количество) – 2, в поле Selection Rule (Пра­

Рис. 3.40. Установка параметров в окне Resources

вило, по которому происходит выбор парикмахера) выберем Cyclical (циклический) (рис. 3.40). Раскро­­ем содержимое модуля Set из окна проекта и нажмём на кнопку 0 rows, появившуюся в окне таблиц. Появится окно Members (Члены). В нём надо произвести двойной щелчок на надписи Double-click hear to add a new row (Двойной щелчок здесь, чтобы добавить но­вый ряд). В графе Resource Name наберём название ресурса – Barber1. Создадим ещё одну единицу ресурса – Barber2 (рис. 3.41) и закроем окно нажатием на крестик в его правом верхнем углу. Посмотрев содер­жимое модуля Resource, найдём там установленные нами новые ресурсы. У каждого из них в поле Type заменим параметр Fixed Capacity (Фиксиро­ванное число) на Based on Schedule (На основе расписания), а в поле Schedule Name введём название расписания (рис. 3.42). Оставшуюся лишней строчку, соответствующую ресурсу Barber, лучше удалить.

Рис. 3.41. Создание новых единиц ресурса

Рис. 3.42. Установка параметров используемых ресурсов

Теперь можно составить расписание работы для каждого парикмахера так же, как мы делали это для описания прибытия клиентов. Логично составить расписания так, чтобы они вместе покрывали весь десятичасовой промежуток работы парикмахерской и чтобы обеденные перерывы парикмахеров не совпадали. Пример такого расписания приведён в табл. 3.2.

Таблица 3.2

Расписание работы парикмахеров

Ресурс

Часы работы

1

2

3

4

5

6

7

8

9

10

Barber1

Barber2

Есть ещё один момент, на который надо обратить внимание при со­ставлении расписания. Как уже отмечалось, при наступлении обеденного перерыва или конца рабочего дня возможны следующие варианты действий работника: 1) прекратить работу точно в срок, оставив клиента не обслуженным до конца; 2) закончить обслуживание очередного клиента, прежде чем прекратить работу, при этом время работы увеличивается за счёт уменьшения перерыва; 3) не начинать обслуживание очередного клиента, если работник не успеет обслужить его до окончания рабочего времени. Этим трём случаям соответствуют три значения параметра Schedule Rule в таблице Resource – Wait (Ждать), Ignore (Игнорировать) и Preempt (Сделать заранее). Мы можем выбрать Ignore или Preempt, так как только в этих случаях мы избежим ситуации, когда клиенты будут обслуживаться не полностью. В нашей модели мы установим параметр Ignore. Это значит, что изменение мощности (Capacity) ресурса происходит не сразу, а по окончании обслуживания очередного клиента. Отметим, что возможна ещё одна проблема. Если рабочее время парикмахера закончилось, а к нему ещё есть очередь, то возникает дилемма: работать дальше или нет. Можно было бы продлить время работы парикмахера, но тогда тот, кто работает последним, оказывается в худших условиях по сравнению со вторым работником. Мы не будем пока углубляться в исследование этой проблемы.

Запустив программу на выполнение и получив отчёт, можно увидеть в нём, что на второго парикмахера приходится значительно меньше нагрузки, чем на первого. Исправить положение можно, сместив время обеденного перерыва. Предлагается это проделать самостоятельно в качестве упражнения.

Рассмотрим, как будет работать система, если задать использование ресурсов иным способом (рис.3.43). Проведя вычисления и посмотрев отчёт, мы можем заметить, что общее число захваченных ресурсов превышает число обслуженных клиентов. Дело в том, что в данном случае требуется сразу два парикмахера для обслуживания одного клиента. Таким образом, данный способ назначения ресурсов в рассматриваемой ситуации будет ошибочным.

Рис. 3.43. Иной способ использования ресурсов

Возможен ещё вариант, когда ресурс назначается на обслуживание не как элемент группы, а индивидуально, но его доступное количество (Capacity) устанавливается больше единицы. Это также соответствовало бы случаю работы нескольких парикмахеров, но при этом мы не смогли бы для каждого из них назначить индивидуальное расписание. Такой метод лучше использовать тогда, когда имеется несколько совершенно одинаковых ресурсов для обслуживания.

Познакомимся с ещё одним простым средством отладки моделей и представления результатов – построением графиков функций. Чтобы создать график функции, необходимо проделать последовательность операций, аналогичную той, которой мы воспользовались при выводе значений переменной. Надо сделать щелчок левой клавишей мыши на пиктограмме в строке команд и заполнить появившееся диалоговое окно Plot. Чтобы ввести значение функции в поле Expressions, нажимаем клавишу Add. Появляется окно Plot Expression. В поле Expression можно выбрать переменную из списка или ввести другую. Посмотрим, например, как меняется число клиентов в очереди. Для этого надо ввести название системной переменной NQ (Число объектов в очереди) и указать, какая очередь нас интересует. Правильный вид выражения выглядит так: NQ(HairCutting.Queue). В полях Minimum и Maximum зададим минимальное и максимальное значения 0 и 10, откладываемые по оси Y. Поле # History Points означает число выводимых точек. Можно также выбрать цвет и вид линии, соединяющей точки. Заполненное окно Plot Expression изображено на рис. 3.44. В окне Plot установим параметр Time Range (Диапазон времени) – 15 (единиц измерения) и сделаем отметку в поле X-Labels. Остальные параметры – без изменения.

П

Рис. 3.44. Установка параметров графика

осле закрытия диалогового окна надо пометить область вывода графика так же, как мы помечали область вывода переменной. Аналогичным образом можно построить гистограмму распределения. На рис. 3.45 представлены блок-схема модели, график и гистограмма функции NQ(HairCutting.Queue). График показывает, что очередь возникает преимущественно в периоды, когда работает один парикмахер и когда поток клиентов велик. По окончании работы в очереди никого не остаётся. Гистограмма показывает вероятность образования очередей различной длины. Сплошная линия на гистограмме обозначает кумулятивную вероятность. Как и следовало ожидать, вероятность образования длиной очереди меньше, чем короткой.

Рис. 3.45. Блок-схема модели и график функции NQ(HairCutting.Queue)

Конечным критерием при принятии управленческих решений обычно являются экономические показатели проекта. Рассмотрим на примере работы парикмахерской, как можно определить оптимальные параметры её работы. Типичный вопрос, который возникает: сколько парикмахеров должно работать в парикмахерской? Очевидно, что на результат будут оказывать влияние два основных фактора. 1) Если будет слишком много работников, то они будут простаивать из-за отсутствия клиентов. Величиной, характеризующей степень занятости работников, является так называемый коэффициент утилизации ресурса kу. Его значение равно отношению времени To, в течение которого работник обслуживает клиента, ко всему его рабочему времени: Тр: kу=Tо/Tр. Таким образом, мы должны стремиться к тому, чтобы коэффициент утилизации ресурса был максимален. 2) С другой стороны, все работники будут заняты в том случае, если к ним постоянно будет очередь. При этом клиенты будут недовольны. Часть из них уйдёт искать другую парикмахерскую. Это нежелательный результат, которого нужно постараться избежать. Чтобы учесть этот факт, в модель нужно ввести численную характеристику степени удовлетворённости клиентов. Будем считать, что клиент будет доволен, если время, проведённое им в парикмахерской, меньше 25 минут, и недоволен – в обратном случае. Введём величину, равную доле довольных клиентов: kд=Nд/N, где Nд − число довольных клиентов и N – полное число клиентов. Положим, что kд должно быть больше 0.9 или в процентном выражении 90 %.

Модифицируем модель, представленную на рис. 3.45 для учёта доли довольных клиентов. Новая переменная NSC будет обозначать количество довольных клиентов, а NCustomer − полное число обслуженных клиентов. Через KS обозначим долю удовлетворенных клиентов. Иногда название переменной может совпасть с именем, зарезервированным в системе, тогда это название надо поменять. Например, если бы мы обозначили число парикмахеров NR, то система выдала бы сообщение об ошибке. Такая же реакция была бы на переменную NC. Обратим внимание на то, что значение переменной NRes надо устанавливать отдельно в модуле Variable до начала моделирования.

Расчет величины kд является не очень простой задачей. Организуем для этого отдельную субмодель. В меню Object выберем команду Add Submodel (Добавить субмодель). После этого курсор преобразуется в визир. Наведя его на свободную область окна модели и сделав щелчок левой клавишей мыши, получим блок Submodel 1. Чтобы открыть субмодель, нужно сделать щелчок на изображающем её блоке два раза левой клавишей мыши. В отличие от окна модели в окне субмодели имеются точки входа и выхода в левой и правой частях окна соответственно. Эти точки должны быть соединены с блоками внутри и снаружи области субмодели. Чтобы выйти из окна субмодели, надо нажать правую клавишу мыши и выполнить команду: Close Submodel в появившемся меню. Другой способ перехода между окнами модели и субмодели заключается в развёртывании вкладки Navigate в окне проекта и выборе соответствующего уровня модели.

На рис. 3.46 показано окно субмодели с блок-схемой для расчета kд. В блоке Time Count (счёт времени) описана переменная WaitTime, в которую заносится время, проводимое клиентом в парикмахерской. Вычисляется это время по формуле

WaitTime=TNOW-Entity.CreateTime. (3.2)

Рис. 3.46. Окно субмодели

В этом выражении, кроме уже знакомой нам системной переменной TNOW, используется другая системная переменная Entity.CreateTime, фиксирующая время входа объекта в систему. В блоке TimeCount подсчитывается также полное число клиентов NCustomer по формуле:

NCustomer=NCustomer+1. (3.3)

Образец заполнения диалоговых окон приведён на рис. 3.47. Далее, в блоке Decide 3 определяется, доволен клиент или нет (рис. 3.48). В блоке Assign 4 вводится переменная NSC в которую будем заносить число довольных клиентов согласно формуле:

NSC=NSC+1. (3.4)

Рис. 3.47. Описание переменных WaitTime и NCustomer в блоке Time Count

Рис. 3.48. Параметры блока Decide 3

В блоке Assign 3 модели определим переменную KS, которой присвоим значение доли довольных клиентов (рис. 3.49) согласно формуле:

KS=NSC/NCustomer (3.5)

О

Рис. 3.49. Параметры блока Assign 3

братите внимание, что начальные значения всех переменных по умолчанию устанавливаются равными нулю. Проведём сборку блок-схемы модели как показано на рис. 3.50. Блок Submodel 1 поставим после блока HairCutting. После блока Assign 3 добавим два блока Record 1 и Record 2 для записи результатов (иначе они не появятся в отчёте). В этих блоках сделаем установки параметров таким образом, как показано на рис. 3.51. Назовём получившуюся модель Barber­Shop4. Прежде чем делать расчет внесём некоторые изменения входных параметров.

1. Увеличим поток клиентов в два раза по сравнению с исходными данными, представленными в табл. 3.1.

2. Упростим расписание работы парикмахеров. Будем считать, что их рабочий день составляет 10 часов без перерыва и все парикмахеры работают одинаково. Тогда в блоке HairCutting надо задать Resource в качестве вида ресурса. Назовём этот ресурс Barbers, и в таблице ресурсов в ячейке Type установим параметр Based on Schedule. В графе Schedule Name запишем название расписания – BarbersSchedule, в графе Schedule Rule установим Ignore. Заполним таблицу Schedule через диалог так, как показано на рис. 3.32.

3. Удалим ставшие лишними строки в таблицах Set, Resource и Schedule.

Рис. 3.50. Блок-схема модели работы парикмахерской

Рис. 3.51. Установка параметров блоков Record 1 и Record 2

4. В блоке Create установим время прихода сигнала – 14 часов для того, чтобы к этому времени заведомо завершилось обслуживание клиентов.

5. Ограничивать время работы парикмахерской будем с помощью системной переменной TNOW в блоке Decide 2.

6. Число репликаций установим, равным десяти, а время одной репликации – 15 часов.

7. Моделирование начнём для случая двух парикмахеров. Установим начальное значение переменной NRes = 2.

Чтобы сделать результаты моделирования более наглядными, рекомендуется вывести график функции NQ(HairCutting.Queue) для просмотра в окне модели. Запустим программу на счёт. Обратите внимание, что во время счёта в левой части экрана разворачивается окно Navigate, в котором можно выбрать режим просмотра работы модели или субмодели. После завершения моделирования на последней странице отчёта мы можем увидеть, что среднее значение прибыли за один день работы составляет, скажем, 9 838 рублей, а доля довольных клиентов – 27 %, это слишком мало. Следовательно, необходимо увеличить количество парикмахеров.

Установим NRes = 3, проведём моделирование и посмотрим отчёт. Теперь средняя дневная прибыль − 9 038 рублей – значительно ниже, чем в первый раз. Средняя доля довольных клиентов – 86 % – выше, чем в первый раз, но недостаточно велика. Проведём моделирование с NRes = 4. Получим среднюю прибыль 8 238 рублей в день. Доля удовлетворённых клиентов − 99.9 %. Очевидно, что при дальнейшем увеличении количества парикмахеров доход станет отрицательным. Поэтому можно остановиться на достигнутых результатах. Итак, модель рассчитана. Какой вариант лучше реализовать на практике − судите сами.