МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА»
Кафедра автоматизованих систем управління
Лабораторна робота №2
з дисципліни “Моделювання систем”
на тему
«Імітаційне моделювання систем масового обслуговування»
Мета роботи: Ознайомлення з методом імітаційного моделювання та його застосування для дослідження систем масового обслуговування (СМО).
ТЕОРЕТИЧНІ ПОЛОЖЕННЯ
. Основні поняття систем масового обслуговування
Застосування цього підходу розгланемо на прикладі використання математичних схем систем масового обслуговування.
Для всіх цих моделей характерним є випадковий процес їх функціонування. Розглянемо одноканальну систему масового обслуговування (рис.2.1).
Рис. 2.1. Одноканальна система масового обслуговування.
де Yi-вихідний потік,
ui-час обслуговування заявки,
wi-час очікування обслуговування заявкою,
(i- кількість заявок, які поступають за одиницю часу,
ni- кількість заявок в системі,
Ki-кількість каналів обслуговування,
П-прилад.
ni=li+(i, де (і- коефіцієнт завантаження, li- кількість заявок в черзі.
Потік подій називається однорідним, якщо він характеризується тільки моментами наступлення цих подій, {tn} 0=t1<t2<...<tn і ніяк не характеризує самі події. Однорідний потік подій може також задаватися проміжками часу між послідовними подіями {(n}, (1=t1-t0, (2=t2-t1, ..., (n=tn-tn-1.
Потік неоднорідних подій - це послідовність, яка характеризується двома параметрами {tn,fn}, tn- моменти часу наступлення події, fn- набір ознак цієї події.
Потік подій називається потоком з обмеженою післядією, якщо сумісна функція густини інтервалів (i може бути представлена наступним чином:
f(z1,z2,...,zn)=f(z1)f(z2)...f(zn).
Потік подій називається ординарним, якщо lim[((t0,t)/t]=0 при t→0, де функція ((t0,t) - ймовірність появи двох і більше подій на проміжку часу t.
Нехай заданий цілочисельний вектор k=(k1,k2,...,kn), і вектор t=(t1,t2,...,tn). Визначимо pk(t0,t) як ймовірність появи k1 подій на проміжку часу від t0 до t1 , k2 подій на проміжку часу від t1 до t2 і т.д. Якщо ця функція не залежить від t0, а визначається тільки векторами t і k, то потік називається стаціонарним. Для стаціонарного потоку справедливим є співвідношення f(z2)=f(z3)=...=f(zn), де n>1.
,
де m-середнє значення проміжку часу між моментами наступлення подій.
f(z) - функція густини закону розподілу проміжків часу.
m=1/(, де ( - інтенсивність вхідного потоку.
Для стаціонарного потоку з обмеженою післядією має місце формула Пальма: - функція густини закону розподілу інтервалу τ1. Вона дозволяє знайти розподіл (1, якщо відомий розподіл для всіх інших інтервалів починаючи з другого. Для рівномірного закону розподілу (рис.2.2):
Рис. 2.2. Функція густини рівномірного закону розподілу.
Математичне сподівання:
,
Розподіл інтервалів часу (і:
M(τ1)=b/3 - математичне сподівання τ1.
Якщо ймовірність pk(t0,t) поступлення k заявок в інтервалі часу (t0,t0+t) не залежить від чередування подій до моменту t0, тобто, якщо умовна ймовірність pk(t0,t) , яка обчислена при будь-якому припущенні послідовності подій до моменту t0 дорівнює безумовній ймовірності тої ж події, то потік називається потоком без післядії.
Єдиним стаціонарним ординарним потоком без післядії є найпростіший потік або потік Пуасона, для якого функція розподілу кількості подій на проміжку часу t дорвнює:
pk(t0,t)=(((t)k / k!)*e-( t,
f(z)=(*e-( t,
f(z1)=(*e-( t.
Дані варіанту індивідуального завдання.
№ варіанту
Значення вхідних даних
Початкове значення генератора
X0
Діапазон проміжків часу між поступленнями заявок
хв.
Діапазон часу обслуговування заявок
хв.
7
93067
[1,16]
[1,11]
Роздрук отриманих даних.
Текст програми
Лістинг файлу SMOpr.cpp
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("SMOun.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
Лістинг файлу SMOun.cpp
#include <vcl.h>
#pragma hdrstop
#include "SMOun.h"
#include <stdlib.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "XPManifest"
#pragma link "XPManifest"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
float TimeFormat(int numb)
{
float res=0;
while(numb>60){res++;numb-=60;}
return res+=(float)numb/100;
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
StringGrid1->Cells[0][0]="Покупець";
StringGrid1->Cells[1][0]="Час після прибуття попереднього покупця, хв.";
StringGrid1->Cells[2][0]="Час обслугову- вання, хв.";
StringGrid1->Cells[3][0]="Біжучий час моделювання в момент прибуття покупця";
StringGrid1->Cells[4][0]="Початок обслугову- вання";
StringGrid1->Cells[5][0]="Кінець обслугову- вання";
StringGrid1->Cells[6][0]="Час перебування покупця біля прилавку";
StringGrid1->Cells[7][0]="Час простою продавця в очікуванні покупця";
StringGrid1->Cells[0][1]="N";
StringGrid1->Cells[1][1]="t1";
StringGrid1->Cells[2][1]="t2";
StringGrid1->Cells[3][1]="t3";
StringGrid1->Cells[4][1]="t4";
StringGrid1->Cells[5][1]="t5";
StringGrid1->Cells[6][1]="t6";
StringGrid1->Cells[7][1]="t7";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
int H;
AnsiString str;
PChar s;
Cardinal Flag;
StringGrid1->Canvas->FillRect(Rect);
str = StringGrid1->Cells[ACol][ARow];
s = str.c_str();
Flag = DT_CENTER;
Flag = Flag | DT_WORDBREAK;
Rect.Left+=3;
Rect.Right+=3;
H = DrawTextA(StringGrid1->Canvas->Handle,s,strlen(s),&Rect,Flag);
if (H > StringGrid1->RowHeights[ARow])
StringGrid1->RowHeights[ARow] = H;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
StringGrid1->RowCount=3;
if ((Edit2->Text!="")&&
(Edit3->Text!="")&&
(Edit4->Text!="")&&
(Edit5->Text!="")&&
(Edit9->Text!=""))
{
int smo[8][1000]={0}, k_ex=0/*кількість покупців*/, d_rec[2],
d_ser[2], temp, t_och=0, t_in=0,/*час входження заявки*/ t_pros=0;//час простою
d_rec[0]=StrToInt(Edit2->Text);
d_rec[1]=StrToInt(Edit3->Text);
if (d_rec[0]>d_rec[1])
{
temp=d_rec[0];
d_rec[0]=d_rec[1];
d_rec[1]=temp;
}
d_ser[0]=StrToInt(Edit4->Text);
d_ser[1]=StrToInt(Edit5->Text);
if (d_ser[0]>d_ser[1])
{
temp=d_ser[0];
d_ser[0]=d_ser[1];
d_ser[1]=temp;
}
k_ex=StrToInt(Edit9->Text);
srand(time(NULL));
rand();
for(int i=1; i<=k_ex;i++)
{
smo[0][i]=i;
StringGrid1->Cells[0][i+1]=IntToStr(smo[0][i]);
if (i==1)
{
smo[1][i]=0;
StringGrid1->Cells[1][i+1]="-";
}
else
{ /*Час після прибуття попереднього покупця*/
smo[1][i]=((float)rand()/(float)RAND_MAX)*d_rec[1]+d_rec[0];
StringGrid1->Cells[1][i+1]=IntToStr(smo[1][i]);
}
/*Час обслуговування*/
smo[2][i]=((float)rand()/(float)RAND_MAX)*d_ser[1]+d_ser[0];
StringGrid1->Cells[2][i+1]=IntToStr(smo[2][i]);
/*Біжучий час моделювання в момент прибуття покупця*/
smo[3][i]=smo[3][i-1]+smo[1][i];
StringGrid1->Cells[3][i+1]=FloatToStr(TimeFormat(smo[3][i]));
/*Початок обслуговування*/
if (smo[5][i-1]>smo[3][i])smo[4][i]=smo[5][i-1];
else smo[4][i]=smo[3][i];
StringGrid1->Cells[4][i+1]=FloatToStr(TimeFormat(smo[4][i]));
/*кінець обслуговування*/
smo[5][i]=smo[4][i]+smo[2][i];
StringGrid1->Cells[5][i+1]=FloatToStr(TimeFormat(smo[5][i]));
/*Час перебування покупця біля прилавку*/
smo[6][i]=smo[5][i]-smo[3][i];
StringGrid1->Cells[6][i+1]=IntToStr(smo[6][i]);
/*Час простою продавця в очікуванні покупця*/
smo[7][i]=smo[3][i]-smo[5][i-1];
if (smo[7][i]<0)smo[7][i]=0;
StringGrid1->Cells[7][i+1]=IntToStr(smo[7][i]);
t_och+=smo[4][i]-smo[3][i];
t_in+=smo[6][i];
t_pros+=smo[7][i];
StringGrid1->RowCount++;
}
/*інтенсивність вхідного потоку заявок*/
Edit6->Text=FloatToStrF((float)k_ex/(float)smo[5][k_ex],ffFixed,5,2);
/*час очікування заявкою обслуговування*/
Edit7->Text=FloatToStrF((float)t_och/(float)k_ex,ffFixed,5,2);
/*час перебування в системі*/
Edit8->Text=FloatToStrF((float)t_in/(float)k_ex,ffFixed,5,2);
/*Коефіцієнт завантаження каналу системи*/
Edit1->Text=FloatToStrF(1-((float)t_pros/(float)smo[5][k_ex]),ffFixed,5,2);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
ShowMessage("Інтенсивність входного потоку заявок \n L=кількість покупців/tкінц обслуг\n\n tоч=tоч/кількість покупців \n\n tпростою=tвходження/кількість покупців \n \n Коефіцієнт завантаження=1-tпрост/tкінц обслугов.\n \n ");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1:: Edit1KeyPress(TObject *Sender, char &Key)
{
if ((Key < '0' || Key > '9') && Key != 8) Key= 0;
}
//---------------------------------------------------------------------------
Лістинг файлу SMOun.h
#ifndef SMOunH
#define SMOunH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
#include "XPManifest.h"
#include "AlignmentEdit.h"
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TStringGrid *StringGrid1;
TXPManifest *XPManifest1;
TPanel *Panel1;
TEdit *Edit6;
TEdit *Edit7;
TEdit *Edit8;
TEdit *Edit1;
TLabel *Label6;
TLabel *Label7;
TLabel *Label8;
TLabel *Label9;
TLabel *Label10;
TPanel *Panel2;
TLabel *Label1;
TLabel *Label3;
TLabel *Label4;
TLabel *Label5;
TAlignmentEdit *AlignmentEdit1;
TAlignmentEdit *AlignmentEdit2;
TLabel *Label2;
TAlignmentEdit *AlignmentEdit3;
TAlignmentEdit *AlignmentEdit4;
TAlignmentEdit *AlignmentEdit5;
TLabel *Label11;
TButton *Button1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall StringGrid1DrawCell(TObject *Sender, int ACol, int ARow,
TRect &Rect, TGridDrawState State);
void __fastcall Button1Click(TObject *Sender);
void __fastcall AlignmentEdit1KeyPress(TObject *Sender, char &Key);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Вигляд форми SMOun.dfm
Висновок: я ознайомився з методом імітаційного моделювання та із застосуванням методу для дослідження систем масового обслуговування (СМО).