📄 main.~cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#define morning 14400
#define noon 21600
#define afternoon 36000
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
SysTime=0; //仿真时钟初值
BusyTime=0;
TimeBeforeService=0; //服务前时间
Service_Time=0; //服务时间
Ticket_Time=0;
Tele_Time=0;
Ticket_In=0;//一天中来购票的人数
Tele_In=0;//一天中打进的电话数
Tele_UnIn=0;
Tele_TimeOut=0;//一天中因超时自动挂断的电话数
Ticket_Sold=0;//一天中卖出的票数
ConductorState=false;//售票员状态 - 闲
FirstComeInLunchTime=false; //是否为第一次进入午餐时间
FirstComeInAfternoon=false;
FirstComeInOverTime=false;
Ticket=0; //标志服务对象
}
//---------------------------------------------------------------------------
int TForm1::Gaussian(double mean,double variance)
{
double v1=0;
double v2=0;
float x1,x2;
double w=2.0;
while (w>1.0)
{
v1=2*random(1000)/(float)1000-1.0;
v2=2*random(1000)/(float)1000-1.0;
w=v1*v1+v2*v2;
}
if (w<1.0e-8) w=1.0e-8;
x1=v1*sqrt((-2*log(w))/w);
//x2=v2*sqrt((-2*log(w))/w);
x1=mean+sqrt(variance)*x1;
//x2=mean+sqrt(variance)*x2;
return (int)x1;
}
//-----------------------------------------------------
int TForm1::Poisson(double mean)
{
int i=0,j=0;
double pi1,pi;
double Fi1,Fi;
int x;
randomize();
while(j==0)
{
pi=exp(-mean);
Fi=0;
i=0;
double ui1=random(1000)/(float)1000;
do
{
pi1=pi; //pi1为原值
pi=mean/(i+1)*pi;//pi为改变后的值
Fi1=Fi; //Fi1为原值
Fi=Fi+pi; //Fi为改变后的值
i=i+1;
} while(!(ui1>=Fi1 && ui1<Fi )&& i<100);
if(ui1<Fi && ui1>=Fi1) j=1;
}
x=i;
return x;
}
//----------------------------------------------------
void TForm1::start()
{
int TicketComingTime;
int TelephoneComingTime;
Memo1->Lines->Add("开始仿真...");
TicketComingTime=Poisson(5)*60;//2分钟
Memo1->Lines->Add("正常产生新购票者:"+IntToStr(TicketComingTime));
Ticket_In++;
TicketListBox->Items->Insert(TicketListBox->Items->Count,TicketComingTime);
TelephoneComingTime=Poisson(8)*60; //10分钟
Memo1->Lines->Add("正常产生新问询者:"+IntToStr(TelephoneComingTime));
Tele_In++;
TelephoneListBox->Items->Insert(0,TelephoneComingTime);
SecondsTimer->Enabled=true;
}
//--------------------------------------------------------------------------
void TForm1::Arrive_LastTicket()
{
//时钟已经推进到最后一个顾客到达的时间
if(TicketListBox->Items->Count>0)
{
if (StrToInt(TicketListBox->Items->Strings[TicketListBox->Items->Count-1])==SysTime)
{
//产生一个新到者
int Ticket_Time=0;
while(Ticket_Time==0)
Ticket_Time=Poisson(5)*60;
Ticket_Time=Ticket_Time+StrToInt(TicketListBox->Items->Strings[TicketListBox->Items->Count-1]) ;
if(Ticket_Time<morning || (Ticket_Time>=noon && Ticket_Time<afternoon))
{
Ticket_In++;
TicketListBox->Items->Insert(TicketListBox->Items->Count,Ticket_Time);
//确定到达时间
Memo1->Lines->Add("正常产生新购票者:"+IntToStr(Ticket_Time));
}
}
}
// else Memo1->Lines->Add("购票者为空"+IntToStr(SysTime)) ;
}
//--------------------------------------------------------------------------
void TForm1::Arrive_LastTelephone()
{
//时钟已经推进到最后一个问讯顾客到达的时间
if (TelephoneListBox->Items->Count>0)
{
if (StrToInt(TelephoneListBox->Items->Strings[TelephoneListBox->Items->Count-1])==SysTime)
{
//产生一个新到者
if (TelephoneListBox->Items->Count<5)
{
int Telephone_Time=0;
while(Telephone_Time==0)
Telephone_Time=Poisson(8)*60;
Telephone_Time=Telephone_Time+StrToInt(TelephoneListBox->Items->Strings[TelephoneListBox->Items->Count-1]);
if(Telephone_Time<morning || (Telephone_Time>=noon && Telephone_Time<afternoon))
{
Tele_In++;
TelephoneListBox->Items->Insert(TelephoneListBox->Items->Count,Telephone_Time);
//确定到达时间
Memo1->Lines->Add("正常产生新问询者:"+IntToStr(Telephone_Time));
}
}
else
Tele_UnIn++;
}
}
// else Memo1->Lines->Add("问询者为空"+IntToStr(SysTime)) ;
}
//----------------------------------------------------
void TForm1::Ticket_Count()
{
//得到购票者购票的可能性
int Probability=random(2);
if(Probability==1)
{
//得到该购票者所购的票数
int probability_Ticket=random(10);
switch(probability_Ticket)
{
case 0: Ticket_Sold++;
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: Ticket_Sold=Ticket_Sold+2;
break;
case 7: Ticket_Sold=Ticket_Sold+3;
break;
case 8:
case 9: Ticket_Sold=Ticket_Sold+4;
break;
}
}
}
//-----------------------------------------------------
void TForm1::Telephone_TimeOut()
{
if (TelephoneListBox->Items->Count>0)
{
if (StrToInt(TelephoneListBox->Items->Strings[0])+180==SysTime)
//超时挂断
{
Memo1->Lines->Add("挂断超时电话:"+TelephoneListBox->Items->Strings[0]);
ListBox2->Items->Insert(ListBox2->Items->Count,TelephoneListBox->Items->Strings[0]+"--超时");
TelephoneListBox->Items->Delete(0);
Tele_TimeOut++;
}
}
//else Memo1->Lines->Add("超时时问询者为空"+IntToStr(SysTime)) ;
}
//--------------------------------------------------------------------------
void __fastcall TForm1::SecondsTimerTimer(TObject *Sender)
{
SysTime=SysTime+1;
//*******************************************************//
//属于上午营业时间
if(SysTime<morning)
{
//判断是否应该产生新到顾客
Arrive_LastTicket();
Arrive_LastTelephone();
//判断是否有电话问询者超时
Telephone_TimeOut();
if(ConductorState==false && ServiceTimer->Enabled==false) //售票员闲
{ //确定服务对象,并进行服务
//*************服务对象为购票者***************
if(TicketListBox->Items->Count>0&&StrToInt(TicketListBox->Items->Strings[0])<=SysTime)
//若购票者到达时间在仿真时钟之前,则为可用购票顾客
{
ConductorState=true;//将售票员状态置为忙 //处理该购票者
ListBox1->Items->Insert(ListBox1->Items->Count,TicketListBox->Items->Strings[0]);
Memo1->Lines->Add("正常服务购票者:"+TicketListBox->Items->Strings[0]);
//得到购票者购票的可能性
Ticket_Count();
TicketListBox->Items->Delete(0);
//将该购票者从购票队列中清除
while(Service_Time<=0)
Service_Time=Gaussian(4,2)*60; //产生一个服务时间,并启动服务时间定时器
Memo1->Lines->Add("开始售票服务,服务时间:"+IntToStr(Service_Time));
Ticket=1;//现在的服务对象为购票者
BusyTime=BusyTime+Service_Time;
Ticket_Time=Ticket_Time+Service_Time;
if(Service_Time==0)
{
Memo1->Lines->Add("服务结束,当前时间:"+IntToStr(SysTime));
Ticket=0;
}
else
{
TimeBeforeService=SysTime;
ServiceTimer->Enabled=true;
}
return;
}
//*************服务对象为购票者***************
//*************服务对象为问讯者或无服务对象***************
else //没有购票者在排队
{
if(TelephoneListBox->Items->Count>0 && StrToInt(TelephoneListBox->Items->Strings[0])<=SysTime) //若问讯者到达时间在仿真时钟之前,则为可用问讯顾客
{
ConductorState=true;//将售票员状态置为忙 //处理该问询者
ListBox2->Items->Insert(ListBox2->Items->Count,TelephoneListBox->Items->Strings[0]);
Memo1->Lines->Add("正常服务问讯者:"+TelephoneListBox->Items->Strings[0]);
TelephoneListBox->Items->Delete(0); //将该问讯者从问讯队列中清除
while(Service_Time<=0)
Service_Time=Gaussian(3,3)*60; // 产生一个服务时间,并启动服务时间定时器
Memo1->Lines->Add("开始问讯服务,服务时间:"+IntToStr(Service_Time));
Ticket=2;//服务对象为问询者
BusyTime=BusyTime+Service_Time;
Tele_Time=Tele_Time+Service_Time;
if(Service_Time==0)
{
Memo1->Lines->Add("服务结束,当前时间:"+IntToStr(SysTime));
Ticket=0;
}
else
{
TimeBeforeService=SysTime;
ServiceTimer->Enabled=true;
}
return;
}
else//既没有问询者,也没有购票者
return;
}//else
//*************服务对象为问讯者或无服务对象***************
}//if(ConductorState==false)//售票员闲着
else//售票员忙着
return;
}// if(SysTime<14400)//属于上午营业时间
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -