交通系统仿真实验报告

实验报告

 

2012 11 10


实验一随机数生成程序

一.  实验要求

产生1~1000的随机数,个数大约256个。

二.  实验环境

工具使用Visual C++ 6.0,程序类型 Win32 Console Application。

三.  实验原理

根据公式x[i]=a*x[i-1]mod(m),可根据所需范围值确定a和m的值,本实验中需要1~1000的随机数,因此可以选择a=35,m=1024。其周期为(m/4)=256,产生256个1~1024之间随机数。根据需要,我们舍弃大于1000的随机数,原理是我们使用中间变量连接产生的数与我们需要的数组,通过对中间变量的不断循环,当产生大于1000的随机数时,我们继续使中间变量不断循环但不放入数组,从而舍弃这些数字,最终得到我们需要的1~1000的随机数的数组并输出数组中的数,并计数其个数,这样就完成了我们的产生随机数的目的。

四.  实验步骤

图一 随机数程序流程图

                   图二  随机数程序运行结果

程序开始先给定初始值(1~1000以内奇数),根据给定的公式计算中间值temp,再判断temp的值是否小于1000,把小于1000的temp值赋给数组x[i],循环执行该命令直至x[i]=x[0],结束程序并输出数组值和数组大小。数组值随初始值改编而改变,初始值决定数组值的变化。

五.   分析总结

由图二随机数程序运行结果可以看出,该程序运行结果与我们所给与的数学模型期望达到的效果一致。程序运行正确,伪随机数的周期为256个,由于去除了大于1000的随机数,故程序结果显示为249,与数学模型的周期一致。

附录


#include <stdio.h>

void main(void)

{

    int i=1,j=0,temp=0;

       int a=35,m=1024;

       int x[256];

       int k;

       printf("输入到达服务时间随机初始值:");

       scanf("%d",&x[0]);

       printf("\n");

          while(i)  

          {       temp=a*x[i-1]%m;

              while(temp>1000)

         {        

                temp=a*temp%m;

         }

         if(temp!=x[0])

         {

                x[i]=temp;

                printf("%5d",x[i]);

                i++;

         }

         else {j=i-1,i=0;}

          }

          printf("\n\nj=%d\n\n",j);}



实验二单服务台排队系统仿真

一.  实验要求

单服务台对到达顾客进行服务,顾客单路排队,随机分配顾客的到达时间间隔和服务时间,从而确定顾客的到达时刻和服务开始结束时刻,并计算服务台的空闲时间和顾客的排队等待时间。通过程序实现对单服务台排队系统的仿真,根据程序运行结果计算重要结果属性值。

二.  实验环境

工具使用Visual C++ 6.0,程序类型 Win32 Console Application。

三.  实验原理

在程序设计中,顾客到达时间间隔time_interval和服务时间service_time由随机数确定。顾客到达时间间隔通过随机数分布并定义其分布区间,从而确定其到达间隔时间;服务时间也是先通过随机数程序产生一组随机数,然后通过对随机数区间的定义确定随机服务时间。这两个参数确定后可以通过数学方法确定其他参数,因此到达时间间隔和服务时间是程序中最重要的两个参数。

四.  实验步骤

                     图三 单服务台仿真流程图

 

图四 随机时间间隔 

               图五 随机服务时间

图六  单服务台排队系统顾客服务时刻表

程序先通过随机数方法分配排队顾客的随机到达时间间隔和随机服务时间。随机到达时间间隔是用1~1000之间的随机数进行等概率分配给1~8分钟的到达间隔;随机服务时间是将1~1000的随机数分配给1~6分钟的服务时间,其分配时段根据概率0.1,0.2,0.35,0.2,0.1,0.05分配,通过这种方法将1~1000以内的随机数分配给各个时间段,从而得到顾客的随机到达时间间隔和随机服务时间。

得到这两个基本参数后,通过数学方法联系其他参数,运用程序的循环过程最终可以输出单服务台顾客服务时刻表。

五.  分析总结

通过程序运行和结果校正,程序输出结果正确,程序运行正确。我们以10个顾客为例,运行程序,可以计算出在该程序设定条件下的属性值:

顾客平均等待时间=0.7 min

服务员平均服务时间=3.4 min

服务员平均空闲时间=1.2 min

六.  附录

#include <stdio.h>

int  imax(int, int);

void main(void)

{

        int time_interval[256];

        int reach_point[256];

        int service_time[256];

        int service_end_point[256];

        int wait_time[256];

        int free_time[256];

        int x[256];

     int y[256];

        int n,max;

     int i=1,temp=0;

        int a=35,m=1024;

/*输入顾客人数*/

     printf("输入顾客数n: ");

     scanf("%d",&n);

/*产生到达时间随机间隔*/

       printf("\n输入到达时间间隔随机初始值(1~1000): ");

       scanf("%d",&x[0]);

    printf("\n");

          while(i>=1)  

          {      

                 temp=a*x[i-1]%m;

              while(temp>1000)

         {        

                temp=a*temp%m;

         }

         if(temp!=x[0])

         {

                x[i]=temp;

                i++;

         }

         else {i=0;}

          }

          for(i=1;i<=n;i++)

          {

                 if(x[i]>=1&&x[i]<=125)

                        time_interval[i]=1;

                 if(x[i]>=126&&x[i]<=250)

                        time_interval[i]=2;

                 if(x[i]>=251&&x[i]<=375)

                        time_interval[i]=3;

                 if(x[i]>=376&&x[i]<=500)

                        time_interval[i]=4;

                 if(x[i]>=501&&x[i]<=625)

                        time_interval[i]=5;

                 if(x[i]>=626&&x[i]<=750)

                        time_interval[i]=6;

                 if(x[i]>=751&&x[i]<=875)

                        time_interval[i]=7;

                 if(x[i]>=876&&x[i]<=1000)

                        time_interval[i]=8;

          }

     i=1;

     printf("第1位顾客到达时间间隔为: 0");

     for(i=2;i<=n;i++)

       {

         printf("\n第%d位顾客的随机到达时间间隔位: %d",i,time_interval[i]);

       }

     printf("\n\n");

/*产生随机服务时间*/

     i=1,temp=0;

        a=35,m=1024;

     printf("\n输入到达服务时间随机初始值(1~1000): ");

        scanf("%d",&y[0]);

        printf("\n");

          while(i>=1)  

          {       temp=a*y[i-1]%m;

              while(temp>1000)

         {        

                temp=a*temp%m;

         }

         if(temp!=y[0])

         {

                y[i]=temp;

                i++;

         }

         else {i=0;}

          }

          for(i=1;i<=n;i++)

          {

                 if(y[i]>=1&&y[i]<=100)

                        service_time[i]=1;

                 if(y[i]>=101&&y[i]<=300)

                        service_time[i]=2;

                 if(y[i]>=301&&y[i]<=650)

                        service_time[i]=3;

                 if(y[i]>=651&&y[i]<=850)

                        service_time[i]=4;

                 if(y[i]>=851&&y[i]<=950)

                        service_time[i]=5;

                 if(y[i]>=951&&y[i]<=1000)

                        service_time[i]=6;

          }

          for(i=1;i<=n;i++)

          {

                 printf("\n第%d位顾客的随机服务时间:%d ",i,service_time[i]);

          }

          printf("\n\n\n");

/*主程序排队序列开始,将第一人单独考虑,后面的连续分配间隔时间*/

    time_interval[0]=0;

       reach_point[0]=0;

       service_time[0]=0;

       service_end_point[0]=0;

       wait_time[0]=0;

       free_time[0]=0;

    time_interval[1]=0;

       reach_point[1]=0;

    wait_time[1]=0;

       free_time[1]=0;

    service_end_point[1]=reach_point[1]+service_time[1];

    printf("顾客号=1");

    printf("   到达时间间隔=%d",time_interval[1]);

    printf("   到达时刻=%d",reach_point[1]);

    printf("   服务时间=%d",service_time[1]);

    printf("   服务结束时刻=%d",service_end_point[1]);

    printf("   等待时间=%d",wait_time[1]);

    printf("   空闲时间=%d",free_time[1]);

   for(i=2;i<=n;i++)

   {

              reach_point[i]=reach_point[i-1]+time_interval[i];

              max=imax(service_end_point[i-1],reach_point[i]);

              service_end_point[i]=service_time[i]+max;

              if(service_end_point[i-1]-reach_point[i]>=0)

                     free_time[i]=0,wait_time[i]=service_end_point[i-1]-reach_point[i];

              if(service_end_point[i-1]-reach_point[i]<0)

                     wait_time[i]=0,free_time[i]=reach_point[i]-service_end_point[i-1];

   printf("\n顾客号=%d",i);

   printf("   到达时间间隔=%d",time_interval[i]);

   printf("   到达时刻=%d",reach_point[i]);

   printf("   服务时间=%d",service_time[i]);

   printf("   服务结束时刻=%d",service_end_point[i]);

   printf("   等待时间=%d",wait_time[i]);

   printf("   空闲时间=%d",free_time[i]);

       }

   printf("\n");

}

 int imax(int x, int y)

 {

        int z;

     if(x>=y)

               z=x;

     else z=y;

     return(z);

 }


实验三单车道车辆跟驰仿真

一.  实验要求

运用编程方法实现车辆跟驰仿真的三种类型:

1、前车匀速行驶,后车的运行状况。

2、前车加速行驶,后车的运行状况。

3、前车减速行驶至停止,后车的运行状况。

二.  实验环境

Visual C++6.0;程序类型:MFC Application。

三.  实验原理

单车道车辆跟驰仿真实验描述了三种过程,它们是:当前车匀速行驶时,后车与前车之间初始时有一段距离,后车判断间距后,通过加速或减速与前车达到一个安全距离后保持与前车相同的速度行驶;当前车加速行驶时,后车先是以初始速度通过一个反应时间,再以大于前车的加速度追赶前车,当后车与前车达到安全距离时,后车与前车以相同的加速度行驶;当前车减速时,后车先以初始速度经过一个反应时间,再以大于前车的减速度减速,当间距为安全距离时,后车保持与前车相同的减速度行驶,直至停车。重要参数有车辆位置、前后车初始速度、前后车加速度、后车司机反应时间、模拟步长等。

四.  实验步骤

   

图七 跟驰仿真流程图           图八 前车匀速时后车跟驰状态

图九 前车加速时后车跟驰状态     图十 前车减速事后车跟驰状态

五.  分析总结

程序设计时可以对图形的边界进行设置,运用程序命令实现循环边界,这样可以更完整的看到在该程序设计条件下的汽车运行状态。通过循环边界我们可以完整的观测到前车加速行驶时后车的先加速追上前车再与前车保持相同加速度的过程。

六.  附录

void CFollowingSimulationView::OnDraw(CDC* pDC)

{

       CFollowingSimulationDoc* pDoc = GetDocument();

       ASSERT_VALID(pDoc);

       if (!pDoc)

              return;

   

       CRect rect;

       GetClientRect(&rect);

    CBitmap bitmap_1,bitmap_2;

       bitmap_1.LoadBitmap(IDB_BITMAP_CAR);//CBitmap是实在数据结构

       bitmap_2.LoadBitmap(IDB_BITMAP_CAR2);

       BITMAP bmp;

       bitmap_1.GetBitmap(&bmp);//同样的素材可以共用

   

       CDC dcCompatible_1,dcCompatible_2;

       dcCompatible_1.CreateCompatibleDC(pDC);

       dcCompatible_1.SelectObject(&bitmap_1);//确定dcCompatible_1的显示表面大小,即位图就是个作图背景;之后,就可以在位图上进行画图了

       dcCompatible_2.CreateCompatibleDC(pDC);

       dcCompatible_2.SelectObject(&bitmap_2);

    if(changes==0)

       {

              if(pos_2<rect.Width())//前面一辆车

          {

       pDC->StretchBlt(pos_1,100,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_1,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

       pDC->StretchBlt(pos_2,100,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_2,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

              //以汽车走的距离为x轴起点

          }

       else {//前车移动到下一行,后车行驶完width()-pos_2的距离,移动到下一行

                      KillTimer(1);

             pos_2=0;

             distance();

                      pos_1=inidis;//两车的初始距离

             Velocity();//计算deltaX_1和deltaX_2的值,即两车的初始速度

                      Accelerated_Velocity_1();//前车的加速度,获得Av_1

                      changes+=1;

                      step=0;

             Sleep(2000);

                      SetTimer(2,50,NULL);

                    

                      //停车

               }

       }

       if(changes==1)

       {

        if(pos_2<rect.Width())//后车位置

          {

       pDC->StretchBlt(pos_1,200,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_1,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

       pDC->StretchBlt(pos_2,200,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_2,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

              //以汽车走的距离为x轴起点

          }

       else {//前车移动到下一行,后车行驶完width()-pos_2的距离,移动到下一行

                      KillTimer(2);

             pos_2=0;

             distance();

                      pos_1=inidis;//两车的初始距离

            // Velocity();//计算deltaX_1和deltaX_2的值,即两车的初始速度

                      deltaX_1=30;deltaX_2=20;

                      Accelerated_Velocity_1();//前车的加速度,获得Av_1

                      changes+=1;

                      step=0;

             Sleep(2000);

                      SetTimer(3,50,NULL);

                      //停车

               }

       }

    if(changes==2)

       {

        if(pos_2<rect.Width()&&(deltaX_1>=0))//后车位置

          {

       pDC->StretchBlt(pos_1,300,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_1,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

       pDC->StretchBlt(pos_2,300,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_2,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

              //以汽车走的距离为x轴起点

          }

              else  {

                     KillTimer(3);

            pDC->StretchBlt(pos_1,300,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_1,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

                  pDC->StretchBlt(pos_2,300,bmp.bmWidth/4,bmp.bmHeight/4,&dcCompatible_2,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

                     bitmap_1.DeleteObject();

                     bitmap_2.DeleteObject();

                     dcCompatible_1.DeleteDC();

                     dcCompatible_2.DeleteDC();

              }

       }

void CFollowingSimulationView::OnTimer(UINT_PTR nIDEvent)

{

       // TODO: Add your message handler code here and/or call default

    step+=1;

       //int temp=0;//存储步长用

       if(changes==0)//说明刚开始第一个时间段,两车均以匀速行驶,但deltaX_1>deltaX_2,因此需要后车加速以完成车距保持的目的

       {

              //Av_2=(30*(deltaX_1-deltaX_2)+realdis-200)/465;//只能计算一次

              pos_1+=deltaX_1;

              pos_2+=deltaX_2;

              if(step>20)//可以通过if语句判断两车的实时距离有没有到200左右,到了的话就停止

              {

                     if(abs(pos_1-pos_2)>200)

                     {

                            deltaX_2+=1;

                         pos_2+=deltaX_2;

                     }

                     else {deltaX_2=deltaX_1;}

              }

       }

       if(changes==1)

       {

                     deltaX_1+=1;//前车加速度

            pos_1+=deltaX_1;

            if(step<=15)

                     pos_2+=deltaX_2;

                     if(step>15)

                     {

                            if(abs(pos_1-pos_2)>200)

                     {

                            deltaX_2+=3;

                         pos_2+=deltaX_2;

                     }

                         else {deltaX_2=deltaX_1;}

                     }

              }

       if(changes==2)

       {

                     deltaX_1-=1;//前车加速度

            pos_1+=deltaX_1;

            if(step<=20)

                     pos_2+=deltaX_2;

                     if(step>20)

                     {

                            if(abs(pos_1-pos_2)>200)

                     {

                            deltaX_2-=2;

                         pos_2+=deltaX_2;

                     }

                         else {deltaX_2=deltaX_1;}

                     }

              }

       Invalidate(true);

       CView::OnTimer(nIDEvent);

}

相关推荐