Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Имитационное моделирование экономических процессов

.pdf
Скачиваний:
242
Добавлен:
01.05.2014
Размер:
6.69 Mб
Скачать

Диалоговая настройка модели

р-Параметры бизнес-процесса

 

Готово

Фирма: |АВТОИЗВОЗЧИК И КО

 

 

 

 

 

 

Отмена

Минуты

Единица времени

Рабочий день Период времени

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

};
char modname[16]; char filename[256];
int stopO; int stopl; int stop2; int stop3;
int maxY; int percent;
// Бирюзовое перо // Модельный таймер
// Время моделирования // Число событий в модели
// Белое перо // Черное перо // Красное перо // Зеленое перо // Синее перо // Желтое перо
// Фиолетовое перо
HBRUSH hRedbrush; HBRUSH hGreenbrush; HBRUSH hBluebrush;
HFONT hOldf; HFONT hNewf;
LONG HWND HDC HDC
mywndproc hwnd; hdc; memdc;
{
void •pointer;
struct kcb *addr[pool];// Массив указателей узлов struct tcb *t; // Адрес продвигаемого транзакта struct ecb *e; // Адрес вновь образованного ecb struct ecb *w; // Адрес спланированного события int next; // Номер «текущего» узла int error; // Фатальная ошибка в модели int maxn; // Число узлов модели
int presise; // Знаков после десятичной точки int maxX; // Размеры экрана X
// Размеры экрана Y
// Процент выполнения модели // Признак выполнения модели // Признак приостановки // Признак трассировки
// Изменить масштаб времени // Название модели // Имя найденного файла
// Указатель произвольной области // Адрес оконной процедуры // Дескриптор окна
// DC устройства
//DC виртуального окна // Старый шрифт //.Новый шрифт
HBITMAP hbit; // Растр - виртуальное окно HBRUSH hbrush; // Рабочая кисть
HBRUSH hOldbrush; // Дескриптор прежней кисти HBRUSH hHollowbrush; // Прозрачная кисть
HBRUSH hWhitebrush; // Белая кисть HBRUSH hBlackbrush; // Черная кисть // Красная кисть // Зеленая кисть
// Синяя кисть HBRUSH hYellowbrush; // Желтая кисть HBRUSH hMagentabrush;// Фиолетовая кисть HBRUSH hCyanbrush; // Бирюзовая кисть
HPEN hOldpen; // Дескриптор прежнего пера HPEN hWhitepen;
HPEN hBlackpen;
HPEN hRedpen;
HPEN hGreenpen;
HPEN hBluepen;
HPEN hYellowpen;
HPEN hMagentapen; HPEN hCyanpen; double timer; float tmax; long nd;
struct fwcb // БЛОК УПРАВЛЕНИЯ ФУНКЦИОНАЛЬНЫМ ОКНОМ

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