Тексты пользовательских PLUS-процедур:
EXPERIMENT Go(Parl,Par2) BEGIN
TEMPORARY CurYield,ShowString,CommandString;
M_HIRED=Parl;
N_WRK=Par2;
CurYield=GetResult();
ShowString = PolyCatenate(" Losses ",String(CurYield),". ");
ShowString =PolyCatenate(ShowString," Hired machines 1,String(M_HIRED),".");
ShowString = PolyCatenate(ShowString," Repairers ",String(N_WRK), ".");
CommandString = PolyCatenate("SHOW.......ShowString,"""", "");
DoCommand(CommandString);
END;
PROCEDURE GetResultO BEGIN
TEMPORARY Sum, CurYield, Ind_i;
Ind_i=l;
Sum=0;
WHILE (Ind_i<10) DO BEGIN
CurYield=DoTheRun(Ind_i);
Sum=Sum+CurYield;
Ind_i «Ind_i+1;
END;
RETURN (Sum/ (Ind_i -1));
END;
PROCEDURE DoTheRun(Run_Number) BEGIN
DoCommand("CLEAR OFF");
TEMPORARY CommandString;
CommandString = Catenate{"RMULT ",Run_Number#3);
DoCommand(CommandString);
CommandString > Catenate("REP STORAGE ",String(N_WRK));
DoCommand(CommandString);
DoCommand("START Iм);
RETURN ((40-SA$MANUF)#140+4.75#N_WRK+2.5#M_HIRED);
END;
EXPERIMENT Seek_Opt() BEGIN
TEMPORARY ShowString,CommandString;
TEMPORARY Prevl,Curl,Flagl;
TEMPORARY Prev2,Cur2,Flag2,Prev_N_WRK; M_HIRED=0-l;
Prevl=100000;
Flagl=l;
Prev_N_WRK=0;
WHILE (Flagl 'NE' 0) DO BEGIN M_HIRED=M_HIRED+1;
N_WRK=1-1;
Prev2=100000;
Flag2=l;
WHILE (Flag2 'NE' 0) DO BEGIN
N_WRK=N_WRK+1;
Cur2=GetResult();
IF (Cur2>Prev2) THEN BEGIN
Flag2=0;
Show_l (Prev2);
END;
ELSE Prev2=Cur2;
END;
Curl=Prev2;
IF (Curl>Prevl) THEN BEGIN
/*show results*/
ShowString = PolyCatenate(" Optimum. Losses ",String(Prevl),". 11);
ShowString = PolyCatenate(ShowString," Hired machines ",String(M_HIRED-l), 11.");
ShowString = PolyCatenate(ShowString," Repairers ",String(Prev_N_WRK), ". ");
CommandString = PolyCatenate("SHOW......,ShowString, '.....", "");
DoCommand(CommandString);
Flagl=0;
END;
ELSE BEGIN
Prevl=Cur1;
Prev_N_WRK=N_WRK-l;
END;
END;
END;
PROCEDURE Show_l(Losses) BEGIN
TEMPORARY ShowString,CommandString;
ShowString = PolyCatenate(" Cur. losses ",String(Losses),". ");
ShowString =PolyCatenate(ShowString," Cur. hired machines 11, String (M_HIRED), ". ");
ShowString = PolyCatenate(ShowString," Cur. repairers ",String(N_WRK-1),".");
CommandString-= PolyCatenate("SHOW """,ShowString,........, "");
DoCommand(CommandString);
END;
Оптимизировать в данном случае нужно средние затраты на производство за час, которые вычисляются следующим образом:
(40-SA$MANUF)#140+4.75#N_WRK+2.5#M_HIRED
Среднее число работающих станков за все время моделирования, определяет СЧА SA$MANUF. Начальное количество ремонтников в модели может не задаваться. Оно нужно только для автономного запуска модели без подключенного эксперимента.
Внешний цикл эксперимента Seek_Opt() организует изменение количества арендуемых станков. Внутренний цикл последовательно изменяет количество работников (чтобы найти минимум функции затрат, становящейся двумерной). Переменные Flagl, Flag2 управляют выходом из циклов. Переменные Prevl, Curl, Flagl соответствуют внешнему циклу; Prev2, Cur2, Flag2 - внутреннему. Переменная Prev_N_WRK хранит значение количества рабочих на предыдущем шаге внешнего цикла (при меньшем фиксированном значении количества арендуемых станков), соответствующее наименьшему значению функции затрат. Процедура Show_l предназначена для отображения промежуточных наименьших значений функции затрат и при каких значениях параметров они достигаются.
Для данной модели выполним два пользовательских эксперимента. Первый (Go) позволяет определить затраты на производство при конкретных значениях числа арендуемых станков и ремонтников, которые задаются как параметры в процедуре. Как и в предыдущем примере, средние затраты рассчитываются по 10 прогонам модели. Для выполнения этого эксперимента необходимо оттранслировать модель с подключенными процедурами, выполнить пункт меню Command/CONDUCT и в диалоговом окне 'Conduct Experiment' Command вызвать процедуру GO






