人工鱼群算法求解VRP问题的MATLAB实现

一、算法原理与VRP问题建模

1.1 VRP问题定义

车辆路径问题(Vehicle Routing Problem, VRP)描述为:有m辆车从配送中心出发,服务n个客户点,每个客户有确定的需求量,车辆有容量限制,目标是找到总距离最短的路径方案。

1.2 人工鱼群算法(AFSA)改进

将人工鱼的位置编码为VRP的解,通过鱼的四种行为(觅食、聚群、追尾、随机)优化解的质量。

二、完整MATLAB代码实现

2.1 主程序框架

%% 人工鱼群算法求解VRP问题
clear; clc; close all;

%% 1. 问题参数设置
problem.nCustomers = 31;          % 客户数量(包括配送中心)
problem.capacity = 100;           % 车辆容量
problem.maxVehicles = 5;          % 最大车辆数
problem.demandRange = [5, 25];    % 客户需求范围

%% 2. 算法参数设置
params.fishNum = 50;              % 鱼群规模
params.maxIter = 200;             % 最大迭代次数
params.visual = 0.3;              % 视觉范围(解空间比例)
params.step = 0.2;                % 移动步长
params.delta = 0.6;               % 拥挤度因子
params.tryNumber = 5;             % 尝试次数
params.probRandom = 0.2;          % 随机行为概率

%% 3. 初始化数据
% 生成随机客户坐标和需求
rng(2024); % 固定随机种子,确保可重复性
[customerData, distanceMatrix] = initializeVRPData(problem);

%% 4. 初始化鱼群
fishes = initializeFishSwarm(params, problem, customerData);

%% 5. 主循环 - 人工鱼群算法
bestFish = fishes(1);  % 记录最优鱼(最优解)
bestCostHistory = zeros(params.maxIter, 1);  % 记录历史最优值

for iter = 1:params.maxIter
    fprintf('迭代 %d/%d: ', iter, params.maxIter);
    
    % 每条鱼执行行为
    for i = 1:params.fishNum
        % 随机选择行为(可根据需要调整概率)
        randVal = rand();
        
        if randVal < 0.35
            % 追尾行为
            fishes(i) = followBehavior(fishes, i, params, distanceMatrix, customerData, problem);
        elseif randVal < 0.7
            % 聚群行为
            fishes(i) = swarmBehavior(fishes, i, params, distanceMatrix, customerData, problem);
        else
            % 觅食行为
            fishes(i) = preyBehavior(fishes(i), params, distanceMatrix, customerData, problem);
        end
        
        % 更新最优鱼
        if fishes(i).totalDistance < bestFish.totalDistance
            bestFish = fishes(i);
        end
    end
    
    % 记录当前最优解
    bestCostHistory(iter) = bestFish.totalDistance;
    
    % 动态调整参数(自适应策略)
    params.step = params.step * 0.995;  % 逐渐减小步长
    params.visual = params.visual * 0.997;  % 逐渐减小视野
    
    % 显示当前最优解信息
    fprintf('最优距离: %.2f, 使用车辆数: %d\n', ...
        bestFish.totalDistance, length(bestFish.routes));
    
    % 每隔20代显示一次当前最优路径
    if mod(iter, 20) == 0
        plotSolution(bestFish, customerData, sprintf('第%d代最优解', iter));
    end
end

%% 6. 结果显示
plotFinalResults(bestFish, bestCostHistory, customerData);
printSolutionDetails(bestFish, customerData);

2.2 数据初始化函数

function [customerData, distanceMatrix] = initializeVRPData(problem)
    % 初始化VRP问题数据
    % 生成客户坐标(0号点为配送中心)
    n = problem.nCustomers;
    
    % 使用中国31个城市坐标作为示例(前31个)
    cityCoords = [
        1304, 2312; 3639, 1315; 4177, 2244; 3712, 1399; 3488, 1535;
        3326, 1556; 3238, 1229; 4196, 1004; 4312, 790; 4386, 570;
        3007, 1970; 2562, 1756; 2788, 1491; 2381, 1676; 1332, 695;
        3715, 1678; 3918, 2179; 4061, 2370; 3780, 2212; 3676, 2578;
        4029, 2838; 4263, 2931; 3429, 1908; 3507, 2367; 3394, 2643;
        3439, 3201; 2935, 3240; 3140, 3550; 2545, 2357; 2778, 2826;
        2370, 2975  % 31个城市
    ];
    
    % 取前n个点(如果n>31则复制)
    if n > size(cityCoords, 1)
        cityCoords = repmat(cityCoords, ceil(n/size(cityCoords,1)), 1);
    end
    customerData.coords = cityCoords(1:n, :);
    
    % 生成随机需求(第一个点为配送中心,需求为0)
    customerData.demands = zeros(n, 1);
    customerData.demands(2:end) = randi(problem.demandRange, n-1, 1);
    
    % 计算距离矩阵(欧氏距离)
    distanceMatrix = zeros(n, n);
    for i = 1:n
        for j = 1:n
            if i ~= j
                dx = customerData.coords(i, 1) - customerData.coords(j, 1);
                dy = customerData.coords(i, 2) - customerData.coords(j, 2);
                distanceMatrix(i, j) = sqrt(dx^2 + dy^2);
            end
        end
    end
    
    % 缩放距离到合理范围
    distanceMatrix = distanceMatrix / 100;
end

2.3 人工鱼初始化

function fishes = initializeFishSwarm(params, problem, customerData)
    % 初始化人工鱼群
    n = problem.nCustomers;
    
    fishes(params.fishNum) = struct();  % 预分配
    
    for f = 1:params.fishNum
        % 随机生成路径编码(排列编码)
        perm = randperm(n-1) + 1;  % 不包括配送中心(点1)
        
        % 解码为可行路径(考虑容量约束)
        fish = decodeSolution(perm, customerData, problem, params);
        
        % 计算适应度(总距离)
        fish.totalDistance = calculateTotalDistance(fish.routes, customerData.coords);
        fish.permutation = perm;
        fish.routes = fish.routes;
        fish.vehicleCount = length(fish.routes);
        
        fishes(f) = fish;
    end
end

function fish = decodeSolution(perm, customerData, problem, params)
    % 将排列解码为可行路径(考虑容量约束)
    routes = {};
    currentRoute = [1];  % 起点为配送中心
    currentLoad = 0;
    
    for i = 1:length(perm)
        customerIdx = perm(i);
        demand = customerData.demands(customerIdx);
        
        if currentLoad + demand <= problem.capacity
            % 可以加入当前路径
            currentRoute = [currentRoute, customerIdx];
            currentLoad = currentLoad + demand;
        else
            % 开始新路径
            currentRoute = [currentRoute, 1];  % 返回配送中心
            routes{end+1} = currentRoute;
            
            % 开始新路径
            currentRoute = [1, customerIdx];
            currentLoad = demand;
        end
    end
    
    % 添加最后一条路径
    if length(currentRoute) > 1
        currentRoute = [currentRoute, 1];
        routes{end+1} = currentRoute;
    end
    
    fish.routes = routes;
end

2.4 人工鱼行为实现

function newFish = preyBehavior(fish, params, distanceMatrix, customerData, problem)
    % 觅食行为:尝试移动到更优位置
    bestFish = fish;
    improved = false;
    
    for tryIdx = 1:params.tryNumber
        % 在视野范围内生成新位置
        neighbor = generateNeighbor(fish.permutation, params, distanceMatrix);
        
        % 解码并计算适应度
        newFish = decodeSolution(neighbor, customerData, problem, params);
        newFish.totalDistance = calculateTotalDistance(newFish.routes, customerData.coords);
        newFish.permutation = neighbor;
        newFish.vehicleCount = length(newFish.routes);
        
        if newFish.totalDistance < bestFish.totalDistance
            bestFish = newFish;
            improved = true;
        end
    end
    
    if ~improved
        % 如果没有找到更好的位置,执行随机移动
        newFish = randomBehavior(fish, params, distanceMatrix, customerData, problem);
    else
        newFish = bestFish;
    end
end

function newFish = swarmBehavior(fishes, fishIdx, params, distanceMatrix, customerData, problem)
    % 聚群行为:向中心位置移动
    n = params.fishNum;
    currentFish = fishes(fishIdx);
    
    % 寻找视野内的伙伴
    neighborIndices = [];
    for i = 1:n
        if i ~= fishIdx
            % 计算两条鱼之间的"距离"(解差异度)
            dist = solutionDistance(currentFish.permutation, fishes(i).permutation);
            if dist < params.visual * length(currentFish.permutation)
                neighborIndices = [neighborIndices, i];
            end
        end
    end
    
    if ~isempty(neighborIndices)
        % 计算中心位置
        centerPerm = calculateCenterPosition(fishes(neighborIndices));
        
        % 检查拥挤度
        nf = length(neighborIndices);
        if (nf / n) < params.delta
            % 不拥挤,向中心移动
            newPerm = moveTowardPosition(currentFish.permutation, centerPerm, params.step);
            newFish = decodeSolution(newPerm, customerData, problem, params);
            newFish.totalDistance = calculateTotalDistance(newFish.routes, customerData.coords);
            newFish.permutation = newPerm;
            newFish.vehicleCount = length(newFish.routes);
        else
            % 拥挤,执行觅食行为
            newFish = preyBehavior(currentFish, params, distanceMatrix, customerData, problem);
        end
    else
        % 没有伙伴,执行觅食行为
        newFish = preyBehavior(currentFish, params, distanceMatrix, customerData, problem);
    end
end

function newFish = followBehavior(fishes, fishIdx, params, distanceMatrix, customerData, problem)
    % 追尾行为:向最优邻居移动
    n = params.fishNum;
    currentFish = fishes(fishIdx);
    
    % 寻找视野内的最优伙伴
    bestFish = currentFish;
    minDistance = currentFish.totalDistance;
    
    for i = 1:n
        if i ~= fishIdx
            % 计算两条鱼之间的"距离"
            dist = solutionDistance(currentFish.permutation, fishes(i).permutation);
            if dist < params.visual * length(currentFish.permutation)
                if fishes(i).totalDistance < minDistance
                    bestFish = fishes(i);
                    minDistance = fishes(i).totalDistance;
                end
            end
        end
    end
    
    if bestFish.totalDistance < currentFish.totalDistance
        % 检查最优伙伴周围的拥挤度
        neighborCount = 0;
        for i = 1:n
            if i ~= fishIdx
                dist = solutionDistance(bestFish.permutation, fishes(i).permutation);
                if dist < params.visual * length(bestFish.permutation)
                    neighborCount = neighborCount + 1;
                end
            end
        end
        
        if (neighborCount / n) < params.delta
            % 不拥挤,向最优伙伴移动
            newPerm = moveTowardPosition(currentFish.permutation, bestFish.permutation, params.step);
            newFish = decodeSolution(newPerm, customerData, problem, params);
            newFish.totalDistance = calculateTotalDistance(newFish.routes, customerData.coords);
            newFish.permutation = newPerm;
            newFish.vehicleCount = length(newFish.routes);
        else
            % 拥挤,执行觅食行为
            newFish = preyBehavior(currentFish, params, distanceMatrix, customerData, problem);
        end
    else
        % 没有更好的伙伴,执行觅食行为
        newFish = preyBehavior(currentFish, params, distanceMatrix, customerData, problem);
    end
end

2.5 辅助函数

function dist = calculateTotalDistance(routes, coords)
    % 计算总行驶距离
    dist = 0;
    for r = 1:length(routes)
        route = routes{r};
        for i = 1:length(route)-1
            fromNode = route(i);
            toNode = route(i+1);
            dx = coords(fromNode, 1) - coords(toNode, 1);
            dy = coords(fromNode, 2) - coords(toNode, 2);
            dist = dist + sqrt(dx^2 + dy^2);
        end
    end
end

function newPerm = generateNeighbor(perm, params, distanceMatrix)
    % 生成邻居解(使用2-opt、交换等局部搜索)
    n = length(perm);
    newPerm = perm;
    
    % 随机选择一种邻域操作
    operation = randi(4);
    
    switch operation
        case 1  % 交换两个位置
            i = randi(n);
            j = randi(n);
            while i == j
                j = randi(n);
            end
            temp = newPerm(i);
            newPerm(i) = newPerm(j);
            newPerm(j) = temp;
            
        case 2  % 反转一段序列
            i = randi(n-1);
            j = randi(n);
            while i >= j
                i = randi(n-1);
                j = randi(n);
            end
            newPerm(i:j) = fliplr(newPerm(i:j));
            
        case 3  % 插入操作
            i = randi(n);
            j = randi(n);
            while i == j
                j = randi(n);
            end
            if i < j
                newPerm = [newPerm(1:i-1), newPerm(i+1:j), newPerm(i), newPerm(j+1:end)];
            else
                newPerm = [newPerm(1:j), newPerm(i), newPerm(j+1:i-1), newPerm(i+1:end)];
            end
            
        case 4  % 基于距离的智能交换
            % 优先交换距离远的客户
            if n >= 4
                % 计算所有客户对的距离(简化处理)
                idx1 = randi(n);
                % 找到与idx1距离较远的客户
                possibleIdx = 1:n;
                possibleIdx(idx1) = [];
                
                % 使用概率选择,距离越远被选中概率越高
                probs = ones(1, n-1) / (n-1);  % 这里可以优化为实际距离
                idx2 = randsample(possibleIdx, 1, true, probs);
                
                temp = newPerm(idx1);
                newPerm(idx1) = newPerm(idx2);
                newPerm(idx2) = temp;
            end
    end
end

function dist = solutionDistance(perm1, perm2)
    % 计算两个解之间的差异度(位置差异)
    n = length(perm1);
    dist = 0;
    for i = 1:n
        if perm1(i) ~= perm2(i)
            dist = dist + 1;
        end
    end
    dist = dist / n;  % 归一化到[0,1]
end

function centerPerm = calculateCenterPosition(fishes)
    % 计算多个鱼位置的中心(排列的中位数)
    nFishes = length(fishes);
    n = length(fishes(1).permutation);
    
    % 简单平均:对每个位置取出现频率最高的客户
    centerPerm = zeros(1, n);
    positions = zeros(nFishes, n);
    
    for f = 1:nFishes
        positions(f, :) = fishes(f).permutation;
    end
    
    for pos = 1:n
        % 统计该位置各个客户的频率
        clients = positions(:, pos);
        uniqueClients = unique(clients);
        counts = histcounts(clients, [uniqueClients; max(uniqueClients)+1]);
        
        [~, maxIdx] = max(counts);
        centerPerm(pos) = uniqueClients(maxIdx);
    end
    
    % 确保中心位置是有效排列(无重复客户)
    missingClients = setdiff(2:max(centerPerm), centerPerm);
    if ~isempty(missingClients)
        % 如果有缺失的客户,进行修复
        duplicates = find(diff(sort(centerPerm)) == 0);
        if ~isempty(duplicates)
            centerPerm(duplicates(1)) = missingClients(1);
        end
    end
end

2.6 可视化函数

function plotSolution(fish, customerData, titleStr)
    % 绘制路径方案
    figure(1);
    clf;
    hold on;
    
    routes = fish.routes;
    colors = lines(length(routes));
    
    % 绘制客户点
    scatter(customerData.coords(1,1), customerData.coords(1,2), 200, 'r', 'p', 'LineWidth', 2);
    scatter(customerData.coords(2:end,1), customerData.coords(2:end,2), 100, 'b', 'o', 'filled');
    
    % 绘制每条路径
    for r = 1:length(routes)
        route = routes{r};
        x = customerData.coords(route, 1);
        y = customerData.coords(route, 2);
        
        plot(x, y, '-', 'Color', colors(r,:), 'LineWidth', 2);
        plot(x, y, 'o', 'Color', colors(r,:), 'MarkerFaceColor', colors(r,:));
        
        % 显示路径方向
        for i = 1:length(route)-1
            midX = (x(i) + x(i+1)) / 2;
            midY = (y(i) + y(i+1)) / 2;
            text(midX, midY, sprintf('%d', r), 'FontSize', 8);
        end
    end
    
    % 标注
    text(customerData.coords(1,1), customerData.coords(1,2), ' 配送中心', ...
        'FontSize', 10, 'FontWeight', 'bold');
    
    xlabel('X坐标');
    ylabel('Y坐标');
    title(sprintf('%s\n总距离: %.2f, 车辆数: %d', titleStr, fish.totalDistance, length(routes)));
    grid on;
    axis equal;
    hold off;
    
    drawnow;
end

function plotFinalResults(bestFish, bestCostHistory, customerData)
    % 绘制最终结果
    
    figure('Position', [100, 100, 1200, 400]);
    
    % 子图1:优化收敛曲线
    subplot(1, 3, 1);
    plot(bestCostHistory, 'b-', 'LineWidth', 2);
    xlabel('迭代次数');
    ylabel('总行驶距离');
    title('人工鱼群算法收敛曲线');
    grid on;
    
    % 添加统计信息
    avgCost = mean(bestCostHistory);
    stdCost = std(bestCostHistory);
    text(0.05, 0.95, sprintf('最优值: %.2f\n平均值: %.2f\n标准差: %.2f', ...
        bestCostHistory(end), avgCost, stdCost), ...
        'Units', 'normalized', 'FontSize', 9, ...
        'VerticalAlignment', 'top', 'BackgroundColor', 'w');
    
    % 子图2:最终路径方案
    subplot(1, 3, [2, 3]);
    plotSolution(bestFish, customerData, '最终优化方案');
end

function printSolutionDetails(bestFish, customerData)
    % 打印详细解决方案
    fprintf('\n========== 最优解详细信息 ==========\n');
    fprintf('总行驶距离: %.2f\n', bestFish.totalDistance);
    fprintf('使用车辆数: %d\n', length(bestFish.routes));
    fprintf('\n各车辆路径详情:\n');
    
    for v = 1:length(bestFish.routes)
        route = bestFish.routes{v};
        routeStr = sprintf('%d', route(1));
        totalDemand = 0;
        
        for i = 2:length(route)
            if route(i) == 1  % 配送中心
                routeStr = sprintf('%s → %d', routeStr, route(i));
            else
                routeStr = sprintf('%s → %d', routeStr, route(i));
                totalDemand = totalDemand + customerData.demands(route(i));
            end
        end
        
        fprintf('车辆%d: %s\n', v, routeStr);
        fprintf('  服务客户数: %d, 总需求量: %d\n', ...
            length(route)-2, totalDemand);
        
        % 计算该路径距离
        routeDist = 0;
        for i = 1:length(route)-1
            fromNode = route(i);
            toNode = route(i+1);
            dx = customerData.coords(fromNode, 1) - customerData.coords(toNode, 1);
            dy = customerData.coords(fromNode, 2) - customerData.coords(toNode, 2);
            routeDist = routeDist + sqrt(dx^2 + dy^2);
        end
        fprintf('  路径距离: %.2f\n\n', routeDist);
    end
end

三、算法参数调优建议

3.1 关键参数设置

% 经验参数配置(针对不同规模问题)
if problem.nCustomers <= 20
    params.fishNum = 30;
    params.maxIter = 100;
    params.visual = 0.4;
    params.step = 0.3;
elseif problem.nCustomers <= 50
    params.fishNum = 50;
    params.maxIter = 200;
    params.visual = 0.3;
    params.step = 0.2;
else
    params.fishNum = 80;
    params.maxIter = 300;
    params.visual = 0.2;
    params.step = 0.15;
end

3.2 自适应参数调整

% 在每次迭代中动态调整参数
if mod(iter, 20) == 0
    % 根据搜索进度调整
    improvementRatio = (bestCostHistory(max(1, iter-10)) - bestCostHistory(iter)) / bestCostHistory(max(1, iter-10));
    
    if improvementRatio < 0.01  % 改进很小
        params.step = params.step * 1.2;  % 增加步长,跳出局部最优
        params.visual = min(0.5, params.visual * 1.1);  % 扩大视野
    else
        params.step = max(0.05, params.step * 0.95);  % 逐渐减小步长
        params.visual = max(0.1, params.visual * 0.98);  % 逐渐聚焦
    end
end

四、算法扩展与变体

4.1 带时间窗的VRP(VRPTW)

function fish = decodeSolutionVRPTW(perm, customerData, problem, params)
    % VRPTW的解码,考虑时间窗约束
    routes = {};
    currentRoute = [1];  % 起点
    currentLoad = 0;
    currentTime = 0;
    
    for i = 1:length(perm)
        customerIdx = perm(i);
        demand = customerData.demands(customerIdx);
        serviceTime = customerData.serviceTime(customerIdx);
        timeWindow = customerData.timeWindows(customerIdx, :);  % [最早, 最晚]
        
        % 计算到达时间
        travelTime = getTravelTime(currentRoute(end), customerIdx, customerData);
        arrivalTime = currentTime + travelTime;
        
        % 检查是否满足约束
        if currentLoad + demand <= problem.capacity && ...
           arrivalTime <= timeWindow(2)
            
            % 等待(如果早于最早时间)
            if arrivalTime < timeWindow(1)
                waitTime = timeWindow(1) - arrivalTime;
                arrivalTime = timeWindow(1);
            else
                waitTime = 0;
            end
            
            currentRoute = [currentRoute, customerIdx];
            currentLoad = currentLoad + demand;
            currentTime = arrivalTime + serviceTime + waitTime;
        else
            % 开始新路径
            if length(currentRoute) > 1
                % 返回配送中心
                returnTime = getTravelTime(currentRoute(end), 1, customerData);
                currentRoute = [currentRoute, 1];
                routes{end+1} = currentRoute;
            end
            
            % 开始新路径
            currentRoute = [1, customerIdx];
            currentLoad = demand;
            travelTime = getTravelTime(1, customerIdx, customerData);
            arrivalTime = travelTime;
            
            if arrivalTime < timeWindow(1)
                waitTime = timeWindow(1) - arrivalTime;
                currentTime = timeWindow(1) + serviceTime;
            else
                currentTime = arrivalTime + serviceTime;
            end
        end
    end
    
    % 添加最后一条路径
    if length(currentRoute) > 1
        currentRoute = [currentRoute, 1];
        routes{end+1} = currentRoute;
    end
    
    fish.routes = routes;
end

4.2 混合人工鱼群算法

function newFish = hybridAFSBehavior(fish, params, distanceMatrix, customerData, problem)
    % 混合行为:结合局部搜索
    % 先执行标准人工鱼行为
    if rand() < 0.5
        newFish = swarmBehaviorWrapper(fish, params, distanceMatrix, customerData, problem);
    else
        newFish = followBehaviorWrapper(fish, params, distanceMatrix, customerData, problem);
    end
    
    % 再执行局部搜索优化
    if rand() < 0.3  % 30%的概率执行局部搜索
        newFish = localSearch(newFish, params, customerData, problem);
    end
end

function improvedFish = localSearch(fish, params, customerData, problem)
    % 局部搜索:2-opt, 3-opt, 交换等
    improvedFish = fish;
    
    for lsIter = 1:10
        % 随机选择一种局部搜索操作
        operation = randi(3);
        newPerm = improvedFish.permutation;
        
        switch operation
            case 1  % 2-opt
                i = randi(length(newPerm)-1);
                j = randi(length(newPerm));
                while i >= j
                    i = randi(length(newPerm)-1);
                    j = randi(length(newPerm));
                end
                newPerm(i:j) = fliplr(newPerm(i:j));
                
            case 2  % 交换两个子路径
                % 实现路径间交换
                
            case 3  % 插入操作
                % 实现客户插入优化
        end
        
        % 评估新解
        tempFish = decodeSolution(newPerm, customerData, problem, params);
        tempFish.totalDistance = calculateTotalDistance(tempFish.routes, customerData.coords);
        
        if tempFish.totalDistance < improvedFish.totalDistance
            improvedFish = tempFish;
            improvedFish.permutation = newPerm;
        end
    end
end

参考代码 人工鱼群算法求解VRP问题 www.3dddown.com/cna/83325.html

五、使用说明与建议

5.1 运行步骤

  1. 将上述所有代码保存为单独的.m文件或在一个主文件中
  2. 根据需要调整问题参数(客户数、车辆容量等)
  3. 运行主程序
  4. 查看可视化结果和详细输出

5.2 性能优化建议

  1. 并行计算:可以使用parfor并行处理鱼群的行为计算
  2. 记忆功能:添加一个外部档案记录历史最优解
  3. 多种群策略:使用多个子群并行搜索,定期交换信息
  4. 启发式初始化:使用最近邻、节约算法等生成初始解

5.3 应用到实际问题

% 读取真实数据
function customerData = loadRealData(filename)
    % 从文件读取真实VRP数据
    data = readtable(filename);
    customerData.coords = [data.X, data.Y];
    customerData.demands = data.Demand;
    customerData.serviceTime = data.ServiceTime;
    
    if ismember('TimeWindow', data.Properties.VariableNames)
        customerData.timeWindows = [data.EarliestTime, data.LatestTime];
    end
end

% 批量运行测试
function results = batchTestAFS(problemSizes, nRuns)
    % 批量测试不同规模问题
    results = struct();
    
    for p = 1:length(problemSizes)
        problem.nCustomers = problemSizes(p);
        problem.capacity = 100;
        
        runTimes = zeros(nRuns, 1);
        bestCosts = zeros(nRuns, 1);
        
        for r = 1:nRuns
            tic;
            % 运行人工鱼群算法
            [bestFish, ~] = runAFS(problem);
            runTimes(r) = toc;
            bestCosts(r) = bestFish.totalDistance;
        end
        
        results(p).problemSize = problemSizes(p);
        results(p).avgTime = mean(runTimes);
        results(p).stdTime = std(runTimes);
        results(p).avgCost = mean(bestCosts);
        results(p).bestCost = min(bestCosts);
        results(p).worstCost = max(bestCosts);
    end
end

这个实现提供了完整的人工鱼群算法求解VRP问题的框架,包含了算法核心、可视化、参数调优和扩展功能。

posted @ 2025-12-18 09:42  康帅服  阅读(33)  评论(0)    收藏  举报