直接修改在下列代码中%% 交通信号协同优化模型 - 遗传算法实现(修正版)
clear; clc; close all;
%% 输入数据(根据附件1)
% 经中路交叉口距离(环北路 - 纬一路 - 纬中路 - 环南路)
distances_jing = [520, 510, 710]; % 3个路段距离
% 纬中路交叉口距离(环西路-经一路-经二路-经三路-经中路-景区出入口-经四路-经五路-环东路)
distances_wei = [460, 340, 440, 420, 530, 560, 430, 270]; % 8个路段距离
% 交叉口数量
num_jing = length(distances_jing) + 1; % 经中路4个交叉口
num_wei = length(distances_wei) + 1; % 纬中路9个交叉口
% 交通流量数据(假设值,实际应用需替换为真实数据)
flow_main_jing = [850, 880, 920, 810]; % 经中路主路流量(辆/小时)
flow_side_jing = [310, 290, 330, 300]; % 经中路支路流量
flow_main_wei = [930, 870, 890, 910, 840, 900, 860, 880, 850]; % 纬中路主路流量
flow_side_wei = [320, 280, 310, 290, 340, 300, 320, 310, 330]; % 纬中路支路流量
% 公共参数
sat_flow = 1800; % 饱和流率(辆/小时/车道)
v_free = 50; % 自由流速度(km/h)
v_free_ms = v_free * 1000 / 3600; % 转换为m/s
y_time = 3; % 黄灯时间(秒)
ar_time = 2; % 全红时间(秒)
g_min = 15; % 最小绿灯时间(秒)
%% 遗传算法参数设置
pop_size = 100; % 种群大小
max_generations = 200; % 最大迭代次数
mutation_rate = 0.1; % 变异率
crossover_rate = 0.8; % 交叉率
% 变量边界
C_min = 80; % 最小周期
C_max = 150; % 最大周期
g_max_ratio = 0.7; % 绿灯时间最大比例
% 变量总数 = 1(周期) + 4(经中绿灯) + 3(经中相位差) + 9(纬中绿灯) + 8(纬中相位差)
num_vars = 1 + num_jing + (num_jing-1) + num_wei + (num_wei-1);
% 初始化种群
population = zeros(pop_size, num_vars);
fitness = zeros(pop_size, 1);
% 创建初始种群
for i = 1:pop_size
% 随机周期
C = randi([C_min, C_max]);
% 经中路绿灯时间
green_jing = randi([g_min, floor(g_max_ratio*C)], 1, num_jing);
% 经中路相位差
offsets_jing = randi([0, C], 1, num_jing-1);
% 纬中路绿灯时间
green_wei = randi([g_min, floor(g_max_ratio*C)], 1, num_wei);
% 纬中路相位差
offsets_wei = randi([0, C], 1, num_wei-1);
population(i, :) = [C, green_jing, offsets_jing, green_wei, offsets_wei];
end
%% 遗传算法主循环
best_fitness = -inf;
best_solution = [];
fitness_history = zeros(max_generations, 1);
for gen = 1:max_generations
% 评估种群适应度
for i = 1:pop_size
fitness(i) = evaluate_fitness(population(i, :), distances_jing, distances_wei, ...
flow_main_jing, flow_side_jing, flow_main_wei, flow_side_wei, ...
sat_flow, v_free_ms, g_min, g_max_ratio);
end
% 记录最佳适应度
[max_fit, idx] = max(fitness);
fitness_history(gen) = max_fit;
if max_fit > best_fitness
best_fitness = max_fit;
best_solution = population(idx, :);
fprintf('Generation %d: Best Fitness = %.4f\n', gen, best_fitness);
end
% 选择操作(锦标赛选择)
new_population = zeros(size(population));
for i = 1:pop_size
% 随机选择两个个体
candidates = randperm(pop_size, 2);
if fitness(candidates(1)) > fitness(candidates(2))
winner = population(candidates(1), :);
else
winner = population(candidates(2), :);
end
new_population(i, :) = winner;
end
% 交叉操作
for i = 1:2:pop_size-1
if rand < crossover_rate
% 选择交叉点
cross_point = randi([2, num_vars-1]);
% 执行交叉
parent1 = new_population(i, :);
parent2 = new_population(i+1, :);
child1 = [parent1(1:cross_point), parent2(cross_point+1:end)];
child2 = [parent2(1:cross_point), parent1(cross_point+1:end)];
new_population(i, :) = child1;
new_population(i+1, :) = child2;
end
end
% 变异操作
for i = 1:pop_size
if rand < mutation_rate
% 随机选择变异点
mut_point = randi([1, num_vars]);
if mut_point == 1
% 变异周期
new_population(i, mut_point) = randi([C_min, C_max]);
elseif mut_point <= 1 + num_jing
% 变异经中路绿灯时间
C = new_population(i, 1);
new_population(i, mut_point) = randi([g_min, floor(g_max_ratio*C)]);
elseif mut_point <= 1 + num_jing + (num_jing-1)
% 变异经中路相位差
C = new_population(i, 1);
new_population(i, mut_point) = randi([0, C]);
elseif mut_point <= 1 + num_jing + (num_jing-1) + num_wei
% 变异纬中路绿灯时间
C = new_population(i, 1);
new_population(i, mut_point) = randi([g_min, floor(g_max_ratio*C)]);
else
% 变异纬中路相位差
C = new_population(i, 1);
new_population(i, mut_point) = randi([0, C]);
end
end
end
population = new_population;
end
%% 提取最优解
C_opt = round(best_solution(1));
green_jing = round(best_solution(2:1+num_jing));
offsets_jing = round(best_solution(2+num_jing:1+num_jing+num_jing-1));
green_wei = round(best_solution(2+num_jing+num_jing-1:2+num_jing+num_jing-1+num_wei));
offsets_wei = round(best_solution(2+num_jing+num_jing-1+num_wei:end));
% 修正:确保所有向量为行向量
green_jing = green_jing(:).';
offsets_jing = offsets_jing(:).';
green_wei = green_wei(:).';
offsets_wei = offsets_wei(:).';
% 计算绝对相位差
abs_offsets_jing = cumsum([0, offsets_jing]);
abs_offsets_jing = mod(abs_offsets_jing, C_opt); % 确保在周期范围内
abs_offsets_wei = cumsum([0, offsets_wei]);
abs_offsets_wei = mod(abs_offsets_wei, C_opt);
% 修正:确保所有信号时间参数维度一致
yellow_jing = repmat(y_time, 1, num_jing);
all_red_jing = repmat(ar_time, 1, num_jing);
yellow_wei = repmat(y_time, 1, num_wei);
all_red_wei = repmat(ar_time, 1, num_wei);
% 确保为行向量(虽然repmat得到行向量,但为了统一,也转换)
yellow_jing = yellow_jing(:).';
all_red_jing = all_red_jing(:).';
yellow_wei = yellow_wei(:).';
all_red_wei = all_red_wei(:).';
% 计算红灯时间
red_jing = C_opt - green_jing - yellow_jing - all_red_jing;
red_wei = C_opt - green_wei - yellow_wei - all_red_wei;
% 确保红灯时间非负
red_jing(red_jing < 0) = 0;
red_wei(red_wei < 0) = 0;
%% 评价指标计算
% 初始方案(假设固定周期和绿灯时间)
x0_jing = [120, 30*ones(1, num_jing), zeros(1, num_jing-1)];
x0_wei = [120, 30*ones(1, num_wei), zeros(1, num_wei-1)];
% 经中路优化前指标
[avg_speed0_jing, stops0_jing, queue0_jing, sat0_jing, delays0_jing] = evaluate_road(...
x0_jing, num_jing, distances_jing, flow_main_jing, flow_side_jing, sat_flow, v_free_ms);
% 经中路优化后指标
x_opt_jing = [C_opt, green_jing, offsets_jing];
[avg_speed_opt_jing, stops_opt_jing, queue_opt_jing, sat_opt_jing, delays_opt_jing] = evaluate_road(...
x_opt_jing, num_jing, distances_jing, flow_main_jing, flow_side_jing, sat_flow, v_free_ms);
% 纬中路优化前指标
[avg_speed0_wei, stops0_wei, queue0_wei, sat0_wei, delays0_wei] = evaluate_road(...
x0_wei, num_wei, distances_wei, flow_main_wei, flow_side_wei, sat_flow, v_free_ms);
% 纬中路优化后指标
x_opt_wei = [C_opt, green_wei, offsets_wei];
[avg_speed_opt_wei, stops_opt_wei, queue_opt_wei, sat_opt_wei, delays_opt_wei] = evaluate_road(...
x_opt_wei, num_wei, distances_wei, flow_main_wei, flow_side_wei, sat_flow, v_free_ms);
%% 结果输出
fprintf('\n============= 优化结果 =============\n');
fprintf('公共周期: %d 秒\n', C_opt);
fprintf('\n经中路信号配时方案:\n');
jing_table = array2table([green_jing; yellow_jing; red_jing; abs_offsets_jing]', ...
'VariableNames', {'绿灯时长', '黄灯时长', '红灯时长', '绝对相位差'}, ...
'RowNames', {'环北路', '纬一路', '纬中路', '环南路'});
disp(jing_table);
fprintf('\n纬中路信号配时方案:\n');
wei_table = array2table([green_wei; yellow_wei; red_wei; abs_offsets_wei]', ...
'VariableNames', {'绿灯时长', '黄灯时长', '红灯时长', '绝对相位差'}, ...
'RowNames', {'环西路','经一路','经二路','经三路','经中路','景区出入口','经四路','经五路','环东路'});
disp(wei_table);
fprintf('\n============ 评价指标对比 ============\n');
fprintf('%-25s %10s %10s %10s\n', '指标', '优化前', '优化后', '提升率(%)');
fprintf('%-25s %10.2f %10.2f %10.2f\n', '经中路平均速度(km/h)', ...
avg_speed0_jing*3.6, avg_speed_opt_jing*3.6, ...
100*(avg_speed_opt_jing - avg_speed0_jing)/abs(avg_speed0_jing));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '纬中路平均速度(km/h)', ...
avg_speed0_wei*3.6, avg_speed_opt_wei*3.6, ...
100*(avg_speed_opt_wei - avg_speed0_wei)/abs(avg_speed0_wei));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '经中路平均停车次数', ...
mean(stops0_jing), mean(stops_opt_jing), ...
100*(mean(stops0_jing) - mean(stops_opt_jing))/abs(mean(stops0_jing)));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '纬中路平均停车次数', ...
mean(stops0_wei), mean(stops_opt_wei), ...
100*(mean(stops0_wei) - mean(stops_opt_wei))/abs(mean(stops0_wei)));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '经中路平均排队长度', ...
mean(queue0_jing), mean(queue_opt_jing), ...
100*(mean(queue0_jing) - mean(queue_opt_jing))/abs(mean(queue0_jing)));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '纬中路平均排队长度', ...
mean(queue0_wei), mean(queue_opt_wei), ...
100*(mean(queue0_wei) - mean(queue_opt_wei))/abs(mean(queue0_wei)));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '经中路平均饱和度', ...
mean(sat0_jing), mean(sat_opt_jing), ...
100*(mean(sat0_jing) - mean(sat_opt_jing))/abs(mean(sat0_jing)));
fprintf('%-25s %10.2f %10.2f %10.2f\n', '纬中路平均饱和度', ...
mean(sat0_wei), mean(sat_opt_wei), ...
100*(mean(sat0_wei) - mean(sat_opt_wei))/abs(mean(sat0_wei)));
%% 可视化结果
figure('Position', [100, 100, 1400, 800])
% 适应度进化曲线
subplot(2,3,1)
plot(1:max_generations, fitness_history, 'LineWidth', 2)
xlabel('迭代次数')
ylabel('适应度值')
title('遗传算法适应度进化曲线')
grid on
% 经中路相位差可视化
subplot(2,3,2)
plot(1:num_jing, abs_offsets_jing, 'o-', 'LineWidth', 2, 'MarkerSize', 8)
xlabel('交叉口序号')
ylabel('绝对相位差(秒)')
title('经中路协调相位差')
grid on
xticks(1:num_jing)
xticklabels({'环北路', '纬一路', '纬中路', '环南路'})
% 纬中路相位差可视化
subplot(2,3,3)
plot(1:num_wei, abs_offsets_wei, 'o-', 'LineWidth', 2, 'MarkerSize', 8)
xlabel('交叉口序号')
ylabel('绝对相位差(秒)')
title('纬中路协调相位差')
grid on
xticks(1:num_wei)
xticklabels({'环西路','经一路','经二路','经三路','经中路','景区出入口','经四路','经五路','环东路'})
xtickangle(45)
% 经中路绿灯时间分布
subplot(2,3,4)
bar(green_jing)
xlabel('交叉口')
ylabel('绿灯时长(秒)')
title('经中路绿灯时间分配')
grid on
xticklabels({'环北路', '纬一路', '纬中路', '环南路'})
% 纬中路绿灯时间分布
subplot(2,3,5)
bar(green_wei)
xlabel('交叉口')
ylabel('绿灯时长(秒)')
title('纬中路绿灯时间分配')
grid on
xticklabels({'环西路','经一路','经二路','经三路','经中路','景区出入口','经四路','经五路','环东路'})
xtickangle(45)
% 速度提升对比
subplot(2,3,6)
speed_data = [avg_speed0_jing*3.6, avg_speed_opt_jing*3.6;
avg_speed0_wei*3.6, avg_peed_opt_wei*3.6];
bar(speed_data)
ylabel('平均速度(km/h)')
set(gca, 'XTickLabel', {'经中路', '纬中路'})
legend({'优化前', '优化后'}, 'Location', 'northwest')
title('优化前后平均速度对比')
grid on
%% 适应度函数
function fitness = evaluate_fitness(x, dist_jing, dist_wei, ...
flow_main_jing, flow_side_jing, flow_main_wei, flow_side_wei, ...
sat_flow, v_free, g_min, g_max_ratio)
% 提取变量
C = x(1);
num_jing = length(flow_main_jing);
num_wei = length(flow_main_wei);
green_jing = x(2:1+num_jing);
offsets_jing = x(2+num_jing:1+num_jing+num_jing-1);
green_wei = x(2+num_jing+num_jing-1:2+num_jing+num_jing-1+num_wei);
offsets_wei = x(2+num_jing+num_jing-1+num_wei:end);
% 约束检查
penalty = 0;
% 检查绿灯时间是否在范围内
for i = 1:num_jing
if green_jing(i) < g_min || green_jing(i) > g_max_ratio*C
penalty = penalty + 1000;
end
end
for i = 1:num_wei
if green_wei(i) < g_min || green_wei(i) > g_max_ratio*C
penalty = penalty + 1000;
end
end
% 检查相位差是否在范围内
for i = 1:length(offsets_jing)
if offsets_jing(i) < 0 || offsets_jing(i) > C
penalty = penalty + 500;
end
end
for i = 1:length(offsets_wei)
if offsets_wei(i) < 0 || offsets_wei(i) > C
penalty = penalty + 500;
end
end
% 如果有惩罚,直接返回负值
if penalty > 0
fitness = -penalty;
return;
end
% 评估经中路性能
[avg_speed_jing, ~, ~, ~, ~] = evaluate_road(...
[C, green_jing, offsets_jing], num_jing, dist_jing, ...
flow_main_jing, flow_side_jing, sat_flow, v_free);
% 评估纬中路性能
[avg_speed_wei, ~, ~, ~, ~] = evaluate_road(...
[C, green_wei, offsets_wei], num_wei, dist_wei, ...
flow_main_wei, flow_side_wei, sat_flow, v_free);
% 适应度为两条路平均速度的加权和
fitness = 0.5*avg_speed_jing + 0.5*avg_speed_wei;
end
%% 单条道路性能评估
function [avg_speed, stops, queue, sat, delays] = evaluate_road(...
x, num_intersections, distances, flow_main, flow_side, sat_flow, v_free)
% 提取参数
C = x(1);
green_times = x(2:1+num_intersections);
offsets = x(2+num_intersections:end);
% 计算绝对相位差(相对于第一个交叉口)
abs_offsets = cumsum([0, offsets]);
abs_offsets = mod(abs_offsets, C);
% 初始化性能指标
stops = zeros(1, num_intersections);
queue = zeros(1, num_intersections);
sat = zeros(1, num_intersections);
delays = zeros(1, num_intersections);
% 计算各交叉口性能指标
for i = 1:num_intersections
% 计算饱和度
capacity = sat_flow * green_times(i) / C;
sat(i) = (flow_main(i) + flow_side(i)) / capacity;
% 计算延误 (Webster公式)
lambda = green_times(i) / C;
x_val = sat(i);
if x_val < 1
d_uniform = (C * (1 - lambda)^2) / (2 * (1 - lambda * x_val));
d_random = (x_val^2) / (2 * flow_main(i) * (1 - x_val));
delays(i) = d_uniform + d_random;
else
delays(i) = C; % 饱和状态下取周期时长作为延误
end
% 计算排队长度 (近似)
red_time = C - green_times(i);
queue(i) = (flow_main(i)/3600) * red_time;
% 计算停车次数 (近似)
stops(i) = (flow_main(i)/3600) * red_time * 0.8; % 80%车辆停车
end
% 计算干线平均速度
total_distance = sum(distances);
% 计算代表车通过所有交叉口的总时间
total_time = 0;
arrival_time = 0;
for i = 1:num_intersections
% 到达当前交叉口的时间
t_arrival = mod(arrival_time, C);
% 计算在当前交叉口的延误
green_start = abs_offsets(i);
green_end = green_start + green_times(i);
if t_arrival >= green_start && t_arrival <= green_end
% 绿灯期间到达,无延误
delay_i = 0;
elseif t_arrival < green_start
% 红灯期间到达,等待绿灯开始
delay_i = green_start - t_arrival;
else
% 到达时绿灯已结束,等待下一周期
delay_i = C - t_arrival + green_start;
end
% 累计时间
total_time = total_time + delay_i;
% 如果不是最后一个交叉口,添加路段行驶时间
if i < num_intersections
travel_time = distances(i) / v_free;
total_time = total_time + travel_time;
arrival_time = arrival_time + delay_i + travel_time;
end
end
% 计算平均速度 (m/s)
avg_speed = total_distance / total_time;
end