Модель данной задачи:
HARDWARE_COUNT EQU 6;Количество типов комплектующих
STORE_INFO MATRIX,6,3;Матрица, содержащая входные данные по типам комплектующих
;Каждая строка - отдельный тип комплектующих
;Первый столбец - количество комплектующих
;Второй столбец - брак, записанный в долях от единицы
;Третий столбец - количество комплектующих данного типа для одного ПК
INITIAL MX$STORE_INFO(1,1),520
INITIAL MX$STORE_INFO(1,2),0.01
INITIAL MX$STORE_INFO(1,3),1
INITIAL MX$STORE_INFO(2,1),520
INITIAL MX$STORE_INFO(2,2),0.01
INITIAL MX$STORE_INFO(2,3),1
INITIAL MX$STORE_INFO(3,1),510
INITIAL MX$STORE_INFO(3,2),0.001
INITIAL MX$STORE_INFO(3,3),1
INITIAL MX$STORE_INFO(4,1),1100
INITIAL MX$STORE_INFO(4,2),0.02
INITIAL MX$STORE_INFO(4,3),2
INITIAL MX$STORE_INFO(5,1),550
INITIAL MX$STORE_INFO(5,2),0.02
INITIAL MX$STORE_INFO(5,3),1
INITIAL MX$STORE_INFO(6,1),520
INITIAL MX$STORE_INFO(6,2),0.01
INITIAL MX$STORE_INFO(6,3),1
ASSEMBLERS STORAGE 4;Количество сборщиков
TECHNICIANS STORAGE 5;Количество техников
TEST_CHAMBERS STORAGE 50;Количество мест в термокамере
PACKERS STORAGE 2;Количество комплектовщиков
INITIAL X$X_0,500;Количество ПК
INITIAL X$X_5,30;Время сборки
INITIAL X$X_6,15;Время подготовки ПК и установки в термокамеру
INITIAL X$X_7,1440;Время проведения стрессового тестирования
INITIAL X$X_8,15;Время определения бракованной детали и ее замена
INITIAL X$X_9,5;Время снятия ПК из термокамеры
INITIAL X$X_10,10;Время упаковки ПК
GENERATE,,,X$X_0;Генерация всех транзактов (ПК)
;Сборка ПК
QUEUE ASSEMBLERS_QUEUE
ENTER ASSEMBLERS
DEPART ASSEMBLERS_QUEUE
;Записываем в параметры транзакта 1-6 флаг, показывающий является ли соответствующий этому номеру тип комплектующего бракованный
ASSIGN I1,HARDWARE_COUNT;Счетчик для блока LOOP
SET_PARAM_MARK TEST G MX$STORE_INFO(P$I1,1),0,HARDWARE_RUN_OUT_MARK;Проверяем, есть ли еще комплектующие этого типа на складе
MSAVEVALUE STORE_INFO-,P$I1,1,MX$STORE_INFO(P$I1,3);Уменьшаем количество комплектующих данного типа на складе
ASSIGN P$I1,(RN10/1000'LE'MX$STORE_INFO(P$I1,2));Записываем в параметр с номером данного комплектующего, будет ли он бракованным с заданной вероятностью (RN10 возврщает от 1 до 999)
LOOP I1,SET_PARAM_MARK;Повторяем с уменьшением счетчика i1
ADVANCE X$X_5,(X$X_5#0.1);Производим сборку ПК
LEAVE ASSEMBLERS
;Тестирование ПК
PUT_IN_CHAMBER_MARK QUEUE TECHNICIANS_QUEUE
ENTER TEST_CHAMBERS
ENTER TECHNICIANS
DEPART TECHNICIANS_QUEUE
ADVANCE X$X_6,(X$X_6#0.1);Установка в термокамеру
LEAVE TECHNICIANS
TEST E (P1+P2+P3+P4+P5+P6),0,TEST_FAULTED;Если нет бракованных комплектующих
ADVANCE X$X_7,(X$X_7#0.02);Производим тестирование сутки
TRANSFER,PUT_OUT_CHAMBER_MASK
TEST_FAULTED ADVANCE (UNIFORM(RN1,0,X$X_7));Иначе тестирование остановится в произвольное время
PUT_OUT_CHAMBER_MASK ENTER TECHNICIANS
ADVANCE X$X_9,(X$X_9#0.1);Снятие с термокамеры
LEAVE TECHNICIANS
LEAVE TEST_CHAMBERS
TEST E (P1+P2+P3+P4+P5+P6),0,REPEAR_MARK;Если есть бракованные комплектующие,то отправляем на ремонт
;Упаковка ПК
QUEUE PACKERS_QUEUE
ENTER PACKERS
DEPART PACKERS_QUEUE
ADVANCE X$X_10,(X$X_10#0.1)
LEAVE PACKERS
TERMINATE 1
;Ремонт ПК
REPEAR_MARK ENTER TECHNICIANS
ADVANCE X$X_8,(X$X_8#0.5);Производим ремонт ПК
;Обновляем данные по комплектующим
ASSIGN I1,HARDWARE_COUNT;счетчик для блока LOOP
;Используя косвенную адресацию, находим параметр транзакта с текущим номером счетчика и проверяем этот ли тип комплектующих бракованный
REPEAR_TRY_SET_PARAM_MARK TEST E P*$I1,1,REPEAR_NEXT_PARAM_MARK
TEST G MX$STORE_INFO(P$I1,1),0,HARDWARE_RUN_OUT_MARK;Проверяем есть ли еще комплектующие этого типа на складе
MSAVEVALUE STORE_INFO-,P$I1,1,MX$STORE_INFO(P$I1,3);Уменьшаем количество комплектующих данного типа на складе
SAVEVALUE P$I1+,MX$STORE_INFO(P$I1,3);Суммируем бракованные детали каждого типа
ASSIGN P$I1,(RN10/1000'LE'MX$STORE_INFO(P$I1,2));Записываем в параметр с номером данного комплектующего, будет ли он бракованным с заданной вероятностью (RN10 возврщает от 1 до 999)
REPEAR_NEXT_PARAM_MARK LOOP I1,REPEAR_TRY_SET_PARAM_MARK;Повторяем с уменьшением счетчика i1
LEAVE TECHNICIANS
TRANSFER,PUT_IN_CHAMBER_MARK;Отправляем отремонтированные ПК в термокамеру
HARDWARE_RUN_OUT_MARK SAVEVALUE HARDWARE_RUN_OUT,1;Указываем, что на складе закончились комплектующие какого-то типа
TERMINATE 10000;останавливаем моделирование
;цикл, блокирующий работу сотрудников, имитирую ночь, обед и выходные
GENERATE 0,,,1,2;Генерируем единственный транзакт с повышенным приоритетом
ASSIGN REST_TIME,480;Время первого отдыха, отсчитывая от 00:00 (8 часов)
ASSIGN WORK_TIME,240;Время работы до перерыва (4 часа)
ASSIGN DAY_PART,1;Будет показывать часть дня (до обеда/после обеда)
ASSIGN DAY_COUNT,1;Будет отсчитывать дни недели
;блокируем работу сотрудников
REST_MARK SUNAVAIL ASSEMBLERS
SUNAVAIL TECHNICIANS
SUNAVAIL PACKERS
ADVANCE P$REST_TIME;Имитируем отдых
;разблокируем сотрудников
SAVAIL ASSEMBLERS
SAVAIL TECHNICIANS
SAVAIL PACKERS
ADVANCE P$WORK_TIME;Время работы сотрудников
TEST L P$DAY_PART,2,NIGHT_MARK;Если время до обеда
ASSIGN REST_TIME,60;Устанавливаем обеденное время (1 час)
ASSIGN DAY_PART+,1;Изменяем часть дня
TRANSFER,REST_MARK;Повторяем блокировку
NIGHT_MARK TEST L P$DAY_COUNT,5,HOLYDAY_MARK;Если время после обеда
ASSIGN REST_TIME,900;Устанавливаем время отдыха до следующего дня (15 часов)
ASSIGN DAY_PART,1;Устанавливаем время до обеда
ASSIGN DAY_COUNT+,1;Увеличиваем день недели
TRANSFER,REST_MARK;Повторяем блокировку
;если начинаются выходные
HOLYDAY_MARK ASSIGN REST_TIME,3780;Устанавливаем время отдыха до следующего дня (63 часа)
ASSIGN DAY_PART,1;Устанавливаем время до обеда
ASSIGN DAY_COUNT,1;Устанавливаем день недели в 1
TRANSFER,REST_MARK;Повторяем блокировку
START 500