①事情的发生
朋友突然发来课题向我求助,关于用其他编程语言(不能用VB)实现仿真泊松分布的交通生成。
②问题的分析
在分析了这个课题之后,我将它拆分为这么几大块的知识点:
1、数学知识:什么是泊松分布。
2、编程知识:如何实现图形化界面内小车的生成、移动与消去。
③解决问题的进行过程
带着这样的问题我开始查阅资料。首先,简单说说泊松分布。记得以前上概率论课程是学习过,但是久而久之也就忘了。通过百度,了解到:
因为二项分布是一个时间段是有或者没有,但在现实生活中这并不是太普遍,因为一个时间段可能会有几个这种情况。但是如果我们把每段时间细分的很小,趋近于0,也就是几乎分了无穷多个时间段(n趋近于无穷),那么每个时间段就符合二项分布了。
好,知道了什么是泊松分布,接下来开始编程。这里应朋友要求,用C++(我虽然没系统的学过C++,但我有C语言的基础)。图形界面库选择用EGE(因为以前没有用过,于是现在去学来现炒现卖)。
推荐学习网址:
https://blog.csdn.net/qq_39151563/article/details/100154767?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase
因为以前学习过用python的pygame库写界面化游戏,所以一些图形化界面控制的思想还是有的,代码如下:
#include <graphics.h> // 就是需要引用这个图形库
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include<windows.h>
#include <math.h>
#define MAX 10
using namespace std;
typedef struct Car{
int x;
int y;
PIMAGE p;
}Car;
double U_Random();
int possion() /* 产生一个泊松分布的随机数,Lamda为总体平均数*/
{
int Lambda = 20, k = 0;
long double p = 1.0;
long double l=exp(-Lambda); /* 为了精度,才定义为long double的,exp(-Lambda)是接近0的小数*/
//printf("%.15Lfn",l);
while (p>=l)
{
double u = U_Random();
p *= u;
k++;
}
return k-1;
}
double U_Random() /* 产生一个0~1之间的随机数 */
{
double f;
srand( (unsigned)time( NULL ) );
f = (float)(rand() % 100);
return f/100;
}
Car InitCar()
{
Car car;
car.x = 0;
car.y = 0;
car.p = newimage();
getimage(car.p,"QQ图片20200531184828.png");//载入小车图片
return car;
}
int main()
{
initgraph(750, 300); // 初始化图形
Car car[MAX];
int carnum = 0;//小车总数
int havecar = 0;//一个判断是否应该出现新车的常量
int i,j;
setbkcolor(EGERGB(255, 255, 255));//设置背景为白色
havecar = possion()%10;//得到一个1到10之内的泊松分布随机数
while(1)
{
if(havecar == 0)//判断是否应该有新的车进入路段
{
if(carnum < MAX)//判断在这个路段的车是否小于这个路段最多能有的车,小于才生成新车
{
car[carnum] = InitCar();
carnum++;
havecar = possion()%10;
}
}
for(i = 0;i < carnum;i++)//将每辆车的位置放入画面
{
putimage(car[i].x, car[i].y, car[i].p);
}
for(i = 0;i < carnum;i++)//改变每辆车x轴的位置
{
car[i].x += getwidth(car[i].p);
if(car[i].x > 750)//如果车已经超出边界,便消除这辆车
{
for(j = i;j < carnum;j++)//让结构体组从消除车下一辆的标号向前平移
{
car[j] = car[j+1];
}
carnum--;
i--;
}
}
havecar--;
Sleep(400);//每个画面等待0.4秒
cleardevice();//清屏
}
getch(); // 按任意键继续也可以用system("pause");
closegraph(); // 关闭图形界面
}
其实这里的小车组可以用链式结构串起来,消去车会要方便一些,但是一开始我都用结构体组来写了,就将就了。
强调几个学习到的函数的使用:
得到图片:
getimage(一个PIMAGE类型的变量,“图片路径”)//注意,这里这个PIMAGE类型的变量必须先执行这句话:PIMAGE类型的变量 = newimage();
将图片加载到屏幕上:
putimage(左上角x轴的位置, 左上角y轴的位置, PIMAGE类型的变量);
设置背景颜色
setbkcolor(EGERGB(255, 255, 255));//通过RGB色彩设置模式设置,此处为白色
延迟时间:
Sleep(毫秒);//一个window.h库文件下的函数
清屏:
cleardevice()
得到图片的宽和高:
getwidth(PIMAGE类型的变量),gethigh(PIMAGE类型的变量)
④小小的心得
通过这次帮朋友解决课题中的困难,我更加坚信了以前听乔布斯在斯坦福大学演讲所说的一段话:你不可能将未来的片断串连起来;你只能在回顾的时候将点点滴滴串连起来。所以你必须相信这些片断会以某种方式在未来的某一天串连起来。你必须要相信某些东西:你的勇气、命运、生命、因缘,随便是什么。这种方法从来没有令我失望,只是让我的生命更加地与众不同。