zoukankan      html  css  js  c++  java
  • 快递公司送货策略

    方案一基本思路:通过蚁群算法生成最优化路径,沿着最优路径规划业务员的送货路线,由车的限载货量25kg来分隔各个送货地点,然后计算这个方案的总路程和总时间,再根据业务员的上班时间安排每条路线所需的业务员。

    蚁群算法实现如下:

    由于题目假设送货运行路线均为平行于坐标轴的折线。则每两个点间的距离为:D(i,j)=|x(i)-x(j)|+|y(i)-y(j)|

     

     由此行代码可得出每两个点间的距离矩阵D,但在进行蚁群算法的实现时,要保证启发函数的分母不为零,需将对角线上的元素修正为一个足够小的正数,可为10^-3.

    %% 蚁群算法及Matlab实现——TSP问题
    %% 数据准备
    % 清空环境变量
    clear all
    clc
    
    % 程序运行计时开始
    t0 = clock;
    
    %导入数据
    citys=xlsread('送货.xlsx', 'C3:D32');
    x=xlsread('送货.xlsx','C3:C32');
    y=xlsread('送货.xlsx','D3:D32');
    
    %% 计算城市间相互距离
    n = size(citys,1);
    D = zeros(n,n);
    for i = 1:n
        for j = 1:n
            if i ~= j
                D(i,j) = abs(x(i)'-x(j))+abs(y(i)'-y(j));
            else
                D(i,j) = 1e-4;      %设定的对角矩阵修正值
            end
        end    
    end
    
    %% 初始化参数
    m = 75;                              % 蚂蚁数量
    alpha = 1;                           % 信息素重要程度因子
    beta = 5;                            % 启发函数重要程度因子
    vol = 0.2;                           % 信息素挥发(volatilization)因子
    Q = 10;                               % 常系数
    Heu_F = 1./D;                        % 启发函数(heuristic function)
    Tau = ones(n,n);                     % 信息素矩阵
    Table = zeros(m,n);                  % 路径记录表
    iter = 1;                            % 迭代次数初值
    iter_max = 100;                      % 最大迭代次数 
    Route_best = zeros(iter_max,n);      % 各代最佳路径       
    Length_best = zeros(iter_max,1);     % 各代最佳路径的长度  
    Length_ave = zeros(iter_max,1);      % 各代路径的平均长度  
    Limit_iter = 0;                      % 程序收敛时迭代次数
    
    %% 迭代寻找最佳路径
    while iter <= iter_max
        % 随机产生各个蚂蚁的起点城市
          start = zeros(m,1);
          for i = 1:m
              temp = randperm(n);
              start(i) = temp(1);
          end
          Table(:,1) = start; 
          % 构建解空间
          citys_index = 1:n;
          % 逐个蚂蚁路径选择
          for i = 1:m
              % 逐个城市路径选择
             for j = 2:n
                 tabu = Table(i,1:(j - 1));           % 已访问的城市集合(禁忌表)
                 allow_index = ~ismember(citys_index,tabu);    % 参加说明1(程序底部)
                 allow = citys_index(allow_index);  % 待访问的城市集合
                 P = allow;
                 % 计算城市间转移概率
                 for k = 1:length(allow)
                     P(k) = Tau(tabu(end),allow(k))^alpha * Heu_F(tabu(end),allow(k))^beta;
                 end
                 P = P/sum(P);
                 % 轮盘赌法选择下一个访问城市
                Pc = cumsum(P);     %参加说明2(程序底部)
                target_index = find(Pc >= rand); 
                target = allow(target_index(1));
                Table(i,j) = target;
             end
          end
          % 计算各个蚂蚁的路径距离
          Length = zeros(m,1);
          for i = 1:m
              Route = Table(i,:);
              for j = 1:(n - 1)
                  Length(i) = Length(i) + D(Route(j),Route(j + 1));
              end
              Length(i) = Length(i) + D(Route(n),Route(1));
          end
          % 计算最短路径距离及平均距离
          if iter == 1
              [min_Length,min_index] = min(Length);
              Length_best(iter) = min_Length;  
              Length_ave(iter) = mean(Length);
              Route_best(iter,:) = Table(min_index,:);
              Limit_iter = 1; 
              
          else
              [min_Length,min_index] = min(Length);
              Length_best(iter) = min(Length_best(iter - 1),min_Length);
              Length_ave(iter) = mean(Length);
              if Length_best(iter) == min_Length
                  Route_best(iter,:) = Table(min_index,:);
                  Limit_iter = iter; 
              else
                  Route_best(iter,:) = Route_best((iter-1),:);
              end
          end
          % 更新信息素
          Delta_Tau = zeros(n,n);
          % 逐个蚂蚁计算
          for i = 1:m
              % 逐个城市计算
              for j = 1:(n - 1)
                  Delta_Tau(Table(i,j),Table(i,j+1)) = Delta_Tau(Table(i,j),Table(i,j+1)) + Q/Length(i);
              end
              Delta_Tau(Table(i,n),Table(i,1)) = Delta_Tau(Table(i,n),Table(i,1)) + Q/Length(i);
          end
          Tau = (1-vol) * Tau + Delta_Tau;
        % 迭代次数加1,清空路径记录表
        iter = iter + 1;
        Table = zeros(m,n);
    end
    
    %% 结果显示
    [Shortest_Length,index] = min(Length_best);
    Shortest_Route = Route_best(index,:);
    Time_Cost=etime(clock,t0);
    disp(['最短距离:' num2str(Shortest_Length)]);
    disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);
    disp(['收敛迭代次数:' num2str(Limit_iter)]);
    disp(['程序执行时间:' num2str(Time_Cost) '秒']);
    
    %% 绘图
    figure(1)
    plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...  %三点省略符为Matlab续行符
         [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
    grid on
    for i = 1:size(citys,1)
        text(citys(i,1),citys(i,2),['   ' num2str(i)]);
    end
    text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),'       起点');
    text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),'       终点');
    xlabel('城市位置横坐标')
    ylabel('城市位置纵坐标')
    title(['ACA最优化路径(最短距离:' num2str(Shortest_Length) ')'])
    figure(2)
    plot(1:iter_max,Length_best,'b')
    legend('最短距离')
    xlabel('迭代次数')
    ylabel('距离')
    title('算法收敛轨迹')
    %--------------------------------------------------------------------------
    %% 程序解释或说明
    % 1. ismember函数判断一个变量中的元素是否在另一个变量中出现,返回0-1矩阵;
    % 2. cumsum函数用于求变量中累加元素的和,如A=[1, 2, 3, 4, 5], 那么cumsum(A)=[1, 3, 6, 10, 15]。
    

    程序的执行结果为:

     

     

    由此获得最短路径1-2-5-6-16-17-20-14-18-24-25-19-27-26-29-29-30--23-15-21-22-11-10-9-8-12-13-7-4-3-1

    由车的限载重量25kg划分这条最短路径,可得到8条送货线路:

     

    0-1-2-5-6-0

    0-16-17-20-14-0

    0-18-24-25-0

    0-19-27-30-0

    0-26-29-28-0

    0-23-15-21-22-0

    0-11-10--9-8-12-13-0             

    0-3-4-7-0                                   

    其中在0-19-27-0这条路线上做了优化,由于这条路线的载重量为19.8kg,而下一条路线0-26-29-28-0又无法将距离原点最远的30号送货点并入,30号距离路线下一个送货点23距离较远,故将30号点并入0-19-27-30-0这条线路中,更新后载货量为24kg,未超过限载货量。

     

     

    可得具体线路为

    由每两个点间的距离矩阵D,将每条线路两点间距离相加,求得每条线路的总路程S,再计算总时间T=S/v+10*k;(其中v为送货速度,k为每条路线中的送货点个数)

    最后根据业务员上班时间不超过六小时的限制条件分配每条路线的业务员:

    方案二:按顺序从1到30号送货点进行送货,根据车的限载货量25kg来分隔各个送货地点,然后计算这个方案的总路程和总时间,再根据业务员的上班时间安排每条路线所需的业务员。

    将两个方案进行对比:

    经过实验对比发现:运用蚁群算法得出的规划路线比直接按顺序送货的规划路线更优。

    故答案为方案一的路线方案

  • 相关阅读:
    4.Linux的目录结构
    使用idea创建spring mvc项目图文教程
    传统的Servlet在spring boot中怎么实现的?
    springboot系列教程导学篇
    记录一次序列化引起的问题解决办法 查看已编译类序列化值
    springboot支付项目之springboot集成jpa
    springboot支付项目之日志配置
    设计模式之状态模式总结篇
    看了这个Java实习生入职测试题后,幸亏我不是实习生
    幂等性学习及接口的幂等性
  • 原文地址:https://www.cnblogs.com/tavee/p/13337023.html
Copyright © 2011-2022 走看看