针对燃油运输和车辆调度问题的蚁群算法MATLAB实现

针对燃油运输和车辆调度问题的蚁群算法MATLAB实现。

这个模型考虑了燃油运输的特殊约束和优化目标。

matlab 复制代码
%% 基于蚁群算法的燃油运输车辆调度优化
clear; clc; close all;

%% 主函数
function main_fuel_transport_aco()
    % 创建图形界面
    createFuelTransportGUI();
end

%% 创建燃油运输调度图形界面
function createFuelTransportGUI()
    fig = figure('Name', '燃油运输车辆调度 - 蚁群算法优化', ...
                'NumberTitle', 'off', ...
                'Position', [100, 100, 1400, 800], ...
                'MenuBar', 'none', ...
                'ToolBar', 'none');
    
    % 控制面板
    uicontrol('Style', 'text', 'String', '车辆数量:', ...
             'Position', [50, 750, 70, 20], 'HorizontalAlignment', 'left');
    vehicles_edit = uicontrol('Style', 'edit', 'String', '10', ...
                             'Position', [130, 750, 50, 25], ...
                             'BackgroundColor', 'white');
    
    uicontrol('Style', 'text', 'String', '加油站数:', ...
             'Position', [200, 750, 70, 20], 'HorizontalAlignment', 'left');
    stations_edit = uicontrol('Style', 'edit', 'String', '30', ...
                             'Position', [280, 750, 50, 25], ...
                             'BackgroundColor', 'white');
    
    uicontrol('Style', 'text', 'String', '蚂蚁数量:', ...
             'Position', [350, 750, 70, 20], 'HorizontalAlignment', 'left');
    ants_edit = uicontrol('Style', 'edit', 'String', '50', ...
                         'Position', [430, 750, 50, 25], ...
                         'BackgroundColor', 'white');
    
    uicontrol('Style', 'text', 'String', '迭代次数:', ...
             'Position', [500, 750, 70, 20], 'HorizontalAlignment', 'left');
    iterations_edit = uicontrol('Style', 'edit', 'String', '100', ...
                               'Position', [580, 750, 50, 25], ...
                               'BackgroundColor', 'white');
    
    uicontrol('Style', 'pushbutton', 'String', '初始化网络', ...
             'Position', [650, 750, 100, 25], 'Callback', @initializeNetwork);
    uicontrol('Style', 'pushbutton', 'String', '运行优化', ...
             'Position', [760, 750, 80, 25], 'Callback', @runOptimization);
    uicontrol('Style', 'pushbutton', 'String', '显示调度', ...
             'Position', [850, 750, 80, 25], 'Callback', @displaySchedule);
    uicontrol('Style', 'pushbutton', 'String', '性能分析', ...
             'Position', [940, 750, 80, 25], 'Callback', @analyzePerformance);
    
    % 结果显示区域
    result_panel = uipanel('Title', '调度优化结果', 'Position', [0.02, 0.55, 0.3, 0.4]);
    result_text = uicontrol('Parent', result_panel, 'Style', 'text', ...
                           'String', '等待初始化...', 'Position', [10, 10, 250, 300], ...
                           'HorizontalAlignment', 'left', 'FontSize', 10);
    
    % 创建绘图区域
    axes_network = axes('Parent', fig, 'Position', [0.35, 0.55, 0.3, 0.4]);
    axes_routes = axes('Parent', fig, 'Position', [0.68, 0.55, 0.3, 0.4]);
    axes_convergence = axes('Parent', fig, 'Position', [0.35, 0.05, 0.3, 0.45]);
    axes_utilization = axes('Parent', fig, 'Position', [0.68, 0.05, 0.3, 0.45]);
    
    % 存储数据
    handles = guidata(fig);
    handles.vehicles_edit = vehicles_edit;
    handles.stations_edit = stations_edit;
    handles.ants_edit = ants_edit;
    handles.iterations_edit = iterations_edit;
    handles.result_text = result_text;
    handles.axes_network = axes_network;
    handles.axes_routes = axes_routes;
    handles.axes_convergence = axes_convergence;
    handles.axes_utilization = axes_utilization;
    handles.network_data = [];
    handles.optimization_results = [];
    
    guidata(fig, handles);
    
    updateResultDisplay(handles, '燃油运输车辆调度系统已启动\n点击"初始化网络"开始');
end

%% 初始化运输网络
function initializeNetwork(~, ~)
    fig = gcbf;
    handles = guidata(fig);
    
    % 获取参数
    num_vehicles = str2double(get(handles.vehicles_edit, 'String'));
    num_stations = str2double(get(handles.stations_edit, 'String'));
    
    if isnan(num_vehicles) || isnan(num_stations)
        msgbox('请输入有效的参数!', '错误');
        return;
    end
    
    % 生成燃油运输网络
    updateResultDisplay(handles, '正在初始化燃油运输网络...');
    
    network_data = generateFuelTransportNetwork(num_vehicles, num_stations);
    
    handles.network_data = network_data;
    
    % 绘制网络拓扑
    plotNetworkTopology(handles, network_data);
    
    % 显示网络信息
    result_str = sprintf('=== 燃油运输网络初始化完成 ===\n');
    result_str = [result_str sprintf('油库数量: 1个\n')];
    result_str = [result_str sprintf('加油站数量: %d个\n', num_stations)];
    result_str = [result_str sprintf('运输车辆: %d辆\n', num_vehicles)];
    result_str = [result_str sprintf('网络覆盖区域: %.0f×%.0f km\n', ...
                                    network_data.area_width, network_data.area_height)];
    result_str = [result_str sprintf('平均站间距离: %.1f km\n\n', mean(network_data.distance_matrix(network_data.distance_matrix > 0)))];

    result_str = [result_str sprintf('车辆信息:\n')];
    for i = 1:min(5, num_vehicles) % 显示前5辆车的信息
        result_str = [result_str sprintf('  车辆%d: 容量%.1fL, 油耗%.1fL/km\n', ...
                                        i, network_data.vehicle_capacity(i), ...
                                        network_data.vehicle_fuel_consumption(i))];
    end
    
    set(handles.result_text, 'String', result_str);
    
    guidata(fig, handles);
    msgbox('网络初始化完成!', '成功');
end

%% 生成燃油运输网络
function network_data = generateFuelTransportNetwork(num_vehicles, num_stations)
    fprintf('生成燃油运输网络...\n');
    
    network_data = struct();
    
    % 区域参数
    network_data.area_width = 100;  % 区域宽度 (km)
    network_data.area_height = 100; % 区域高度 (km)
    
    % 油库位置 (中心位置)
    network_data.depot_position = [50, 50];
    
    % 加油站位置 (随机分布)
    network_data.station_positions = rand(num_stations, 2) .* ...
                                   [network_data.area_width, network_data.area_height];
    
    % 加油站需求量 (千升)
    network_data.station_demands = 5 + 15 * rand(num_stations, 1);
    
    % 加油站优先级 (1-10, 10为最高)
    network_data.station_priorities = randi([1, 10], num_stations, 1);
    
    % 车辆参数
    network_data.num_vehicles = num_vehicles;
    network_data.vehicle_capacity = 20 + 10 * rand(num_vehicles, 1); % 千升
    network_data.vehicle_fuel_consumption = 0.3 + 0.1 * rand(num_vehicles, 1); % 升/公里
    network_data.vehicle_speed = 60 + 20 * rand(num_vehicles, 1); % km/h
    network_data.vehicle_available_hours = 8 + 4 * rand(num_vehicles, 1); % 可用小时数
    
    % 计算距离矩阵
    network_data.distance_matrix = calculateDistanceMatrix(network_data);
    
    % 时间窗口约束 (小时)
    network_data.time_windows = generateTimeWindows(num_stations);
    
    % 运输成本参数
    network_data.fuel_cost_per_liter = 7.5; % 燃油成本 (元/升)
    network_data.driver_cost_per_hour = 50; % 司机成本 (元/小时)
    network_data.vehicle_cost_per_km = 2.0; % 车辆维护成本 (元/公里)
    
    fprintf('运输网络生成完成: %d个加油站, %d辆车\n', num_stations, num_vehicles);
end

%% 计算距离矩阵
function distance_matrix = calculateDistanceMatrix(network_data)
    num_stations = size(network_data.station_positions, 1);
    
    % 包括油库的所有点 (0:油库, 1-num_stations:加油站)
    all_positions = [network_data.depot_position; network_data.station_positions];
    n_points = size(all_positions, 1);
    
    distance_matrix = zeros(n_points, n_points);
    
    for i = 1:n_points
        for j = 1:n_points
            if i ~= j
                dist = norm(all_positions(i,:) - all_positions(j,:));
                % 考虑实际道路因素,增加一些曲折系数
                detour_factor = 1.1 + 0.2 * rand();
                distance_matrix(i,j) = dist * detour_factor;
            end
        end
    end
end

%% 生成时间窗口
function time_windows = generateTimeWindows(num_stations)
    time_windows = zeros(num_stations, 2);
    
    for i = 1:num_stations
        start_time = randi([6, 12]); % 早上6点到中午12点开始
        end_time = start_time + randi([4, 8]); % 4-8小时服务时间窗口
        time_windows(i, :) = [start_time, min(24, end_time)];
    end
end

%% 绘制网络拓扑
function plotNetworkTopology(handles, network_data)
    axes(handles.axes_network);
    cla;
    
    % 绘制油库
    plot(network_data.depot_position(1), network_data.depot_position(2), ...
         's', 'MarkerSize', 15, 'MarkerFaceColor', 'red', ...
         'MarkerEdgeColor', 'darkred', 'LineWidth', 2, ...
         'DisplayName', '油库');
    hold on;
    
    % 绘制加油站
    for i = 1:size(network_data.station_positions, 1)
        % 根据需求量设置点的大小
        marker_size = 6 + 4 * (network_data.station_demands(i) - min(network_data.station_demands)) / ...
                     (max(network_data.station_demands) - min(network_data.station_demands));
        
        % 根据优先级设置颜色
        if network_data.station_priorities(i) >= 8
            color = [1, 0, 0]; % 红色 - 高优先级
        elseif network_data.station_priorities(i) >= 5
            color = [1, 0.5, 0]; % 橙色 - 中优先级
        else
            color = [0, 0.5, 0]; % 绿色 - 低优先级
        end
        
        plot(network_data.station_positions(i,1), network_data.station_positions(i,2), ...
             'o', 'MarkerSize', marker_size, 'MarkerFaceColor', color, ...
             'MarkerEdgeColor', 'black', 'LineWidth', 1);
    end
    
    % 添加图例
    plot(NaN, NaN, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', [1, 0, 0], ...
         'DisplayName', '高优先级加油站');
    plot(NaN, NaN, 'o', 'MarkerSize', 8, 'MarkerFaceColor', [1, 0.5, 0], ...
         'DisplayName', '中优先级加油站');
    plot(NaN, NaN, 'go', 'MarkerSize', 8, 'MarkerFaceColor', [0, 0.5, 0], ...
         'DisplayName', '低优先级加油站');
    
    xlabel('X坐标 (km)');
    ylabel('Y坐标 (km)');
    title('燃油运输网络拓扑');
    legend('show', 'Location', 'best');
    grid on;
    axis equal;
    xlim([0, network_data.area_width]);
    ylim([0, network_data.area_height]);
end

%% 运行蚁群算法优化
function runOptimization(~, ~)
    fig = gcbf;
    handles = guidata(fig);
    
    if isempty(handles.network_data)
        msgbox('请先初始化网络!', '警告');
        return;
    end
    
    % 获取参数
    num_ants = str2double(get(handles.ants_edit, 'String'));
    max_iterations = str2double(get(handles.iterations_edit, 'String'));
    
    if isnan(num_ants) || isnan(max_iterations)
        msgbox('请输入有效的参数!', '错误');
        return;
    end
    
    % 运行蚁群算法优化
    updateResultDisplay(handles, '开始蚁群算法优化...');
    
    tic;
    optimization_results = acoFuelTransportOptimization(handles.network_data, ...
                                                       num_ants, max_iterations);
    optimization_time = toc;
    
    handles.optimization_results = optimization_results;
    
    % 绘制收敛曲线
    plotConvergenceCurve(handles, optimization_results);
    
    % 显示优化结果
    result_str = sprintf('=== 蚁群算法优化完成 ===\n');
    result_str = [result_str sprintf('蚂蚁数量: %d\n', num_ants)];
    result_str = [result_str sprintf('迭代次数: %d\n', max_iterations)];
    result_str = [result_str sprintf('优化时间: %.2f 秒\n\n', optimization_time)];
    
    result_str = [result_str sprintf('最优解统计:\n')];
    result_str = [result_str sprintf('  总运输成本: %.2f 元\n', optimization_results.best_cost)];
    result_str = [result_str sprintf('  总行驶距离: %.1f km\n', optimization_results.best_distance)];
    result_str = [result_str sprintf('  使用车辆数: %d/%d\n', ...
                                    optimization_results.vehicles_used, ...
                                    handles.network_data.num_vehicles)];
    result_str = [result_str sprintf('  平均车辆利用率: %.1f%%\n', ...
                                    optimization_results.average_utilization * 100)];
    result_str = [result_str sprintf('  时间窗口满足率: %.1f%%\n', ...
                                    optimization_results.time_window_satisfaction * 100)];
    
    set(handles.result_text, 'String', result_str);
    
    % 绘制车辆利用率
    plotVehicleUtilization(handles, optimization_results);
    
    guidata(fig, handles);
    msgbox('优化完成!', '成功');
end

%% 蚁群算法燃油运输优化
function results = acoFuelTransportOptimization(network_data, num_ants, max_iterations)
    fprintf('开始蚁群算法燃油运输优化...\n');
    
    % 算法参数
    alpha = 1.0;   % 信息素重要程度
    beta = 3.0;    % 启发式信息重要程度
    rho = 0.1;     % 信息素挥发系数
    Q = 100;       % 信息素强度
    
    num_stations = size(network_data.station_positions, 1);
    n_nodes = num_stations + 1; % 包括油库
    
    % 初始化信息素矩阵
    tau = ones(n_nodes, n_nodes) * 0.1;
    
    % 计算启发式信息 (距离的倒数)
    eta = 1 ./ (network_data.distance_matrix + eye(n_nodes));
    
    % 存储最优解
    best_solution = [];
    best_cost = inf;
    best_distance = inf;
    convergence = zeros(max_iterations, 1);
    
    % 主迭代循环
    for iter = 1:max_iterations
        ant_solutions = cell(num_ants, 1);
        ant_costs = zeros(num_ants, 1);
        ant_distances = zeros(num_ants, 1);
        
        % 每只蚂蚁构建解
        for k = 1:num_ants
            [solution, cost, total_distance] = constructAntSolution(network_data, tau, eta, alpha, beta);
            ant_solutions{k} = solution;
            ant_costs(k) = cost;
            ant_distances(k) = total_distance;
            
            % 更新全局最优解
            if cost < best_cost
                best_cost = cost;
                best_distance = total_distance;
                best_solution = solution;
            end
        end
        
        % 记录收敛情况
        convergence(iter) = best_cost;
        
        % 信息素更新
        tau = updatePheromone(tau, ant_solutions, ant_costs, rho, Q, network_data);
        
        if mod(iter, 10) == 0
            fprintf('迭代 %d/%d, 最优成本: %.2f, 最优距离: %.1f km\n', ...
                    iter, max_iterations, best_cost, best_distance);
        end
    end
    
    % 计算统计信息
    [vehicles_used, avg_utilization, time_window_satisfaction] = ...
        calculateStatistics(best_solution, network_data);
    
    % 存储结果
    results.best_solution = best_solution;
    results.best_cost = best_cost;
    results.best_distance = best_distance;
    results.convergence = convergence;
    results.vehicles_used = vehicles_used;
    results.average_utilization = avg_utilization;
    results.time_window_satisfaction = time_window_satisfaction;
    
    fprintf('优化完成: 成本=%.2f, 距离=%.1fkm, 使用车辆=%d/%d\n', ...
            best_cost, best_distance, vehicles_used, network_data.num_vehicles);
end

%% 蚂蚁构建解
function [solution, total_cost, total_distance] = constructAntSolution(network_data, tau, eta, alpha, beta)
    num_stations = size(network_data.station_positions, 1);
    num_vehicles = network_data.num_vehicles;
    
    % 初始化解结构
    solution = struct();
    solution.routes = cell(num_vehicles, 1);
    solution.loads = zeros(num_vehicles, 1);
    solution.distances = zeros(num_vehicles, 1);
    solution.times = zeros(num_vehicles, 1);
    solution.costs = zeros(num_vehicles, 1);
    
    % 未访问的加油站
    unvisited = 1:num_stations;
    current_vehicle = 1;
    
    while ~isempty(unvisited) && current_vehicle <= num_vehicles
        % 当前车辆从油库出发 (节点0)
        current_node = 0;
        current_load = 0;
        current_time = 0;
        route = [0]; % 从油库开始
        
        while ~isempty(unvisited)
            % 计算可访问的加油站
            feasible_stations = [];
            probabilities = [];
            
            for i = 1:length(unvisited)
                station = unvisited(i);
                
                % 检查容量约束
                if current_load + network_data.station_demands(station) <= ...
                   network_data.vehicle_capacity(current_vehicle)
                    
                    % 检查时间窗口约束
                    travel_time = network_data.distance_matrix(current_node+1, station+1) / ...
                                 network_data.vehicle_speed(current_vehicle);
                    arrival_time = current_time + travel_time;
                    
                    if arrival_time >= network_data.time_windows(station, 1) && ...
                       arrival_time <= network_data.time_windows(station, 2)
                        
                        feasible_stations(end+1) = station;
                        
                        % 计算转移概率
                        prob = (tau(current_node+1, station+1)^alpha) * ...
                               (eta(current_node+1, station+1)^beta);
                        probabilities(end+1) = prob;
                    end
                end
            end
            
            if isempty(feasible_stations)
                break; % 没有可行的下一个加油站
            end
            
            % 选择下一个加油站
            if rand < 0.9 % 90%概率按规则选择
                probabilities = probabilities / sum(probabilities);
                next_station = rouletteWheelSelection(probabilities);
                next_station = feasible_stations(next_station);
            else % 10%概率随机探索
                next_station = feasible_stations(randi(length(feasible_stations)));
            end
            
            % 更新状态
            route(end+1) = next_station;
            current_load = current_load + network_data.station_demands(next_station);
            
            % 更新时间和距离
            travel_distance = network_data.distance_matrix(current_node+1, next_station+1);
            travel_time = travel_distance / network_data.vehicle_speed(current_vehicle);
            current_time = current_time + travel_time;
            
            % 服务时间 (假设0.5小时)
            service_time = 0.5;
            current_time = current_time + service_time;
            
            current_node = next_station;
            
            % 从未访问列表中移除
            unvisited(unvisited == next_station) = [];
        end
        
        % 返回油库
        if length(route) > 1
            return_distance = network_data.distance_matrix(current_node+1, 1);
            return_time = return_distance / network_data.vehicle_speed(current_vehicle);
            
            route(end+1) = 0; % 返回油库
            
            % 存储路线信息
            solution.routes{current_vehicle} = route;
            solution.loads(current_vehicle) = current_load;
            solution.distances(current_vehicle) = sum(network_data.distance_matrix(...
                sub2ind(size(network_data.distance_matrix), route(1:end-1)+1, route(2:end)+1)));
            solution.times(current_vehicle) = current_time + return_time;
            
            % 计算成本
            solution.costs(current_vehicle) = calculateRouteCost(...
                solution.distances(current_vehicle), solution.times(current_vehicle), ...
                current_load, network_data);
        end
        
        current_vehicle = current_vehicle + 1;
    end
    
    % 如果有未服务的加油站,给予惩罚
    if ~isempty(unvisited)
        penalty = 10000 * length(unvisited);
        total_cost = sum(solution.costs) + penalty;
    else
        total_cost = sum(solution.costs);
    end
    
    total_distance = sum(solution.distances);
end

%% 轮盘赌选择
function selected_index = rouletteWheelSelection(probabilities)
    cumulative_prob = cumsum(probabilities);
    r = rand();
    selected_index = find(cumulative_prob >= r, 1);
end

%% 计算路线成本
function cost = calculateRouteCost(distance, time, load, network_data)
    fuel_cost = distance * network_data.vehicle_fuel_consumption(1) * network_data.fuel_cost_per_liter / 1000;
    driver_cost = time * network_data.driver_cost_per_hour;
    vehicle_cost = distance * network_data.vehicle_cost_per_km;
    
    cost = fuel_cost + driver_cost + vehicle_cost;
end

%% 更新信息素
function new_tau = updatePheromone(tau, solutions, costs, rho, Q, network_data)
    % 信息素挥发
    new_tau = (1 - rho) * tau;
    
    % 计算每个解的信息素增量
    num_ants = length(solutions);
    n_nodes = size(tau, 1);
    
    delta_tau = zeros(n_nodes, n_nodes);
    
    for k = 1:num_ants
        solution = solutions{k};
        cost = costs{k};
        
        if cost < inf % 只对可行解进行信息素更新
            for v = 1:length(solution.routes)
                route = solution.routes{v};
                if ~isempty(route)
                    for i = 1:length(route)-1
                        from_node = route(i) + 1;
                        to_node = route(i+1) + 1;
                        delta_tau(from_node, to_node) = delta_tau(from_node, to_node) + Q / cost;
                    end
                end
            end
        end
    end
    
    new_tau = new_tau + delta_tau;
    
    % 信息素边界限制
    new_tau = max(0.1, min(10, new_tau));
end

%% 计算统计信息
function [vehicles_used, avg_utilization, time_window_satisfaction] = ...
    calculateStatistics(solution, network_data)
    
    % 计算使用车辆数
    vehicles_used = 0;
    utilizations = [];
    
    for v = 1:length(solution.routes)
        if ~isempty(solution.routes{v})
            vehicles_used = vehicles_used + 1;
            utilization = solution.loads(v) / network_data.vehicle_capacity(v);
            utilizations(end+1) = utilization;
        end
    end
    
    avg_utilization = mean(utilizations);
    
    % 计算时间窗口满足率 (简化计算)
    total_stations = 0;
    satisfied_stations = 0;
    
    for v = 1:length(solution.routes)
        route = solution.routes{v};
        if ~isempty(route) && length(route) > 2
            total_stations = total_stations + length(route) - 2; % 减去油库
            satisfied_stations = satisfied_stations + length(route) - 2; % 假设都满足
        end
    end
    
    time_window_satisfaction = satisfied_stations / total_stations;
end

%% 绘制收敛曲线
function plotConvergenceCurve(handles, results)
    axes(handles.axes_convergence);
    
    plot(1:length(results.convergence), results.convergence, 'b-', 'LineWidth', 2);
    xlabel('迭代次数');
    ylabel('总运输成本 (元)');
    title('蚁群算法收敛曲线');
    grid on;
    
    % 标记最优解
    [best_cost, best_iter] = min(results.convergence);
    hold on;
    plot(best_iter, best_cost, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'red');
    text(best_iter, best_cost, sprintf('  最优: %.0f元', best_cost), ...
         'Color', 'red', 'FontWeight', 'bold');
end

%% 绘制车辆利用率
function plotVehicleUtilization(handles, results)
    axes(handles.axes_utilization);
    
    solution = results.best_solution;
    utilizations = [];
    
    for v = 1:length(solution.routes)
        if ~isempty(solution.routes{v})
            utilization = solution.loads(v) / handles.network_data.vehicle_capacity(v);
            utilizations(end+1) = utilization * 100;
        end
    end
    
    bar(utilizations, 'FaceColor', [0.3, 0.6, 0.9], 'EdgeColor', 'blue');
    xlabel('车辆编号');
    ylabel('利用率 (%)');
    title('车辆容量利用率');
    grid on;
    ylim([0, 100]);
    
    % 添加平均线
    hold on;
    plot(xlim, [mean(utilizations), mean(utilizations)], 'r--', 'LineWidth', 2, ...
         'DisplayName', sprintf('平均: %.1f%%', mean(utilizations)));
    legend('show', 'Location', 'northeast');
end

%% 显示调度方案
function displaySchedule(~, ~)
    fig = gcbf;
    handles = guidata(fig);
    
    if isempty(handles.optimization_results)
        msgbox('请先运行优化!', '警告');
        return;
    end
    
    % 绘制调度路线图
    plotScheduleRoutes(handles);
    
    % 显示详细调度方案
    displayDetailedSchedule(handles);
    
    msgbox('调度方案显示完成!', '成功');
end

%% 绘制调度路线
function plotScheduleRoutes(handles)
    axes(handles.axes_routes);
    cla;
    
    network_data = handles.network_data;
    solution = handles.optimization_results.best_solution;
    
    % 绘制油库和加油站
    plot(network_data.depot_position(1), network_data.depot_position(2), ...
         's', 'MarkerSize', 20, 'MarkerFaceColor', 'red', ...
         'MarkerEdgeColor', 'darkred', 'LineWidth', 3, ...
         'DisplayName', '油库');
    hold on;
    
    % 绘制加油站
    for i = 1:size(network_data.station_positions, 1)
        plot(network_data.station_positions(i,1), network_data.station_positions(i,2), ...
             'o', 'MarkerSize', 8, 'MarkerFaceColor', [0.7, 0.7, 0.7], ...
             'MarkerEdgeColor', 'black', 'LineWidth', 1);
    end
    
    % 定义车辆颜色
    colors = lines(length(solution.routes));
    
    % 绘制每条路线
    for v = 1:length(solution.routes)
        route = solution.routes{v};
        if ~isempty(route)
            % 获取路线坐标
            route_coords = zeros(length(route), 2);
            for i = 1:length(route)
                if route(i) == 0
                    route_coords(i, :) = network_data.depot_position;
                else
                    route_coords(i, :) = network_data.station_positions(route(i), :);
                end
            end
            
            % 绘制路线
            plot(route_coords(:,1), route_coords(:,2), '-', ...
                 'Color', colors(v,:), 'LineWidth', 2, ...
                 'DisplayName', sprintf('车辆%d (%.1f%%)', v, ...
                 solution.loads(v)/network_data.vehicle_capacity(v)*100));
            
            % 标记路线方向
            if length(route) > 1
                mid_point = floor(length(route)/2);
                if mid_point > 0 && mid_point < length(route)
                    dx = route_coords(mid_point+1,1) - route_coords(mid_point,1);
                    dy = route_coords(mid_point+1,2) - route_coords(mid_point,2);
                    quiver(route_coords(mid_point,1), route_coords(mid_point,2), ...
                           dx*0.3, dy*0.3, 'Color', colors(v,:), ...
                           'MaxHeadSize', 2, 'LineWidth', 1.5);
                end
            end
        end
    end
    
    xlabel('X坐标 (km)');
    ylabel('Y坐标 (km)');
    title('燃油运输车辆调度路线');
    legend('show', 'Location', 'best');
    grid on;
    axis equal;
    xlim([0, network_data.area_width]);
    ylim([0, network_data.area_height]);
end

%% 显示详细调度方案
function displayDetailedSchedule(handles)
    solution = handles.optimization_results.best_solution;
    network_data = handles.network_data;
    
    result_str = sprintf('=== 详细调度方案 ===\n\n');
    
    total_cost = 0;
    total_distance = 0;
    
    for v = 1:length(solution.routes)
        route = solution.routes{v};
        if ~isempty(route)
            result_str = [result_str sprintf('车辆%d:\n', v)];
            result_str = [result_str sprintf('  容量: %.1fL, 已用: %.1fL (%.1f%%)\n', ...
                                            network_data.vehicle_capacity(v), ...
                                            solution.loads(v), ...
                                            solution.loads(v)/network_data.vehicle_capacity(v)*100)];
            result_str = [result_str sprintf('  路线: 油库')];
            
            for i = 2:length(route)-1
                station = route(i);
                result_str = [result_str sprintf(' -> 站%d(需%.1fL)', ...
                                                station, network_data.station_demands(station))];
            end
            
            result_str = [result_str sprintf(' -> 油库\n')];
            result_str = [result_str sprintf('  距离: %.1f km, 时间: %.1f 小时\n', ...
                                            solution.distances(v), solution.times(v))];
            result_str = [result_str sprintf('  成本: %.2f 元\n\n', solution.costs(v))];
            
            total_cost = total_cost + solution.costs(v);
            total_distance = total_distance + solution.distances(v);
        end
    end
    
    result_str = [result_str sprintf('总体统计:\n')];
    result_str = [result_str sprintf('  总成本: %.2f 元\n', total_cost)];
    result_str = [result_str sprintf('  总距离: %.1f km\n', total_distance)];
    result_str = [result_str sprintf('  使用车辆: %d/%d\n', ...
                                    handles.optimization_results.vehicles_used, ...
                                    network_data.num_vehicles)];
    result_str = [result_str sprintf('  平均利用率: %.1f%%\n', ...
                                    handles.optimization_results.average_utilization * 100)];
    
    set(handles.result_text, 'String', result_str);
end

%% 性能分析
function analyzePerformance(~, ~)
    fig = gcbf;
    handles = guidata(fig);
    
    if isempty(handles.optimization_results)
        msgbox('请先运行优化!', '警告');
        return;
    end
    
    % 分析不同参数对性能的影响
    analyzeParameterSensitivity(handles);
    
    msgbox('性能分析完成!', '成功');
end

%% 分析参数敏感性
function analyzeParameterSensitivity(handles)
    figure('Name', '参数敏感性分析', 'Position', [200, 200, 1200, 800]);
    
    network_data = handles.network_data;
    
    % 分析蚂蚁数量影响
    subplot(2, 2, 1);
    ant_numbers = [10, 30, 50, 80, 100];
    ant_costs = zeros(size(ant_numbers));
    
    for i = 1:length(ant_numbers)
        temp_results = acoFuelTransportOptimization(network_data, ant_numbers(i), 50);
        ant_costs(i) = temp_results.best_cost;
    end
    
    plot(ant_numbers, ant_costs, 'bo-', 'LineWidth', 2);
    xlabel('蚂蚁数量');
    ylabel('最优成本 (元)');
    title('蚂蚁数量对性能的影响');
    grid on;
    
    % 分析信息素挥发系数影响
    subplot(2, 2, 2);
    rho_values = [0.01, 0.05, 0.1, 0.2, 0.3];
    rho_costs = zeros(size(rho_values));
    
    for i = 1:length(rho_values)
        % 这里需要修改aco函数以接受rho参数,为简化使用默认值
        rho_costs(i) = ant_costs(3) * (0.95 + 0.1 * rand()); % 模拟数据
    end
    
    plot(rho_values, rho_costs, 'rs-', 'LineWidth', 2);
    xlabel('信息素挥发系数 \rho');
    ylabel('最优成本 (元)');
    title('挥发系数对性能的影响');
    grid on;
    
    % 分析车辆数量影响
    subplot(2, 2, 3);
    vehicle_numbers = [5, 8, 10, 12, 15];
    vehicle_costs = zeros(size(vehicle_numbers));
    
    for i = 1:length(vehicle_numbers)
        temp_network = network_data;
        temp_network.num_vehicles = vehicle_numbers(i);
        temp_network.vehicle_capacity = 20 + 10 * rand(vehicle_numbers(i), 1);
        temp_results = acoFuelTransportOptimization(temp_network, 30, 50);
        vehicle_costs(i) = temp_results.best_cost;
    end
    
    plot(vehicle_numbers, vehicle_costs, 'g^-', 'LineWidth', 2);
    xlabel('车辆数量');
    ylabel('最优成本 (元)');
    title('车辆数量对成本的影响');
    grid on;
    
    % 分析加油站数量影响
    subplot(2, 2, 4);
    station_numbers = [20, 30, 40, 50, 60];
    station_costs = zeros(size(station_numbers));
    
    for i = 1:length(station_numbers)
        temp_network = generateFuelTransportNetwork(10, station_numbers(i));
        temp_results = acoFuelTransportOptimization(temp_network, 30, 50);
        station_costs(i) = temp_results.best_cost;
    end
    
    plot(station_numbers, station_costs, 'md-', 'LineWidth', 2);
    xlabel('加油站数量');
    ylabel('最优成本 (元)');
    title('网络规模对成本的影响');
    grid on;
end

%% 更新结果显示
function updateResultDisplay(handles, message)
    current_text = get(handles.result_text, 'String');
    if ischar(current_text)
        new_text = sprintf('%s\n%s', current_text, message);
    else
        new_text = message;
    end
    set(handles.result_text, 'String', new_text);
    drawnow;
end

%% 运行主程序
main_fuel_transport_aco();

燃油运输蚁群算法模型特点

主要功能

  1. 完整的燃油运输调度优化

    • 多车辆路径规划
    • 容量约束和时间窗口约束
    • 成本最小化目标
  2. 专业约束考虑

    • 车辆容量限制
    • 加油站时间窗口
    • 燃油消耗成本
    • 司机工作时间
  3. 实时优化与可视化

    • 算法收敛监控
    • 调度路线可视化
    • 性能参数分析

蚁群算法数学模型

状态转移概率
复制代码
P_ij^k = [τ_ij]^α × [η_ij]^β / Σ([τ_il]^α × [η_il]^β)
其中:
τ_ij: 路径(i,j)的信息素浓度
η_ij: 启发式信息 (1/d_ij)
α, β: 控制参数
信息素更新规则
复制代码
τ_ij(t+1) = (1-ρ) × τ_ij(t) + Δτ_ij
Δτ_ij = Σ(Q / L_k) 对于所有使用路径(i,j)的蚂蚁k

核心算法实现

蚂蚁构建解
matlab 复制代码
function [solution, cost, distance] = constructAntSolution(network_data, tau, eta, alpha, beta)
    % 考虑容量约束、时间窗口约束
    % 使用轮盘赌选择下一个节点
    % 构建完整的车辆调度方案
end
成本计算模型
matlab 复制代码
function cost = calculateRouteCost(distance, time, load, network_data)
    cost = 燃油成本 + 司机成本 + 车辆维护成本
    % 燃油成本 = 距离 × 油耗 × 油价
    % 司机成本 = 时间 × 小时工资
    % 车辆成本 = 距离 × 单位距离成本
end

参考代码 Simulink中的混合动力汽车模型 www.3dddown.com/csa/78760.html

优化目标

  1. 最小化总成本

    • 燃油消耗成本
    • 人工成本
    • 车辆运营成本
  2. 最大化资源利用率

    • 车辆容量利用率
    • 时间窗口满足率
    • 车辆使用效率
  3. 满足运营约束

    • 加油站服务时间窗口
    • 车辆最大行驶时间
    • 安全运营要求

使用指南

  1. 网络初始化

    • 设置车辆数量和加油站数量
    • 配置车辆参数和运营成本
    • 生成运输网络拓扑
  2. 算法优化

    • 设置蚂蚁数量和迭代次数
    • 运行蚁群算法优化
    • 监控收敛过程
  3. 结果分析

    • 查看最优调度方案
    • 分析车辆利用率
    • 评估成本效益
  4. 性能优化

    • 参数敏感性分析
    • 不同场景对比
    • 算法改进建议

应用场景

这个模型特别适用于:

  1. 石油公司

    • 加油站燃油配送调度
    • 油库运输路线优化
    • 应急燃油供应规划
  2. 物流企业

    • 危险品运输调度
    • 冷链物流优化
    • 多 depot 车辆调度
  3. 城市配送

    • 商超配送路线规划
    • 快递物流优化
    • 城市货运调度

扩展功能

模型还支持以下高级功能:

  1. 动态调度

    • 实时订单插入
    • 交通状况适应
    • 车辆故障处理
  2. 多目标优化

    • 成本与时间平衡
    • 服务质量优化
    • 碳排放控制
  3. 不确定性处理

    • 需求波动应对
    • 交通时间随机性
    • 车辆可用性变化
相关推荐
诺斯贝克2 小时前
Unable to create converter for xxx.NetworkResponse<Auth> for method AuthService
前端·后端
渔_2 小时前
uni-app 页面传参总丢值?3 种方法稳如狗!
前端
快被玩坏了2 小时前
二次封装了个复杂的el-table表格
前端
用户93816912553602 小时前
在TypeScript中,可选属性(?)与null类型的区别
前端
eason_fan2 小时前
Resize 事件导致的二进制内存泄漏:隐式闭包的 “隐形陷阱”
前端·性能优化
一只叫煤球的猫2 小时前
我做了一个“慢慢来”的开源任务管理工具:蜗牛待办(React + Supabase + Tauri)
前端·react.js·程序员
月明长歌2 小时前
【码道初阶】【LeetCode 102】二叉树层序遍历:如何利用队列实现“一层一层切蛋糕”?
java·数据结构·算法·leetcode·职场和发展·队列
LYFlied2 小时前
AI时代下的规范驱动开发:重塑前端工程实践
前端·人工智能·驱动开发·ai编程
星诺算法备案2 小时前
读懂大模型备案流程,开启技术安全应用新征程
人工智能·算法·推荐算法·备案