输出效果

本模型是在NaSch模型基础上加入安全条件以及换道概率的单向3车道模型。

基本思路是一个时间步分为两个部分,前半部分执行换道过程,后半个部分执行跟驰过程,即,NaSch四步。

换道流程是,先判断前车是否阻碍车辆对速度的追求,若阻碍且满足换道条件(目标车道前车车距与安全距离的大小关系)则必定换道;若不阻碍则概率换道。其中中间车道若换道优先右边,且前车不阻碍车辆对速度追求时只会以概率向右换道。

和之前的模型在车辆信息储存上有很大的区别,这次是将固定初始车辆数目(通过输入道路车辆占比来控制),所有车辆都有自己的编号,即车辆之间有区分,遍历所有车辆通过循环车辆编号来实现,这样做有一个好处就是执行周期边界的时候不必担心最左边车道被占据,且驶出车辆继续驶入初始位置,仿真很自然,相应的缺点就是只能模拟出入车辆一直保持相等的交通状态。还有就是用space矩阵(取值只有0,1)来表示车道占据情况,而车辆结构体来储存车辆信息,这样就避免了引入nan来表示无车和静止车辆间区别。

还是先贴代码,最后说缺点。


脚本

%%  单向3车道模型
%%  此模型车辆从左向右运动,左右车道是以车辆前进方向的左右
clc;
clear;
%%  参数设置
lane_length = 100; %车道长度
car_rate = 0.1;  %车辆占有率
v_max = 5; %最大车速
time_max = 1000; %仿真步长
time_span = 0.1; %仿真图片输出间隔
p_slowdown = 0.3; %随机慢化概率
p_changelane = 0.3; %驾驶员换道欲望
%%  开始仿真
main(lane_length,car_rate,v_max,time_max,time_span,p_slowdown,p_changelane)

主函数

%%  单向3车道主函数
%%  注意:在本模型中车辆位置信息由车道和列两个维度唯一确定
function  []= main(lane_length,car_rate,v_max,time_max,time_span,p_slowdown,p_changelane)car_number = fix(1+(3*lane_length-1)*car_rate); %按车辆占有率算出的车辆数
%%  创建空间
space = zeros(3,lane_length);%元胞空间
car = struct('v',zeros(1,car_number),'m',zeros(1,car_number),'n',zeros(1,car_number));% 车辆信息结构体从左到右为速度,车道,列
%%  随机生成初始车辆信息
[space,car] = initialize(space,car,car_number,lane_length,v_max);%%  显示初始仿真图
figure('name','单向3车道模型','position',[241 132 560 420],'doublebuffer','on');%窗口名称,位置,双缓存)
space = -1*space;
H = imshow(space,[]);
title('单向3车道模型','color','red');
space = -1*space;
%%  开始仿真
for time=1:time_max%%  换道阶段[car,space] = change_lane(space,car,car_number,p_changelane,v_max,lane_length);%%  跟驰阶段[space,car] = NaSch(space,car,v_max,lane_length,p_slowdown,car_number);%%  显示仿真图space = -1*space;set(H,'CData',space);pause(time_span);space = -1*space;
end
end

车辆道路初始化函数:

function [space,car] = initialize(space,car,car_number,lane_length,v_max)
%%  随机生成初始车辆信息
for time=1:car_number%%  位置信息初始化if  time<=fix(car_number/3)%%  最左边车道随机投放车辆car.m(time) = 1;car.n(time) = fix( 1+rand(1)*(lane_length-1) );while space(car.m(time),car.n(time))==1car.n(time) = fix( 1+rand(1)*(lane_length-1) );endspace( 1,car.n(time) ) = 1;elseif  time<fix( (car_number*2)/3 )%%  中间车道随机投放车辆car.m(time) = 2;car.n(time) = fix( 1+rand(1)*(lane_length-1) );while space(car.m(time),car.n(time))==1car.n(time) = fix( 1+rand(1)*(lane_length-1) );endspace( 2,car.n(time) ) = 1;else%%  最右边车道投放车辆   car.m(time) = 3;car.n(time) = fix( 1+rand(1)*(lane_length-1) );while space(car.m(time),car.n(time))==1car.n(time) = fix( 1+rand(1)*(lane_length-1) );endspace( 3,car.n(time) ) = 1;end%%  速度信息初始化car.v(time) = fix( 1+rand(1)*(v_max-1) );end
end

跟驰函数

function [space,car] = NaSch(space,car,v_max,lane_length,p_slowdown,car_number)
for id = 1:car_number%%  加速car.v(id) = min(car.v(id)+1,v_max);%%  获取车辆前空元胞数以及是否符合满足周期循环[cycle,empty]=get_empty_front(id,car,v_max,lane_length,space);%%  判断车辆是否满足周期边界条件if  cycle%%  减速car.v(id) = min( car.v(id) , empty );%%  概率慢化if  rand(1) <= p_slowdowncar.v(id) = max( car.v(id)-1,0 );end%%  位置更新space ( car.m(id),car.n(id) ) = 0;                 %位置更新前元胞变为无车car.n(id) = car.n(id) +car.v(id);space ( car.m(id),car.n(id) ) = 1;   else%%  周期边界条件将头车以原速度道路最左边space ( car.m(id),car.n(id) ) = 0;car.n(id) = 1;space ( car.m(id),car.n(id) ) = 1;   end
end
end

换道函数

%%  换道函数
function [car,space] = change_lane(space,car,car_number,p_changelane,v_max,lane_length)empty_safe = v_max; %安全车距for  id = 1:car_number[cycle,empty]=get_empty_front(id,car,v_max,lane_length,space);if  cycle   %执行周期边界条件车辆不换道if  car.m(id) == 1
%%  最左侧车道换道%%  获取周边车距[empty_right_back,empty_right_front] = get_empty(car.m(id)+1,car.n(id),v_max,space,lane_length);if  empty<min(car.v(id)+1,v_max)%%  前车阻碍对速度的追求if  empty_right_front>=empty_safe && empty_right_back>=empty_safe && space( car.m(id)+1,car.n(id) )==0 %右前,右后,旁边均安全%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)+1;space (car.m(id),car.n(id)) =1;endelse%%  前车无影响if  rand(1)<p_changelaneif  empty_right_front>empty_safe && empty_right_back>empty_safe &&  space( car.m(id)+1,car.n(id) )==0 %右前,右后,旁边均安全%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)+1;space (car.m(id),car.n(id)) =1;endendendelseif  car.m(id) ==2
%%  中间车道换道%%  获取周边车距[empty_right_back,empty_right_front] = get_empty(car.m(id)+1,car.n(id),v_max,space,lane_length);[empty_left_back,empty_left_front] = get_empty(car.m(id)-1,car.n(id),v_max,space,lane_length);if  empty<min(car.v(id)+1,v_max)%%  前车阻碍对速度的追求%%  向右换道if  empty_right_front>=empty_safe && empty_right_back>=empty_safe && space( car.m(id)+1,car.n(id) )==0 %右前,右后,旁边均安全%%  右边满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)+1;space (car.m(id),car.n(id)) =1;%%  向左换道elseif  empty_left_front>=empty_safe && empty_left_back>=empty_safe && space( car.m(id)-1,car.n(id) )==0%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)-1;space (car.m(id),car.n(id)) =1;end%%  前车不阻碍速度追求        else%%  以一定几率向右换道if  rand(1)<p_changelaneif  empty_right_front>empty_safe && empty_right_back>empty_safe &&  space( car.m(id)+1,car.n(id) )==0 %右前,右后,旁边均安全%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)+1;space (car.m(id),car.n(id)) =1;endendendelse
%%  最右侧车辆换道%%  获取周边车距[empty_left_back,empty_left_front] = get_empty(car.m(id)-1,car.n(id),v_max,space,lane_length);if  empty<min(car.v(id)+1,v_max)%%  前车阻碍对速度的追求if  empty_left_front>=empty_safe && empty_left_back>=empty_safe && space( car.m(id)-1,car.n(id) )==0 %右前,右后,旁边均安全%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)-1;space (car.m(id),car.n(id)) =1;endelse%%  前车无影响if  rand(1)<p_changelaneif  empty_left_front>empty_safe && empty_left_back>empty_safe &&  space( car.m(id)-1,car.n(id) )==0 %右前,右后,旁边均安全%%  满足安全条件换道space (car.m(id),car.n(id)) =0;car.m(id) = car.m(id)-1;space (car.m(id),car.n(id)) =1;endendendend
end
end

获取前车车距及判断是否执行周期边界条件函数

%用于求出cell_i与前方元胞空元胞数并判断是否需要执行周期边界条件,cycle返回值为1不需要,0需要
%  输出EmptyFront为输入车辆处元胞前方空元胞数(超过v_max按v_max算)
function [cycle,empty_front] = get_empty_front(id,car,v_max,lane_length,space)
empty_front = 0;
cycle=1;
if  car.n(id)+v_max < lane_length-v_max       %判断是否到边界(lane_length-v_max)%%  求出车辆前方空元胞数for front= ( car.n(id) + 1 ) : ( car.n(id) + v_max )if space( car.m(id),front )==1empty_front = front- (car.n(id)+1);break;endempty_front = v_max;endelse%% 判断是否是头车first = 1;for front= min( ( car.n(id) + 1 ),lane_length ) :lane_lengthif  space( car.m(id),front )==1empty_front = front- (car.n(id)+1);    %不是头车就输出空格数first =0;break;endendif first%%  判断头车下一时间步是否可能移动到lane_length-1处if  car.n(id)+car.v(id)+1 >= lane_length-1cycle = 0;elseempty_front =v_max;  %只要头车下一秒不到达lane_length前方空元胞数按v_max记endend
end
end

获取指定位置车辆前后车距函数

%%  本函数用于求输入车辆前后车距
%%  输入参数m,n为一辆车的位置信息,输出该车所在车道前后车距,车距超过安全车距按安全车距算
function [empty_back,empty_front] = get_empty(m,n,v_max,space,lane_length)
empty_back = 0;
empty_front = 0;%%  求出车辆后方空元胞数for back=  n :-1: max(n-v_max ,1)if space( m,back )==1empty_back =n-back;break;endempty_back = v_max;end%%  获取车辆前方空元宝数for front=  n: min(n+ v_max,lane_length) if space( m,front )==1empty_front = front-n;break;endempty_front = v_max;end
end

目前缺点:

1.安全车距的设置我是将安全车距设为最大车速,还需要查阅相关文献,只是按自己主观臆测随便设置的。

2.车辆换道过程变成了一个横向运动,这和实际肯定有出入,没有了倾斜运动。且换道过程可以在一个时间步内完成,而且车辆确定换道之后就判断安全条件是否满足,而没有考虑前后车之间的博弈过程。

3.本模型实际是区分左右车道的换道优先性的,但只是为了方便,并没有引入快慢车道,所以对快慢车道以及驾驶员对车道偏好的影响并没没有考虑。

最后还是希望有小伙伴可以加我一起进步哈。

vissim跟驰模型_MATLAB——基于元胞自动机的单向3车道模型相关推荐

  1. 【元胞自动机】基于元胞自动机模拟3D森林火灾模型含Matlab源码

    1 简介 森林火灾威胁森林安全,导致生命财产与环境损失,动态模拟森林火灾对于预判森林火灾发展趋势,减少森林火灾危害,科学开展森林火灾灭火工作具有重要理论与现实意义.为更加形象,直观地展示林火三维可视化 ...

  2. 【元胞自动机】基于元胞自动机模拟双车道交通流模型含靠右行驶matlab源码

    元胞自动机的初步理解 对元胞自动机的初步认识\ 元胞自动机(CA)是一种用来仿真局部规则和局部联系的方法.典型的元\ 胞自动机是定义在网格上的,每一个点上的网格代表一个元胞与一种有限的状\ 态.变化规 ...

  3. c#元胞自动机_基于元胞自动机模型的行人排队行为模拟

    06 系统工程理论与方法 基于元胞自动机模型的行人排队行为模拟 廖明军 1, 2 , 孙

  4. 【元胞自动机】基于元胞自动机模拟大型商场人流疏散含Matlab源码

    1 简介 基于元胞自动机的场强模型在二维平面行人流疏散问题的研究中已得到了广泛应用.已有模型主要描述行人基于出口位置并跟随其余行人进行疏散的行为特征,未充分考虑火灾蔓延和局部拥堵对行为选择的影响,难以 ...

  5. 【元胞自动机】基于元胞自动机模拟双通道人群疏散含Matlab源码

    1 简介 为了消除礼堂的安全隐患,制定行之有效的应急预案,有必要对礼堂人群疏散运动进行研究,掌握礼堂人群疏散的一般特点和规律.采用基于二维元胞自动机模型对某高校礼堂发生人群疏散运动进行仿真,找出影响礼 ...

  6. 【元胞自动机】基于元胞自动机模拟晶体生长附matlab代码

    1 内容介绍 基于溶质扩散和界面能的作用,考虑成分过冷,曲率过冷,界面能各 向异性和界面扰动等因素,建立了单个等轴枝晶的生长模型.采用元胞自动机(cellular automata)方法模拟了枝晶生长 ...

  7. 【元胞自动机】基于元胞自动机模拟商场人流量matlab代码

    1 简介 本文属于计算机科学和交通工程的交叉领域,涉及一种基于元胞自动机的商场行人微观仿真方法,首先对商场行人区域网格化处理,得到元胞自动机模型相应的元胞空间,并将其划分为一些凸多边形区域;其次判断每 ...

  8. 【元胞自动机】基于元胞自动机模拟行人通过斑马线matlab代码

    1 简介 近年来,伴随着我国社会经济的快速发展和人们生活水平的普遍提高,整个社会对交通运输的需求日益增加,带来了交通运输业的空前繁忙和各种车辆的迅猛增加,这也使得我国复杂的交通流组成和相对落后的交通流 ...

  9. 【元胞自动机】基于元胞自动机实现高速公路收费站交通流问题附matlab代码

    1 简介 近年来,我国高等级公路发展迅速,截止到2012年底,我国高速公路的通车里程已达到97355公里,比2011年增长14.6%.而我国自1984年以来实行"贷款修路.收费还贷" ...

最新文章

  1. Android中AES256加密的实现
  2. 逻辑运算符和||与(和|)的区别
  3. oracle主键自动增长
  4. Django - 网页加载报错:A server error occurred. Please contact the administrator(亲测)
  5. vfs管理下的linux文件系统
  6. Dalivik垃圾回收收机制Cocurrent GC简介
  7. 网关过滤器验证token
  8. nginx fastcgi php-fpm的关系梳理
  9. windows永久添加路由
  10. 大数据与BI的区别在哪
  11. 太傻了!下次二面再回答不好“秒杀系统“设计原理,我就捶死自己...
  12. 在MATLAB中快速画圆(给出圆心坐标和半径就能直接画的那种)
  13. 费德勒球拍_球拍编程指南(DrRacket)
  14. 黎曼和 Riemann Sum ,黎曼积分Riemann Integral,正态分布normal distribution
  15. Unity烘焙基础操作
  16. 关于树的一些学习心得
  17. VLOOKUP函数最常用的10种用法
  18. android 扫描枪封装,Android 扫码枪监听封装
  19. 美国自由女神像是法国赠送的【科普】
  20. pta-7-2 最大公约数与最小公倍数 (15 分)

热门文章

  1. ajax mysql登录我注册_ajax方式实现注册功能(提交数据到后台数据库完成交互)
  2. 检测和校准实验室能力认可准则_CNAS-CL01:2018检测和校准实验室能力认可准则之管理体系...
  3. 数据库比特币勒索病毒攻击警示,云和恩墨技术通讯六月刊精选
  4. 2018数据库流行度12月排行:Oracle续跌至年内低位,PostgreSQL激增创新高
  5. 备份恢复:如何让xtrabackup恢复速度提升20倍?
  6. 揭开KPI异常检测顶级AI模型面纱
  7. 实践案例丨ACL2020 KBQA 基于查询图生成回答多跳复杂问题
  8. 补习系列(13)-springboot redis 与发布订阅
  9. leetcode71 (2022.1.6)
  10. C# 集合 泛型 匿名方法(四)