

一句话介绍: 这套程序用改进遗传算法自动搜索 4 个交通信号相位的绿灯时间,在固定信号周期和各相位时间约束下,以降低交叉口车辆延误为目标,自动寻找更合适的信号配时方案。
交叉口的信号灯不能简单 平均分时间。
如果某个方向车流量很大,但绿灯时间太短,就容易形成排队;反过来,如果车流较少的方向占用过多绿灯时间,又会浪费整个信号周期。
这套程序要解决的就是:
在一个固定信号周期内,4 个相位的绿灯时间应该怎样分配,才能让总体车辆延误尽量小?
程序的整体思路是:
交通流量 + 饱和流量 → 随机生成多组绿灯配时 → 计算每组方案的车辆延误 → 选择 / 交叉 / 变异 → 不断改进 → 输出较优 4 相位配时
1. 这个程序真正优化什么?
源码中设置:信号周期 C = 140 s、总损失时间 L = 10 s
因此每个周期真正能够分配给 4 个相位的有效绿灯时间为:140 - 10 = 130 s
程序直接优化前三个相位:t₁、t₂、t₃
第四个相位由总周期自动得到:t₄ = 130 - t₁ - t₂ - t₃
这样可以天然保证 4 个相位总有效绿灯时间始终等于 130 s。
2. 当前 4 个相位允许的绿灯范围
源码给出了前三个相位的取值范围,同时 test.m 对第四相位也进行了限制。
相位 | 允许绿灯时间 |
|---|---|
相位 1 | 38~59 s |
相位 2 | 26~37 s |
相位 3 | 33~44 s |
相位 4 | 22~33 s |
因此遗传算法不能随意给出一个绿灯时间,而必须满足这些边界条件。
例如:[49, 26, 33, 22] s
就是一个合法方案,因为:49 + 26 + 33 + 22 = 130 s
3. 程序使用了什么交通数据?
data.mat 中保存了两个 4×2 矩阵:
q:交通流量、xij:源码注释中的饱和流量
当前数据如下。
相位 | 两股交通流量 q / veh·h⁻¹ | 两股饱和流量 xij / veh·h⁻¹ |
相位 1 | 368,462 | 2000,2000 |
相位 2 | 152,121 | 960,960 |
相位 3 | 311,360 | 1800,1800 |
相位 4 | 128,115 | 960,960 |
从总流量看:
相位 1:830 veh/h、相位 2:273 veh/h、相位 3:671 veh/h、相位 4:243 veh/h
可以看到,相位 1 和相位 3 的交通需求明显更高。
程序会根据这些数据评价不同绿灯分配方案造成的延误大小。
4. 一条遗传算法染色体代表什么?
当前程序采用实数编码,每条染色体只有 3 个变量:X = [t₁, t₂, t₃]
第四个相位不单独编码,而是自动计算:t₄ = 130 - t₁ - t₂ - t₃
相比把绿灯时间转成很长的二进制串,这种实数编码更直接:
染色体里的数值本身就是绿灯秒数。
例如某条个体:X = [48.5, 27.2, 33.7]
就表示前三个相位分别使用这些绿灯时间,第四相位自动由剩余时间得到。
5. 程序怎样判断一个配时方案好不好?
fun.m 是整个优化的核心评价函数。
对第 i 个相位,程序先计算绿信比:
λᵢ = tᵢ / C
也就是:
当前相位绿灯时间占整个 140 s 信号周期的比例。
随后结合交通流量 q 和 xij 计算车辆延误,并把 4 个相位、每个相位两股交通流的延误全部累加。
源码中的单股交通流计算形式可以写成:
d = C(1-λ)² / [2(1-λx)] + x² / [2q(1-x)]
程序最终使用:D = Σ(q × d)作为优化目标。
因此:
D 越小,说明当前绿灯分配带来的总体延误越小。
遗传算法就是在不断寻找更小的 D。
6. 为什么要把总延误再换成平均延误?
程序最终还计算:E = D / Σq
其中 Σq 是所有交通流量之和。
当前总交通量为:Σq = 2017 veh/h
这样得到的 E 可以理解成程序用于表示单车平均延误的指标。
相比只看总延误,平均延误更容易理解:
平均每辆车因为信号控制需要等待多长时间。
7. IGA 中的“改进”主要体现在哪里?
这个程序不是最基础的固定参数遗传算法。
它主要加入了:
自适应交叉概率、自适应变异概率、可行性检查、较优个体保留
所以更准确地说:
IGA = Improved Genetic Algorithm,改进遗传算法。
8. 初始种群是怎么来的?
主程序设置:
参数 | 当前值 |
种群规模 | 50 |
最大迭代代数 | 50 |
初始交叉率参数 | 0.7 |
初始变异率参数 | 0.01 |
每生成一组以后,都会调用 test.m 检查:
t₁、t₂、t₃ 是否在各自范围内;自动计算得到的 t₄ 是否在 22~33 s。
只有满足全部条件的个体才能进入初始种群。
这意味着:算法从一开始搜索的就是可行绿灯配时,而不是先生成大量非法方案再处罚。
9. 选择操作怎样保留更好的方案?
当前问题是最小化延误,所以:fun(X) 越小越好
Select.m 先计算:Fᵢ = 1 / Dᵢ
然后得到轮盘赌概率:Pᵢ = Fᵢ / ΣF
因此延误 D 较小的方案会拥有较大的选择概率。
可以简单理解成:
等待时间更短的配时方案,更容易成为下一代方案的“父代”。
但程序并不是只 复 制第一名,因此还能保留一定种群多样性。
10. 交叉操作怎样产生新的绿灯方案?
程序会随机选择两个配时方案,再随机选取 t₁、t₂、t₃ 中的一个位置进行实数交叉。
假设两个父代在某个相位上的时间分别为:v₁ 和 v₂
程序生成随机数 r,然后形成:
v₁' = r·v₂ + (1-r)·v₁
v₂' = r·v₁ + (1-r)·v₂
也就是说:新方案不是简单交换两个数,而是在两个父代时间之间进行连续插值。
这非常适合绿灯时间这类连续变量。
交叉完成后,程序还会重新检查 t₄ 和所有上下界。如果不满足约束,就重新交叉。
11. 自适应交叉概率是什么意思?
Cross.m 不会始终使用固定交叉率。
它会根据个体延误与种群平均水平重新计算当前交叉概率。
源码使用两组常数:k₁ = 0.6,k₂ = 0.7
设计目的可以理解为:
根据当前个体表现动态改变交叉强度,而不是 50 代始终用同一个概率。
这也是程序相对于普通固定参数 GA 的主要改进之一。
不过当前实现对“最小化问题”的适应度方向处理存在一个值得注意的问题,后文会说明。
12. 变异怎样扩大搜索范围?
如果种群只进行选择和交叉,很多个体会逐渐变得相似。
程序通过变异随机改变某个绿灯时间。
变异形式可以概括成:
新值 = 当前值 + 向上界或下界移动一段随机距离
这样可以产生父代中没有出现过的新配时。
源码还设置:k₃ = 0.001,k₄ = 0.01
用于自适应调整变异概率。
因此变异的主要作用是:
在搜索趋于集中时继续产生新方案,降低算法过早停在局部最优附近的风险。
13. 为什么还需要可行性检查?
遗传操作很容易产生这样的结果:前三相位本身都合法;
但前三相位之和太大;导致 t₄ 小于 22 s。或者:t₄ 大于 33 s。
所以 test.m 每次都会计算:
t₄ = 130 - t₁ - t₂ - t₃
再同时检查 4 个相位范围。
这保证了最终算法不会为了降低某些方向的延误而把另一个相位的绿灯时间压缩到不允许的范围。
14. 为什么遗传算法适合信号配时?
如果只增加相位 1 的绿灯时间,就一定会压缩其他相位可以使用的时间。
所以不能单独优化一个相位。
遗传算法直接把:[t₁,t₂,t₃]
作为一个整体方案搜索,更适合处理这种变量互相制约的问题。
程序只需要做到:给出一组配时 → 调用 fun → 算出延误。
遗传算法并不要求先把延误函数完整求导,因此很适合这种带约束的非线性优化问题。
50 个个体代表 50 种不同绿灯分配方案。
相比只从一个初始方案往附近搜索,种群方法更容易同时探索多个区域。
绿灯时间本来就是连续数值。
程序直接用实数染色体优化秒数,不需要额外二进制解码,表达更自然。
15. 为什么不直接按车流量比例分绿灯时间?
一个很直观的办法是:哪个相位流量大,就按流量比例多分一些时间。
但这种方法只考虑交通流量大小,并没有直接考虑:
饱和流量;信号周期;绿信比;各相位上下限;延误公式本身的非线性。
IGA 的思路是:
不是先规定“时间必须与流量成比例”,而是直接用最终延误作为评价标准,让算法自己搜索。
所以它优化的是实际目标函数,而不仅是一条简单经验比例。
16. 当前数据下,较优配时大约是多少?
根据 fun.m 的实际目标函数和全部时间约束,对连续变量进行独立数值核对,可以得到一组最优配时约为:
t₁ = 49 s、t₂ = 26 s、t₃ = 33 s、t₄ = 22 s
总和为:49 + 26 + 33 + 22 = 130 s
对应源码目标函数:D ≈ 25.699
按照主程序中的平均延误计算:E ≈ 45.87 s/车
这组结果也符合当前交通量分布:
流量最大的相位 1 获得 49 s;
相位 2、3、4 分别落在当前约束允许的较低区间;
第四相位达到下限 22 s。
需要注意:遗传算法具有随机性,而且当前源码还有若干实现细节会影响历史最优记录,因此每次运行未必都严格输出这一组数值。
17. 程序最终能够得到什么?
运行结束后,主程序会输出:
最佳染色体 bestchrom、4 个相位最终绿灯时间、延误目标值 D、平均延误 E
遗传搜索过程中记录的最优指标
因此用户最终真正关心的结果可以概括成:4 个相位各亮多少秒绿灯,以及这套配时对应的车辆延误水平。
18. 它适合用在哪里?
当前程序已经固定为 4 个相位,非常适合研究一个完整信号周期内的绿灯分配问题。
可以直观看到:
编码 → 适应度 → 选择 → 交叉 → 变异 → 最优配时
如何对应实际交通信号优化。
只要修改 data.mat 中的 q,就可以研究高峰、平峰等不同交通流量条件下绿灯时间如何变化。
把自适应交叉、变异改回固定概率以后,可以比较改进遗传算法是否改善搜索效果。
19. 怎么运行?
保持 ysw2.m、Code.m、Select.m、Cross.m、Mutation.m、test.m、fun.m 和 data.mat 在同一 MATLAB 路径下;
运行 ysw2.m;
程序自动读取交通流量和饱和流量;
自动生成 50 个初始配时方案;
进行 50 代遗传搜索;
输出最终 4 相位绿灯时间和延误指标。
工程还包含 ysw2.asv,它只是 MATLAB 自动保存文件,不是正式主程序。
20. 哪些参数最值得修改?
参数 | 当前值 | 主要作用 |
| 140 s | 信号周期 |
| 10 s | 总损失时间 |
| 50 | 种群规模 |
| 50 | 遗传代数 |
| 0.7 | 初始交叉率参数 |
| 0.01 | 初始变异率参数 |
| 三组范围 | t₁、t₂、t₃ 允许范围 |
t₄ 范围 | 22~33 s | 第四相位约束 |
如果研究交通控制本身,最值得修改的是:
信号周期;各相位时间范围;q 交通流量;xij 数据。
如果研究遗传算法,则可以修改:种群大小;迭代次数;交叉/变异参数。
21. 一句话看懂这个项目
这是一个 MATLAB 改进遗传算法交通信号配时程序:它把前三个相位绿灯时间 [t₁,t₂,t₃] 作为实数染色体,第四相位由 130 s 有效绿灯总时间自动得到,再根据 4×2 交通流量与fun.m **中的延误模型评价每组方案,通过轮盘赌选择、自适应交叉、自适应变异和较优个体保留不断搜索更小车辆延误。当前数据和源码目标函数下,独立数值核对得到的较优 4 相位配时约为 [49, 26, 33, 22] s,对应平均延误约 45.87 s/车。