⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.~cpp

📁 单窗口售票系统仿真程序 运用秒推进法模拟了单窗口售票系统售票员忙、闲
💻 ~CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------

#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 + -