Имитационное моделирование экономических процессов
.pdfДиалоговая настройка модели
р-Параметры бизнес-процесса |
|
Готово |
|
Фирма: |АВТОИЗВОЗЧИК И КО |
|
||
|
|
||
|
|
|
Отмена |
Минуты |
Единица времени |
Рабочий день Период времени |
|
600.0 |
Время моделирования |
0.0 |
Окошко 11 |
1.0 |
Прибытие пассажиров |
|
Окошко 12 |
8.0 |
Интервал подхода такси |
|
Окошко 13 |
|
Окошко 4 |
|
Окошко 14 |
|
Окошко 5 |
|
Окошко 15 |
|
Окошко 6 |
|
Окошко 16 |
|
Окошко 7 |
|
Окошко 17 |
|
Окошко 8 |
|
Окошко 18 |
|
Окошко 9 |
|
Окошко 19 |
|
Окошко 10 |
|
Окошко 20 |
Рис. 4.11. Диалоговое окно для управления параметрами модели
В данном примере количество окошек избыточно, задействовано только 3 из 20 для отображения и управления тремя параметрами модели: 1) float winOl «Время моделирования»; 2) float win02 «При бытие пассажиров»; 3) float win03 «Интервал подхода таксго>. Заре зервировано одно окошко (с номером 11) для отображения парамет ра float winl 1, который в модели не используется.
Далее рассмотрим текст программы, которая выводит численные значения параметров модели и позволяет их корректировать. Обра щение к этой программе производится с помощью вызова Parametr из любого места (или любого узла) модели. Описание макета такой программы приведено ниже.
151
#include <Pilgrim.h> tinclude "UserHid.h" extern char commtext[]; extern char lefttext[]; extern float winOl; extern float win02; extern float win03; extern char rightext[]; extern float winll;
II- |
|
процесса |
|
|
II |
Диалог настройки параметров |
|
||
II- |
hdwnd, |
|
||
BOOL CALLBACK ParametrFunc(HWND |
|
|||
|
UINT message, |
|
||
|
WPARAM wParam, |
|
||
|
LPARAM |
1Param) |
|
|
{ |
|
|
|
|
switch(message) |
|
|
|
|
|
{ |
|
|
|
|
case WM_INITDIALOG: |
|
|
|
|
SetDlgltemText(hdwnd,DM_TITLE,commtext); |
|
||
|
SetDlgltemText(hdwnd,DM_T1, |
lefttext) |
|
|
|
sprintf(str,"%4.2f",win01); |
str |
) |
|
|
SetDlgltemText(hdwnd,DM_P1, |
|
||
|
sprintf(str,"%4.2f",win02); |
str |
) |
|
|
SetDlgltemText(hdwnd,DM_P2, |
|
||
|
sprintf(str,"%4.2f",win03) ; |
str |
) |
|
|
SetDlgltemText(hdwnd,DM_P3, |
|
||
|
SetDlgltemText(hdwnd,DM_T2, |
rightext) |
|
|
|
sprintf(str,"%4.2f",winll); |
|
) |
|
|
SetDlgltemText(hdwnd,DM_P11,,str |
|
||
|
return FALSE; |
|
|
|
|
case WM_COMMAND: |
|
|
|
|
switch(wParam) |
|
|
|
|
{ |
|
|
|
|
case IDOK: |
|
|
|
|
GetDlgltemText(hdwnd,DM_TITLE, commtext,80) |
|||
|
GetDlgltemText(hdwnd,DM_T1, |
lefttext,80) |
||
|
GetDlgltemText(hdwnd,DM_P1, |
str, |
80) |
|
|
sscanf(str,"%f",&win01); |
|
|
|
|
GetDlgltemText(hdwnd,DM_P2, |
str, |
80) |
|
|
sscanf(str,"%f",&win02); |
|
||
|
GetDlgltemText(hdwnd,DM_P3, |
str. |
!0) |
|
|
sscanf(str,"%f",&win03); |
|
rightext,80) |
|
|
GetDlgltemText(hdwnd,DM_T2, |
|||
|
GetDlgltemText(hdwnd,DM_P11, |
str, |
80) |
|
|
sscanf(str,"%f",&winll); |
|
EndDialog(hdwnd,TRUE) ; break;
152
case IDCANCEL: EndDialog(hdwnd,FALSE) ; break;
default: return FALSE;
}
break;
default: return FALSE;
}
return TRUE;
}
Начальные значения переменных winOl, win02, wm03, win11, a также заголовки и надписи задаются в головной части текста модели:
ttinclude <Pilgrim.h> |
|
/ / |
и |
Модель |
с |
диалогом |
|||
char |
coirantextTSl]="АВТОизвозчик |
Ко"; |
/ / |
|
Название |
||||
char |
l e f t t e x t [ 8 1 j |
="Минуты"; |
/ / |
|
Время |
в |
|
минутах |
|
float |
winOl |
= |
600.0; |
/ / |
|
Моделрфуем 10 час |
|||
float |
win02 |
= |
1.0; |
/ / |
|
Приход |
такси |
||
float |
win03 |
= |
8.0; |
/ / |
|
Приход |
пассажиров |
||
char |
rightext[81]="Рабочий день"; |
Резерв |
/ / |
|
Период |
||||
float |
winll=0.0; |
|
|
/ / |
|
|
(окно 11) |
||
forward |
|
|
|
|
|
|
|
|
{
Parametr; // Диалог настройки modbeg("Стоянка такси",8,
winOl,(long)time(NULL),none,l,none,4,2);
modend("Res_taxi.doc",1,12,page); return 0;
}.
После возможной корректировки файлов UserRes.rc и Parametr.cpp выполняется компиляция и сборка модели, для чего используется клавиша Build общего меню Developer Studio и режим Rebuild АН. В результате создается выполняемая модель ModelPro.exe. Запуск модели: Build -> Execute ModelPro.exe.
Проект модели с функциональным окном для конечного пользо вателя. Часто бьшает необходимо показать конечному пользователю информацию в понятном ему проблемно-ориентированном виде. Это могут быть изменяющиеся таблички, графики, перемещающиеся по экрану изображения (например, автомобили). Такой пользователь не будет изучать моделирующую систему. Поэтому для него средства ми Visual C++ создается специальная функциональная программа
153
funcwindow, которая помещается в динамически вызываемую биб лиотеку Windows (dll-библиотеку). Обращение к такой библиотеке производится после каждого события в модели. После первого со бытия она загружается в оперативную память. Типовые операторы Visual C++ , используемые при создании такого окна, приведены в приложении 2.
В качестве примера можно рассмотреть полезную программу - «часы моделирования». Изображение, появляющееся в правом верх нем углу такого окна, показано на рис. 4.12. Как только очередной интервал моделирования превзойдет 1% модельного времени, эта программа переформировьшает содержание функционального окна. В результате можно наблюдать эффект анимации.
Модель "Стоянка такси" Часы моделирования
Sat Sep 15 18:15:26 2001 Процент выполнения: 76
Рис. 4.12. Фунюшональное окно Часы моделирования
Программа функционального окна получает в качестве парамет ра область памяти strupt fwcb, в которой размещены все необходи мые оперативные данные на момент последнего события, которое произошло в модели. Адрес этой области памяти содержится в па раметре S, передаваемом в прогр^шу fimcwindow. Ее структура по казана ниже:
154
155
Рассмотренная область описана в системном h-файле Simulate.h. В соответствии с ее структурой ниже приведен текст программы, реализующей окно типа «часы моделирования». Следует отметить, что в данной программе значительное место занимают операторы, необходимые для автоматизации размещения текстов и изображений на заданном прямоугольнике. Если это окно сделать без такого сер виса, то программа будет значительно короче (и понятнее):
#include <Windows.h> iinclude <Simulate.h>
void funcwindow(struct fwcb*);
BOOL WINAPI DllEntryPoint(HINSTANCE hDLL, DWORD dwReason, LPWORD Reserved)
{
switch(dwReason)
{
case DLL PROCESS ATTACH:
{
break;
}
case DLL PROCESS DETACH:
{
break;
} }
return TRUE;
}
void funcwindow(struct fwcb *s)
{ |
|
// Метрики текста |
TEXTMETRIC tm; |
||
SIZE |
size; |
// Структура для метрик |
time_t |
ct; |
// Переменная для таймера |
char |
str[3000]; |
// Буфер для строки вывода |
char |
comwork[96];// Строка для измерений |
|
struct |
|
// длин текстов |
tm *newtime;// Адрес структуры таймера |
||
struct |
tcb *к; |
// Адрес узла модели |
double |
ар; |
// Текущий угол |
double |
hp; |
// Шаг угла |
float |
р; |
// Проценты |
int |
xL; |
//X левого верхнего угла |
int |
yL; |
// Y левого верхнего угла |
int |
wE; |
// Ширина эллипса |
int |
hE; |
// Высота эллипса |
int |
xLp; |
// Левый край индикатора |
int |
xRp; |
// Правый край индикатора |
int |
уНр; |
// Верхний край индикатора |
156
int |
yLp; |
// |
Нижний |
край индикатора |
int |
wX; |
// |
Текущие |
координаты X |
int |
wY; |
// |
Текущие |
координаты Y |
int |
xSl; |
// Рабочая |
координата |
|
int |
xS2; |
// Рабочая |
координата |
|
int |
yS; |
// Рабочая |
координата |
|
int |
iP; |
// Рабочая для процентов |
||
int |
i; |
// Рабочая |
переменная |
s->h01df= (HFONT) SelectObject (s->memdc, s-*hNewf) ;
// Шрифт ANSI
if (! SetWindowLong (s->hwnd, GWL_WNDPROC, s->mywndproc) )
MessageBox(s->hwnd, "", "He подключена программа MyWindowProcedure''",MB_OK) ;
hp=pi/100; p=s->timer/s->tmax*100; iP=p;
if{iP>100)
iP=100;
if (iP>s->percent I I s-»percent ==100 I I s->percent
&&! s-^stopO && ! s-*stopl && ! s-*stop2
&&! s->stop3))
{
MessageBeep(1);
ap=hp*p+0.0001;
if{ap>pi)
ap=pi; xRp=s-^maxX-2 ; уНр=2;
GetTextMetrics (s->memdc, Stm); //Метрики текста sprintf(corawork,"Процент выполнения: 100 " ) ; GetTextExtentPoint32 (s->memdc, comwork,
strlen(comwork),&size);
i^xRp-size.ex; xLp=i;
sprintf (comwork, "Модель \"%s\"", s->modname) ; GetTextExtentPoint32 (s->memdc, comwork,
i=xRp-size.cx; |
strlen(comwork),Ssize); |
||
|
\ |
|
|
if(i < xLp ) |
|
|
|
xLp=i; |
*// Получить новое |
время |
|
ct=time(NULL); |
|||
newtime=localtime(Set); |
|
время |
|
strcpy(str,asctime(newtime)); // Новое |
|||
str[strlen(str)-l]='\0'; |
// Удалить \r\n |
||
GetTextExtentPoint32 (s->memdc, str, |
|
||
i=xRp-size.cx-10; |
|
strlen(str),Ssize); |
|
if(i < xLp ) |
|
|
|
xLp=i; |
|
|
|
157
xLp |
-= 9; |
|
|
yLp |
= уНр + 3 + 12*(tm.tmHeight + |
|
|
wX=xLp+3; |
tm.tmExternalLeading) + 3; |
||
// Текущий X |
текста |
||
wY=yHp+3; |
// Текущий Y |
текста |
TextOut {s->memdc, wX, wY, comwork, strlen(comwork)); // Название модели
wY = wY + 9*(tm.tmHeight + tm.tmExternalLeading);
TextOut {s-»memdc, wX, wY, str, strlen (str) ); // Время
wY = wY + (tm.tmHeight + tm.tmExternalLeading); |
|
sprintf(str,"Процент выполнения: %3d |
", |
iP);
TextOut (s-»memdc,wX,wY, str, strlen (str) ) ;
wY = wY + |
(tm.tmHeight + tm.tmExternalLeading); |
||
if (iP == |
100) |
|
|
{ |
|
|
" ) ; |
sprintf(str,"Вьшолнена... |
|||
TextOut (s->memdc,wX,wY, str, strlen (str) ) ; |
|||
} |
|
|
|
else if (s->nd =- 0) |
|
||
{ |
|
|
" ) ; |
sprintf(str,"Моделирование |
|||
TextOut (s->memdc,wX,wY, str, strlen (str) ) ; |
|||
} |
|
// X и Y центра эллипса |
|
xL=(xLp+xRp)/2; |
|||
hE=6*(tm.tmHeight |
+ tm.tmExternalLeading); |
||
wE=hE; |
|
// Высота |
эллипса |
|
// Ширина |
эллипса |
|
xL-=xL-hE/2.0; |
/ / X левого верхнего угла |
yL=yHp+3+2*(tm.tmHeight+tm.tmExternalLeading); //Y левого верхнего угла
SelectObject (s->memdc, s-»hRedpen);
// Выбрать красное перо
SelectObject (s-*memdc, s-»hWhitebrush);
// Выбрать белую кисть Ellipse(s->memdc,xL,yL,xL+wE,yL+hE); // Эллипс xSl=xL+wE*(1-sin(ap))/2; xS2=xL+wE*(l+sin(ap))/2;
yS =yL+hE*(l+cos(ap))/2;
SelectObject (s->memdc, s->hCyanbrush) ;
// Бирюзовая кисть
Pie (s-»memdc,xL,yL,xL+wE,yL+hE,xSl,yS,xS2,yS); // Сектор
SelectObject (s-*memdc, s-»hBluepen);
// Выбрать синее перо MoveToEx (s->memdc, xL+wE/2-1, yL-s-+maxY/60, NULL); LineTo(s->memdc,xL+wE/2-l,yL+hE+s->maxY/60);
MoveToEx (s-*memdc, xL-s->maxX/80, yL+hE/2-1, NULL) ;
LineTo (s->memdc, xL+wE+s->maxX/80, yL+hE/2-1) ;
158
SelectObject (s-*memdc, s->hHollowbrush) ; // Прозрачная кисть
SelectObject {s->memdc,s->hGreenpen);
// Выбрать зеленое перо Rectangle (s-»memdc, xLp, vLp, xRp, уНр) ;
// Прямоугольник
s->percent=iP;
InvalidateRect (s->hwnd,NULL, 1) ;
}
return;
}
Модернизация моделей. Все элементы проекта автоматически сохраняются средствами Developer Studio. Для того чтобы прервать разработку, необходимо выполнить следующее:
•на всякий случай принудительно сохранить последний модифищ1рованный текст модели (если модификации были), выполнив действия File -> Close через главное меню Developer Studio или на жав значок «дискета» на панели инструментов;
•затем либо просто выйти из Developer Studio (если нет других проектов), либо в главном меню выполнить действия: File -> CloseWorkspace (если нужно перейти к другому проекту).
Модернизащ1я моделей возможна всегда. Чтобы выполнить мо дернизацию, через меню Developer Studio открывается существую щий проект: File -> OpenWorkspace.
Далее автоматически подключается проводник для поиска файла управления проектом с суффиксом mdf (например, ModelPro.mdf). Этот файл автоматически показывается в папке с проектом. После двойного щелчка по имени этого файла проект восстановится в том виде, в котором он был в последний раз (повторно его собирать не нужно). Можно сразу перейти к изменению любых текстов и состава модели.
Выполнение моделей. По умолчанию создается ехе-файл в пап ке Debug, вложенной в папку с проектом. Это и есть компьютерная модель. В ехе-файле есть все необходимое для отладки модели. Окончательный вариант отлаженной модели обычно берется из пап ки Release: он работает быстрее и меньше по объему.
В процессе отладки модель запускается из папки Debug одним из двух способов:
•нажатием комбинации клавиш Ctrl+F5;
•через главное меню Build -> Execute ModelPro.exe.
159
Файл с моделью можно переписать в любую другую папку и на любой другой компьютер. Он всегда будет работать.
Замечание. Если модель содержит функциональное окно для ко нечного пользователя, то соответствующий dll-файл должен быть помещен в одну из папок:
•в ту же папку, где находится ехе-файл ( этот способ универ сальный, самый простой и не зависим от типа операционной систе мы);
•в папку System, если модель должна выполняться в системе Windows 98;
•в папку System32, если модель должна выполняться в системе Windows NT (для этого необходимо получить режим администрато ра). В системе Windows 2000 необходимо вьтолнить аналогичные действия.
Вы в о д ы
1.Рассмотрены основные приемы программирования и отладки моделей. Программисту предоставляется возможность получать, задавать и использовать значения параметров транзактов, узлов и глобальных переменных моделирующей системы, а также непосред ственно обращаться к датчикам псевдослучайных чисел. Для отлад ки моделей используются итоговая таблица с результатами модели рования и динамически изменяющиеся отладочные таблицы.
2. Имитационная модель создается в среде Developer Studio с применением средств Visual C++. Приведены типовые технологиче ские последовательности действий, необходимые при создании, мо дернизации и вьшолнении моделей. Программист может создать ти повой проект, проект с диалоговым окном для управления парамет рами при запуске модели иди во время ее выполнения, а также про ект модели с функциональным окном для конечного пользователя.
Вопросы лАя самопроверки
1.Как осуществляется отсчет модельного времени?
2.В какой переменной находится значение модельного времени?
3.Какие параметры транзактов всегда доступны разработчику мо дели?
160