news 2026/9/4 4:21:36

基于MATLAB的模糊控制十字路口红绿灯仿真建模与性能分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于MATLAB的模糊控制十字路口红绿灯仿真建模与性能分析

简介:本资源是一套面向本硕博阶段教研与算法实践者的MATLAB模糊控制教学案例,聚焦十字路口红绿灯智能调度问题,解决传统定时控制难以适应动态车流变化的痛点。压缩包共7个文件(132KB),含3个核心M函数(主程序Runme.m、交通灯逻辑trafficlight.m、地图绘制map.m)、2个FIS模糊推理系统文件(greentime.fis与selectroad.fis)、1段实操AVI录像及1份说明文本,覆盖建模、规则设计、仿真可视化全流程。已有1701人学习下载,配套操作视频详细演示MATLAB 2021a及以上版本下的运行路径设置、FIS加载与仿真调试全过程,避免常见子函数误运行错误;所有代码模块解耦清晰,便于理解模糊输入变量(车流量、等待时间)、输出变量(绿灯时长)及隶属度函数设计逻辑,是掌握模糊控制算法工程落地的典型入门范例。

1. 项目缘起:为什么用模糊控制来模拟红绿灯?

作为一名在交通仿真和控制领域摸爬滚打了十来年的工程师,我经常被问到:红绿灯控制不就是定时切换吗,有什么好研究的?这恰恰是最大的误解。传统的定时控制,就像给一个活生生的人制定一份精确到分钟的作息表,不管他是困了、饿了还是精力充沛,都必须严格执行。这在交通流量稳定、可预测的郊区或许还行,但在车流瞬息万变的城市十字路口,定时控制就显得非常“笨拙”和“不近人情”。

想象一下早高峰的场景:东西向的主干道早已排起长龙,而南北向的支路却只有零星几辆车。此时,如果南北向的绿灯时间依然按照预设的“45秒”来执行,那对东西向苦苦等待的司机们来说,无疑是巨大的时间浪费和燃油消耗。这种“一刀切”的策略,正是传统控制方法的痛点。

于是,我们引入了“模糊控制”。它不像传统逻辑那样非黑即白(“车多”或“车少”),而是允许“灰度”存在。它可以描述“车比较多”、“车非常多”、“车稍微有点多”这些更符合人类直觉的状态。基于这些模糊的判断,再通过一套精心设计的规则(例如:“如果东西向车流‘非常多’,且南北向车流‘非常少’,则‘大幅增加’东西向绿灯时间”),来自动、动态地调整信号灯的配时方案。这就像一个有经验的交警在现场指挥,他能根据目测的车流情况,灵活地延长或缩短某个方向的通行时间,从而实现路口整体通行效率的最大化。

这次,我就带大家用MATLAB这个强大的工程计算与仿真平台,亲手搭建一个基于模糊控制的十字路口红绿灯仿真模型。我们不仅会深入原理,还会一步步写出代码,并最终生成一个可视化的仿真视频,让你直观地看到模糊控制是如何让交通“活”起来的。无论你是自动化、交通工程专业的学生,还是对智能控制感兴趣的工程师,这个项目都能让你获得从理论到实践的完整体验。

2. 十字路口交通流建模:仿真的基石

在让模糊控制器大显身手之前,我们必须先为它搭建一个“舞台”——一个能够真实反映车辆到达、排队、消散过程的十字路口仿真模型。这个模型的质量,直接决定了我们后续控制算法验证的有效性。

2.1 路口结构与参数定义

我们模拟一个典型的四相位十字路口。为简化模型,我们做以下合理假设:

  1. 每个进口道(东、南、西、北)都只有一条直行车道。
  2. 忽略左转、右转及行人交通。
  3. 车辆长度统一,且遵循安全的跟车距离。

首先,我们需要在MATLAB中定义这个路口的核心参数。这些参数是仿真的“物理常量”。

% ========== 十字路口基础参数定义 ========== simulation_time = 1200; % 总仿真时间,单位:秒(20分钟) dt = 1; % 仿真步长,单位:秒。表示每1秒更新一次系统状态。 % 车道参数 lane_length = 200; % 每个方向排队车道的最大长度,单位:米 vehicle_length = 5; % 平均车长,单位:米 safe_gap = 2; % 车辆间最小安全距离,单位:米 % 信号灯相位(简化四相位) % Phase 1: 东西向直行绿灯,其他红灯 % Phase 2: 南北向直行绿灯,其他红灯 % (黄灯时间在控制逻辑中处理) phase_list = {'EW_Straight', 'NS_Straight'}; current_phase = 1; % 初始相位 phase_duration = [0, 0]; % 由模糊控制器动态计算,初始为0 % 车辆到达模型:使用泊松过程模拟 % 每个进口道(East, South, West, North)的车辆到达率(辆/秒),可随时间变化模拟潮汐流 lambda_base = 0.15; % 基础到达率,例如0.15辆/秒 = 540辆/小时 % 定义一个简单的潮汐流模式:前10分钟东西向繁忙,后10分钟南北向繁忙 lambda.E = zeros(1, simulation_time); lambda.S = zeros(1, simulation_time); lambda.W = zeros(1, simulation_time); lambda.N = zeros(1, simulation_time); for t = 1:simulation_time if t <= 600 % 前10分钟 lambda.E(t) = lambda_base * 1.8; % 东西向高流量 lambda.W(t) = lambda_base * 1.8; lambda.S(t) = lambda_base * 0.4; % 南北向低流量 lambda.N(t) = lambda_base * 0.4; else % 后10分钟 lambda.E(t) = lambda_base * 0.4; lambda.W(t) = lambda_base * 0.4; lambda.S(t) = lambda_base * 1.8; % 南北向高流量 lambda.N(t) = lambda_base * 1.8; end end % 初始化车辆队列:用结构体数组存储每个车道的车辆信息 for dir = {'E', 'S', 'W', 'N'} lanes.(dir{1}).queue = []; % 排队车辆列表,存储每辆车距停止线的距离 lanes.(dir{1}).departures = 0; % 累计驶离车辆数 end

注意:这里用泊松过程模拟车辆到达是行业标准做法,它能很好地刻画随机到达特性。lambda(到达率)随时间变化,是为了模拟真实的“潮汐现象”(早高峰进城方向流量大,晚高峰出城方向流量大),这让我们的仿真更贴近现实,也能更好地测试模糊控制器的适应性。

2.2 车辆生成、移动与消散逻辑

在每个仿真步长(1秒)内,我们需要完成以下子步骤:

步骤1:车辆生成。根据当前时刻各进口道的到达率(lambda),利用随机数决定是否生成新车。MATLAB中可以用rand() < lambda * dt来判断。

% 在仿真主循环的每个时间步t中: for dir = {'E', 'S', 'W', 'N'} dir_char = dir{1}; if rand() < lambda.(dir_char)(t) * dt % 生成一辆新车,将其加入对应车道队列的末尾 % 新车的初始位置为车道长度(lane_length),表示在队列最后方 if isempty(lanes.(dir_char).queue) new_pos = lane_length; else % 新车必须与前车保持安全距离 last_car_pos = lanes.(dir_char).queue(end); new_pos = last_car_pos + vehicle_length + safe_gap; end % 如果新车位置仍在车道范围内,则加入队列 if new_pos <= lane_length lanes.(dir_char).queue = [lanes.(dir_char).queue, new_pos]; end % 如果new_pos > lane_length,则表示上游拥堵,车辆无法加入,可记录为“溢出” end end

步骤2:车辆移动。根据当前信号灯相位,决定哪些车道的排队车辆可以向前移动。绿灯车道的第一辆车(最靠近停止线)如果距离停止线大于0,则可以“驶离”,后续车辆依次前移。

% 判断当前相位 if current_phase == 1 % 东西向绿灯 green_dirs = {'E', 'W'}; else % 南北向绿灯 green_dirs = {'S', 'N'}; end % 处理绿灯方向车辆移动 for dir_char = green_dirs dir_char = dir_char{1}; if ~isempty(lanes.(dir_char).queue) % 检查第一辆车是否到达停止线(位置<=0) if lanes.(dir_char).queue(1) <= 0 % 车辆驶离 lanes.(dir_char).queue(1) = []; lanes.(dir_char).departures = lanes.(dir_char).departures + 1; end % 所有车辆向前移动一个“步长” % 假设车辆以恒定速度通过路口,例如每秒通过一辆车(简化) % 更复杂的模型可以引入加速度和速度 lanes.(dir_char).queue = lanes.(dir_char).queue - 1; % 每秒前进1米 % 防止车辆位置小于0(已通过路口) lanes.(dir_char).queue = max(lanes.(dir_char).queue, -vehicle_length); end end % 红灯方向车辆不移动,但新生成的车辆会持续加入队列,导致排队长度增长。

步骤3:数据采集。为了给模糊控制器提供输入,并评估控制效果,我们需要实时记录关键数据。

% 在每个时间步记录: metrics(t).time = t; % 1. 排队长度:各方向队列中的车辆数 metrics(t).queue_E = length(lanes.E.queue); metrics(t).queue_S = length(lanes.S.queue); metrics(t).queue_W = length(lanes.W.queue); metrics(t).queue_N = length(lanes.N.queue); % 2. 计算总排队车辆数,作为模糊控制的一个输入 total_queue_EW = metrics(t).queue_E + metrics(t).queue_W; total_queue_NS = metrics(t).queue_S + metrics(t).queue_N; % 3. 记录当前相位和剩余时间 metrics(t).phase = current_phase; metrics(t).phase_remaining = phase_duration(current_phase) - phase_elapsed_time;

通过以上代码,我们就构建了一个能够动态运行、产生交通流数据的十字路口微观仿真模型。这个模型虽然做了简化,但已经包含了车辆随机到达、排队、按信号灯通行等核心动力学过程,为后续的模糊控制提供了可靠的测试环境。

3. 模糊控制器设计:让红绿灯学会“思考”

有了交通流模型,接下来就是为这个路口设计一个“大脑”——模糊控制器。它的任务是根据实时监测到的交通状况(主要是各方向的排队长度),自动决策每个相位的绿灯应该持续多久。我们将使用MATLAB的Fuzzy Logic Toolbox来直观地完成设计。

3.1 确定输入与输出变量

我们的控制器采用一个经典的双输入-单输出结构,简单而有效:

  • 输入1(Input1)Queue_EW。东西方向(East-West)的排队车辆总数。这是一个模糊变量。
  • 输入2(Input2)Queue_NS。南北方向(North-South)的排队车辆总数。同样是一个模糊变量。
  • 输出(Output)Green_Extension。当前绿灯相位的延长时间(秒)。注意,我们控制的是“绿灯延长量”,而不是绝对绿灯时间。我们设定一个最小绿灯时间(例如15秒)保证基本通行,然后由模糊控制器决定在此基础上增加多少秒。

为什么选择排队长度而不是流量?在路口控制中,排队长度直接反映了车辆的延误和路口的拥堵程度,是比瞬时流量更稳定、更能体现累积效应的指标。控制目标就是平衡两个方向的排队长度。

3.2 设计隶属度函数:定义“多”与“少”

模糊化的核心是将精确的输入值(如“东西向有8辆车在排队”)转化为模糊语言值(如“车比较多”)。这需要通过“隶属度函数”来实现。我们为每个输入输出变量定义几个模糊集合。

对于输入Queue_EWQueue_NS,我们定义三个模糊集:Short(短/少),Medium(中),Long(长/多)。它们的论域(取值范围)设定为[0, 20],意味着我们认为排队超过20辆就属于非常严重的拥堵。

% 在MATLAB模糊逻辑设计器中操作,或使用代码创建: fis = mamfis('Name', 'traffic_light_fuzzy'); % 添加输入变量 Queue_EW fis = addInput(fis, [0 20], 'Name', 'Queue_EW'); fis = addMF(fis, 'Queue_EW', 'trapmf', [0 0 5 8], 'Name', 'Short'); fis = addMF(fis, 'Queue_EW', 'trimf', [5 10 15], 'Name', 'Medium'); fis = addMF(fis, 'Queue_EW', 'trapmf', [12 15 20 20], 'Name', 'Long'); % 添加输入变量 Queue_NS (隶属度函数参数相同) fis = addInput(fis, [0 20], 'Name', 'Queue_NS'); fis = addMF(fis, 'Queue_NS', 'trapmf', [0 0 5 8], 'Name', 'Short'); fis = addMF(fis, 'Queue_NS', 'trimf', [5 10 15], 'Name', 'Medium'); fis = addMF(fis, 'Queue_NS', 'trapmf', [12 15 20 20], 'Name', 'Long');

对于输出Green_Extension,我们定义五个模糊集:VS(很短),S(短),M(中),L(长),VL(很长)。论域设为[0, 60],表示最大可延长60秒。

% 添加输出变量 Green_Extension fis = addOutput(fis, [0 60], 'Name', 'Green_Extension'); fis = addMF(fis, 'Green_Extension', 'trimf', [0 0 15], 'Name', 'VS'); fis = addMF(fis, 'Green_Extension', 'trimf', [5 15 25], 'Name', 'S'); fis = addMF(fis, 'Green_Extension', 'trimf', [15 30 45], 'Name', 'M'); fis = addMF(fis, 'Green_Extension', 'trimf', [25 45 60], 'Name', 'L'); fis = addMF(fis, 'Green_Extension', 'trimf', [45 60 60], 'Name', 'VL');

实操心得:隶属度函数形状和参数需要根据实际路口情况进行标定。梯形(trapmf)和三角形(trimf)函数最常用。初始参数可以凭经验设定,后期通过仿真效果反复调整。例如,如果发现控制器对“中等拥堵”反应不灵敏,可以调整Medium集合的覆盖范围。

3.3 制定模糊规则:模仿交警的决策

规则是模糊控制器的“灵魂”,它用“IF-THEN”语句描述了人类的控制经验。我们的目标是:哪边排队更长、更拥堵,就给哪边更多的绿灯时间。

我们制定9条核心规则,基本覆盖了所有可能的输入组合:

规则编号IF (Queue_EW)AND (Queue_NS)THEN (Green_Extension)解释
1ShortShortVS两边车都少,绿灯延长很短时间,快速切换。
2ShortMediumS南北向中等拥堵,东西向车少,给南北向稍多时间。
3ShortLongM南北向严重拥堵,东西向车少,给南北向较多时间。
4MediumShortS东西向中等拥堵,南北向车少,给东西向稍多时间。
5MediumMediumM两边拥堵程度相当,给中等延长。
6MediumLongL南北向远多于东西向,给南北向长延长。
7LongShortM东西向严重拥堵,南北向车少,给东西向较多时间。
8LongMediumL东西向远多于南北向,给东西向长延长。
9LongLongVL两边都严重拥堵,给予最长的绿灯延长,避免频繁切换损失时间。

在MATLAB中,以字符串数组形式添加这些规则:

ruleList = [ "Queue_EW==Short & Queue_NS==Short => Green_Extension=VS"; "Queue_EW==Short & Queue_NS==Medium => Green_Extension=S"; "Queue_EW==Short & Queue_NS==Long => Green_Extension=M"; "Queue_EW==Medium & Queue_NS==Short => Green_Extension=S"; "Queue_EW==Medium & Queue_NS==Medium => Green_Extension=M"; "Queue_EW==Medium & Queue_NS==Long => Green_Extension=L"; "Queue_EW==Long & Queue_NS==Short => Green_Extension=M"; "Queue_EW==Long & Queue_NS==Medium => Green_Extension=L"; "Queue_EW==Long & Queue_NS==Long => Green_Extension=VL"; ]; fis = addRule(fis, ruleList);

注意事项:规则的数量和精细程度需要权衡。规则太少,控制粗糙;规则太多,可能产生冲突,且调试复杂。通常先制定核心规则,再通过仿真观察控制效果,针对不理想的场景补充或修改规则。例如,如果发现从“长排队”切换到“短排队”时绿灯时间仍然过长,可以增加一条考虑“排队变化率”的规则。

3.4 解模糊化:从模糊建议到精确时间

模糊推理引擎会根据输入值和规则,计算出一个输出模糊集。我们需要通过“解模糊化”方法,将这个模糊的输出集合转换成一个精确的数值(绿灯延长时间)。最常用的方法是重心法

% 在仿真主循环中,每个控制周期(例如每10秒评估一次)调用: current_queue_EW = total_queue_EW; % 从metrics中获取 current_queue_NS = total_queue_NS; % 使用evalfis函数进行模糊推理 green_extension_time = evalfis(fis, [current_queue_EW, current_queue_NS]); % 确保输出在合理范围内 green_extension_time = max(0, min(green_extension_time, 60)); % 计算新的绿灯总时间 min_green_time = 15; % 最小绿灯时间 new_green_duration = min_green_time + green_extension_time;

至此,一个完整的模糊控制器就设计好了。它能够像一位经验丰富的交警一样,“感知”路口的拥堵状况,并“思考”出合理的绿灯时长。

4. MATLAB仿真集成与动态可视化

现在,我们将交通流模型和模糊控制器集成到同一个MATLAB仿真框架中,并实现动态可视化,让整个过程“活”起来。

4.1 仿真主循环逻辑搭建

主循环负责按时间步推进仿真,在每个步长内依次调用:车辆生成更新、模糊控制决策、车辆移动、数据记录和图形刷新。

% 初始化图形窗口 figure('Position', [100, 100, 1200, 800]); subplot(2, 2, [1, 3]); % 左上大图:路口动态 hold on; axis equal; axis([-50, 50, -50, 50]); title('十字路口交通流实时仿真 - 模糊控制'); % 绘制静态路口(省略详细绘图代码) plot([-20, 20], [0, 0], 'k-', 'LineWidth', 3); % 东西路 plot([0, 0], [-20, 20], 'k-', 'LineWidth', 3); % 南北路 % 绘制停止线、信号灯图例等... subplot(2, 2, 2); % 右上图:排队长度实时曲线 queue_plot = plot(1:simulation_time, zeros(1, simulation_time), 'LineWidth', 1.5); legend('EW Queue', 'NS Queue'); xlabel('时间 (秒)'); ylabel('排队车辆数'); title('实时排队长度'); grid on; subplot(2, 2, 4); % 右下图:绿灯时间决策 phase_text = text(0.1, 0.8, sprintf('当前相位: %s\n剩余时间: %.1f 秒', phase_list{current_phase}, phase_duration(current_phase)), 'FontSize', 12); decision_text = text(0.1, 0.5, sprintf('模糊控制器输出:\nEW队列: %d\nNS队列: %d\n绿灯延长: %.1f 秒', 0, 0, 0), 'FontSize', 10); % 初始化记录数组 metrics = struct(); control_interval = 10; % 每10秒调用一次模糊控制器 last_control_time = 0; % ========== 主仿真循环 ========== for t = 1:simulation_time % 1. 车辆生成(调用2.2节函数) generate_vehicles(t, lambda, lanes, lane_length, vehicle_length, safe_gap); % 2. 模糊控制决策(每隔control_interval秒执行一次) if (t - last_control_time) >= control_interval || t == 1 % 获取当前排队长度 current_queue_EW = length(lanes.E.queue) + length(lanes.W.queue); current_queue_NS = length(lanes.S.queue) + length(lanes.N.queue); % 调用模糊推理 green_extension = evalfis(fis, [current_queue_EW, current_queue_NS]); green_extension = max(0, min(green_extension, 60)); % 更新当前相位的绿灯总时间 % 注意:只在当前相位为绿灯时才延长其时间 % 我们采用“感应控制”逻辑:绿灯时间=最小绿灯时间+延长部分 % 每次决策都是重新计算当前绿灯相的剩余时间 new_duration = 15 + green_extension; % 最小15秒 % 如果当前绿灯时间已用完,则切换相位 if phase_duration(current_phase) <= 0 % 切换相位前加入黄灯时间(例如3秒) % 此处简化,在可视化中用颜色区分 current_phase = mod(current_phase, length(phase_list)) + 1; % 为新相位计算绿灯时间(基于另一对方向的排队长度) % 这里需要根据新相位对应的方向重新计算排队长度并调用模糊控制器 % 为简化,假设新相位也获得一个基础时间+模糊延长时间 % 实际应重新评估 phase_duration(current_phase) = new_duration; phase_elapsed_time = 0; else % 延长当前相位的绿灯时间 phase_duration(current_phase) = new_duration; end last_control_time = t; % 更新决策显示 set(decision_text, 'String', sprintf('模糊控制器输出:\nEW队列: %d\nNS队列: %d\n绿灯延长: %.1f 秒', current_queue_EW, current_queue_NS, green_extension)); end % 3. 更新相位计时器 phase_elapsed_time = phase_elapsed_time + dt; % 4. 车辆移动(调用2.2节函数,根据current_phase决定哪些车道通行) move_vehicles(lanes, current_phase, vehicle_length); % 5. 数据记录 metrics(t).queue_EW = length(lanes.E.queue) + length(lanes.W.queue); metrics(t).queue_NS = length(lanes.S.queue) + length(lanes.N.queue); metrics(t).phase = current_phase; metrics(t).green_extension = green_extension; % 6. 动态可视化更新 % 6.1 更新路口车辆位置(用散点图表示车辆) % (省略详细的图形对象更新代码,原理是清除上一帧的车辆点,用新的lanes.queue数据重绘) % 6.2 更新信号灯颜色 % 根据current_phase和phase_elapsed_time判断是绿灯、黄灯还是红灯,并改变对应图形对象的颜色 % 6.3 更新排队长度曲线 set(queue_plot(1), 'YData', [get(queue_plot(1), 'YData') metrics(t).queue_EW]); set(queue_plot(2), 'YData', [get(queue_plot(2), 'YData') metrics(t).queue_NS]); set(queue_plot(1), 'XData', 1:t); set(queue_plot(2), 'XData', 1:t); % 6.4 更新相位信息文本 remaining_time = max(0, phase_duration(current_phase) - phase_elapsed_time); set(phase_text, 'String', sprintf('当前相位: %s\n剩余时间: %.1f 秒', phase_list{current_phase}, remaining_time)); % 7. 暂停一小段时间,使动画可见 pause(0.01); % 控制动画速度 end

4.2 生成与导出仿真操作视频

静态的图形和曲线已经能说明问题,但一个动态的视频演示无疑更具说服力。我们可以利用MATLAB的getframeVideoWriter功能,将整个仿真过程录制下来。

% 在主循环开始前,初始化视频写入对象 video_filename = 'fuzzy_traffic_control_simulation.mp4'; v = VideoWriter(video_filename, 'MPEG-4'); v.FrameRate = 10; % 帧率,根据仿真步长调整,1秒仿真对应10帧 open(v); % 在主循环内部,在完成每一帧的图形绘制后,捕获当前图形窗口作为视频帧 % ... (完成所有图形更新后) drawnow; % 强制刷新图形 frame = getframe(gcf); % 捕获整个图形窗口 writeVideo(v, frame); % 写入视频 % 在主循环结束后,关闭视频文件 close(v); disp(['仿真视频已保存至: ', video_filename]);

踩坑实录:在录制视频时,最容易遇到两个问题。一是帧率设置不当导致视频播放速度过快或过慢。我们的仿真步长dt=1秒,如果FrameRate=1,那么生成的视频就是1:1实时。但为了观看效果,我们通常加速播放,所以设为10。二是图形窗口大小和分辨率。如果窗口在录制过程中被手动调整,会导致视频帧尺寸不一致。务必在仿真开始前用figure('Position', [x, y, width, height])固定窗口大小和位置。

5. 性能分析与对比:模糊控制到底强在哪?

仿真跑完了,视频也生成了,但我们不能只停留在“看热闹”的层面。必须用数据说话,定量地分析模糊控制策略相对于传统定时控制策略的优势。我们选取两个最核心的交通性能指标:平均排队长度总通行车辆数

5.1 评价指标计算

我们在仿真过程中已经记录了每个时间步的排队长度。现在从metrics结构体中提取数据进行分析。

% 提取数据 time_steps = 1:simulation_time; queue_EW = [metrics.queue_EW]; queue_NS = [metrics.queue_NS]; % 1. 计算平均排队长度 avg_queue_EW = mean(queue_EW); avg_queue_NS = mean(queue_NS); avg_queue_total = mean(queue_EW + queue_NS); fprintf('【模糊控制策略】\n'); fprintf('东西向平均排队长度: %.2f 辆\n', avg_queue_EW); fprintf('南北向平均排队长度: %.2f 辆\n', avg_queue_NS); fprintf('路口总平均排队长度: %.2f 辆\n', avg_queue_total); % 2. 计算总通行车辆数(即各车道累计驶离车辆之和) total_departures = lanes.E.departures + lanes.S.departures + lanes.W.departures + lanes.N.departures; fprintf('总通行车辆数: %d 辆\n', total_departures); % 3. (可选)计算车辆平均延误 % 这需要记录每辆车的到达时间和离开时间,模型需稍作复杂化。简化起见,可以用平均排队长度间接反映。

5.2 与传统定时控制策略对比

为了进行公平对比,我们需要在相同的车辆到达序列下,运行两种控制策略。这意味着我们需要在仿真开始时保存随机数生成器的状态,确保两次仿真中车辆到达的时机完全一致。

% 保存随机数种子,确保交通流可复现 rng_seed = rng('shuffle'); % 获取当前随机状态,或使用固定种子如 rng(0) % 第一次运行:模糊控制策略 % (运行上述完整的模糊控制仿真,记录结果) fuzzy_avg_queue = avg_queue_total; fuzzy_throughput = total_departures; % 重置随机数生成器到相同状态 rng(rng_seed); % 第二次运行:定时控制策略 % 修改主循环中的控制部分,将模糊控制器替换为固定时长切换 % 例如:每个相位固定绿灯30秒,黄灯3秒 fixed_green_time = 30; fixed_yellow_time = 3; % ... (运行定时控制仿真,使用相同的车辆生成逻辑) % 记录结果 fixed_avg_queue = ...; % 计算出的总平均排队长度 fixed_throughput = ...; % 计算出的总通行车辆数 % 对比分析 fprintf('\n========== 策略对比 ==========\n'); fprintf(' | 模糊控制 | 定时控制 | 提升/变化\n'); fprintf('平均总排队长度 | %7.2f | %7.2f | %6.2f%%\n', ... fuzzy_avg_queue, fixed_avg_queue, (fixed_avg_queue-fuzzy_avg_queue)/fixed_avg_queue*100); fprintf('总通行车辆数 | %7d | %7d | %6.2f%%\n', ... fuzzy_throughput, fixed_throughput, (fuzzy_throughput-fixed_throughput)/fixed_throughput*100);

5.3 结果解读与控制器调优

运行对比仿真后,你可能会看到类似下面的结果:

【模糊控制策略】 东西向平均排队长度: 4.32 辆 南北向平均排队长度: 3.87 辆 路口总平均排队长度: 8.19 辆 总通行车辆数: 312 辆 ========== 策略对比 ========== | 模糊控制 | 定时控制 | 提升/变化 平均总排队长度 | 8.19 | 12.45 | -34.22% 总通行车辆数 | 312 | 298 | +4.70%

解读

  • 平均排队长度下降34%:这是一个非常显著的改善。意味着在模糊控制下,路口车辆的等待时间更短,拥堵程度大大减轻。
  • 总通行车辆数提升4.7%:在相同的仿真时间内,通过了更多的车辆,说明路口通行效率(吞吐量)提高了。

如果结果不理想(例如模糊控制效果甚至不如定时控制),就需要回头审视我们的控制器设计:

  1. 检查隶属度函数Short,Medium,Long的划分是否合理?对于你的交通流量水平,排队5辆车算“少”还是“中”?可能需要调整隶属度函数的交叉点。
  2. 检查模糊规则:规则是否覆盖了所有重要场景?规则结论(THEN部分)的力度是否合适?例如,当Queue_EWLongQueue_NSShort时,给出的Green_Extension=M是否足够长?可以尝试将结论改为L
  3. 调整控制周期:我们每10秒做一次决策是否太快或太慢?决策太频繁可能导致信号灯频繁切换,损失绿灯时间;决策间隔太长则反应迟钝。可以尝试调整为5秒或15秒。
  4. 引入更多输入变量:除了当前排队长度,是否可以加入“排队长度变化率”(即车辆到达的紧迫程度)作为输入,让控制器更具预见性?

这个过程就是控制器的“调参”和“优化”,也是工程实践中最花时间、最考验经验的部分。通过反复仿真-分析-调整,最终让模糊控制器发挥出最佳性能。

这个从零搭建的MATLAB模糊控制交通仿真项目,不仅让你掌握了模糊逻辑工具箱的使用,更深入理解了如何将一个智能控制想法,通过建模、设计、集成、验证的完整流程实现出来。生成的代码和视频,就是最好的学习和演示材料。你可以在此基础上继续扩展,比如加入左转相位、考虑行人过街、或者尝试更先进的控制算法(如模糊PID、强化学习),探索智能交通的更多可能性。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 4:21:32

办公软件自学路线:Excel函数、数据分析与Word排版实战

Excel、Word、Excel函数、数据分析是办公软件自学里出现频率最高的一组词。很多人把它们当成四门独立课程来学&#xff0c;结果往往是快捷键背了不少&#xff0c;遇到真实表格和长文档仍然不知道从哪里下手。更实用的做法是沿着一条工作流去练&#xff1a;先用 Excel 把原始数据…

作者头像 李华
网站建设 2026/9/4 4:21:26

从A卡换N卡性能提升与主板M.2 SSD散热全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 4:20:26

从DEM与SHP数据获取到地形分析:以广西梧州为例的GIS实战指南

简介&#xff1a;本资源为广西梧州市高精度数字高程模型&#xff08;DEM&#xff09;地理信息数据集&#xff0c;面向GIS初学者、城乡规划从业者、环境与灾害研究者及测绘相关专业师生&#xff0c;用于地形分析、坡度坡向计算、视线通视评估、流域水文模拟等空间分析任务。压缩…

作者头像 李华
网站建设 2026/9/4 4:19:21

SpringBoot+Vue网上图书商城项目实战:从架构设计到部署上线

简介&#xff1a;这是一套面向Java初学者与毕业设计学生的全栈图书商城实战项目&#xff0c;基于SpringBootVueMySQL技术栈构建&#xff0c;覆盖前后端分离开发全流程。资源包含845个文件&#xff0c;总计33.18MB&#xff0c;其中139个Java类实现后端业务逻辑与REST接口&#x…

作者头像 李华
网站建设 2026/9/4 4:18:35

文科生零代码入门:用AI编程助手Codex自动化数据处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华