MATLAB - 外卖送餐路径优化算法(最短路径)

目录

作业名称:外卖送餐路径优化算法

(1)计算最优路径(总送餐时间最短策略)

(2)如果目标是客户总最短等待时间策略,最优路径如何

(3)如果考虑有优先客户(某个客户指定某个时间之前必须送到的优先 策略)最优路径如何变化?

(4)平衡策略,总送餐时间和总等待时间达到平衡,最优路径如何?


作业名称:外卖送餐路径优化算法

作业描述:地图数据,至少200个节点,有餐馆(出发地)、小区(目的地)、路口( 十字、丁字、五字)等节点,单向道、双向道都有,绘制网络图,形成邻接矩阵数据 。可以使用带权重的邻接矩阵随机生成,直接代替地图数据。假设1个外卖小哥从某个 餐馆至少送10份订餐(不同小区节点)。

• 已知条件:假设送餐小哥车速v,每个订餐客户i要求的等待时间是t(i),每个客户节点i

的距离是s(i)(自己可以给出合理的具体数值)

• 要求:设计不同策略下的最优路径算法并实现:

(1)计算最优路径(总送餐时间最短策略)。

(2)如果目标是客户总最短等待时间策略,最优路径如何?

(3)如果考虑有优先客户(某个客户指定某个时间之前必须送到的优先

策略)最优路径如何变化?

(4)平衡策略,总送餐时间和总等待时间达到平衡,最优路径如何?

(5)可视化展示每一种最优路线图

说明:展示时,每个小组人员都上来讲,按照分工讲。

更高的要求(可选做):开发一个app,在网络上,输入餐馆节点位置,

输入10个以上订餐节点位置,再选择最优策略,系统可以自动给出推荐

的最优路线(注意,这个内容是选作,不作为本次作业的要求,仅提供大家思考的方向)

(1)计算最优路径(总送餐时间最短策略)

 运算结果如下

(输入窗口)

%主程序main

clc,clear,close all;

%先生成一个随机的矩阵map储存200个点间的相互距离

tf=eye(200,200);

for i=1:200

    map(i,i)=0;

end

for i=1:200

    for j=(i+1):200

        tf(i,j)=1;

    end

    for j=1:(i-1)

        tf(i,j)=randi([0,1],1,1);

        if tf(i,j)==1

            map(i,j)=map(j,i);

        else

            map(i,j)=10000;

        end

    end

end

for i=1:200

    for j=1:200

        map(i,j)=map(j,i);

    end

end

map1=map;

%dist用来存储两个点之间的距离

for i=1:200

    for j=i:200      

dist(i,j)=map(i,j);

dist(j,i)=dist(i,j);

    end

end

real_world=10000*randi([0,1],200);

for point=1:200

    real_world(point,point)=0;

end

%随机定义不连通道路

dist=dist+real_world;

route=cell(200,200);%用元胞数组记录相应两点间的最短路径

%计算最优距离与最优路线矩阵:dist_good对应两点间最小值,route对应两点间最短路径

[dist_good,route]=floyd(dist,route);



%(1)没有优先顺序时

num=input('请输入订单数:')+1;

VIP=[1 (input('请输入VIP订单(数组形式,若无则输入 0):'))+1];

dist_main=dist_good(1:num,1:num); % 抽取 num+1 个节点,将每个订单理解为一个地点

all_route=1;% 起始点为 1

%用贪心算法计算最优路线与总距离

[sum,all_route]=route_search(dist_main,route,all_route,VIP);





%弗洛伊德算法计算出两点之间的最短路线,记录进矩阵

%弗洛伊德算法的目的:得到最优相邻矩阵和最优路径矩阵

%输入当前的相邻矩阵和记忆最短路径的route矩阵

function[dist,route]=floyd(dist,route)

%i代表中转点

%三层嵌套循环

for i=1:200

    for j=1:200

        for k=1:200

            if dist(j,k)>dist(j,i)+dist(i,k)

                dist(j,k)=dist(j,i)+dist(i,k);

                route{j,k}=[route{j,i} i route{i,k}];

            end

        end

    end

end

end



%贪心算法寻找最优路线

function[sum,all_route]=route_search(dist_main,route,all_route,VIP)

%首先利用贪心算法在 num 个节点中找出最优通路,存入 all_route之中,然后返回最短路径

num=size(dist_main,1);

record=linspace(1,num,num); %计算快递小哥到过的地点

record(1)=0;%除去快递小哥的出发地——餐馆

sum=0;%表示快递小哥跑的总距离

%对于VIP客户进行优先处理

size_VIP=size(VIP,2);

for i=1:size_VIP

    next=VIP(i);

    if next==0

        break %条件判断,所有VIP客户均送完后终止循环

    elseif next==1

        continue

    end

    former=VIP(i-1);

    record(next)=0;

    all_route=[all_route route{former,next} next];%存入路径

    sum=sum+dist_main(former,next);%把送VIP客户的路程长度相加

end

%用贪心算法处理其他的地点

former=next;

while any(record)

    main=100;%此处表示近似无穷大

    for i=1:num

        if(ismember(i,record))&&(main>dist_main(former,i))

            next=i;

            main=dist_main(former,next);

        end

    end

    

all_route=[all_route route{former,next} next];

    former=next;

    sum=sum+main;%再加上给普通客户送餐的路程长度

    record(next)=0;

index = 1:size(map1,1);

names = {};

for ii = index

    names{ii} = num2str(index(ii));

end

    %% 定义图像G

G = graph(map1,names);

%% 指定每个点的坐标

x = randperm(10);

y = randperm(20,10);

figure

p = plot(G,'go-','LineWidth',0.000001,'MarkerSize',10);

highlight(p,all_route, 'EdgeColor', 'r')

highlight(p,all_route,'NodeColor','r')

end

end

(2)如果目标是客户总最短等待时间策略,最优路径如何

输入

输出

 

点与点之间是有连线的

%代码如下

A=randi(100,200,200);

route=cell(200,200);%存储各点之间的最短路径



for i=1:200

    A(i,i)=0;

end

for i=1:200

    for j=(i+1):200

        tf(i,j)=1;

    end

    for j=1:(i-1)

        tf(i,j)=randi([0,1],1,1);

        if tf(i,j)==1

            A(i,j)=A(j,i);

        else

            A(i,j)=10000;

        end

    end

end

for i=1:200

    for j=1:200

        A(i,j)=A(j,i);

    end

end

fprintf("速度默认值为5m/s")

target=input("请输入所有客户的位置数组:");%target:目标客户的位置

st=input("请输入起点");

%% 随机数生成tf邻接矩阵,map距离矩阵

tf=eye(200,200);

map=randi(100,200,200);

route=cell(200,200);%存储各点之间的最短路径



v=5;%速度

for i=1:200

    map(i,i)=0;

end

for i=1:200

    for j=(i+1):200

        tf(i,j)=1;

    end

    for j=1:(i-1)

        tf(i,j)=randi([0,1],1,1);

        if tf(i,j)==1

            map(i,j)=map(j,i);

        else

            map(i,j)=10000;

        end

    end

end

%% 弗洛伊德算法求任意两点之间的最短路径



for i=1:200

    for j=1:200

        for k=1:200

            if map(j,k)>map(j,i)+map(i,k)

                map(j,k)=map(j,i)+map(i,k);

                route{j,k}=[route{j,i} i route{i,k}];

            end

        end

    end

end

%%  贪心求解

all_dist=0;%总距离

all_route=st;%总路线

all_time=0;%总等待时间

num=numel(target);%顾客数量

judge=ones(1,num);%标记节点

flag=1;

former=st;

while (flag<=num)

    min_dist=1000;

    min_target=1;

    

    for i=1:num%贪心寻找距离former最短的点

        if min_dist>map(former,target(i)) &&judge(i)==1

           min_dist=map(former,target(i));

           min_target=i;

        end

    end

      judge(min_target)=0;

      all_route=[all_route route{former,target(min_target)} target(min_target)];

      all_dist=all_dist+min_dist;

      all_time=all_time+(num+1-flag)*(min_dist/v);

      former=target(min_target);

      flag=flag+1;

end

%% 输出结果

fprintf("最优路径是:")

fprintf("%5d",all_route)

fprintf("\n最短距离是:")

fprintf("%d",all_dist)

fprintf("\n顾客总最短等待时间是:")

fprintf("%d",all_time)







index = 1:size(A,1);

names = {};

for ii = index

    names{ii} = num2str(index(ii));

end

% 定义图像G

G = graph(A,names);

%% 指定每个点的坐标

x = randperm(10);

y = randperm(20,10);

%绘制无向图

figure

p = plot(G,'go-','LineWidth',0.000001,'MarkerSize',10);

%把最优路径和要经过的节点高亮出来

highlight(p,all_route, 'EdgeColor', 'r')

highlight(p,all_route,'NodeColor','r')

(3)如果考虑有优先客户(某个客户指定某个时间之前必须送到的优先 策略)最优路径如何变化?

输入

输出

%代码如下

st=input("请输入起点");

VIP=input("请输入vip的位置");

target=input("请输入普通客户的位置数组:");%target:目标客户的位置

str=VIP;

%% 随机数生成tf邻接矩阵,map距离矩阵

tf=eye(200,200);

map=randi(100,200,200);

route=cell(200,200);%存储各点之间的最短路径



for i=1:200

    map(i,i)=0;

end

for i=1:200

    for j=(i+1):200

        tf(i,j)=1;

    end

    for j=1:(i-1)

        tf(i,j)=randi([0,1],1,1);

        if tf(i,j)==1

            map(i,j)=map(j,i);

        else

            map(i,j)=10000;

        end

    end

end

for i=1:200

    for j=1:200

        map(i,j)=map(j,i);

    end

end

%% 计算VIP路线

[vip_distance,vip_route]=vip(map,st,VIP);

%% 弗洛伊德算法求任意两点之间的最短路径



for i=1:200

    for j=1:200

        for k=1:200

            if map(j,k)>map(j,i)+map(i,k)

                map(j,k)=map(j,i)+map(i,k);

                route{j,k}=[route{j,i} i route{i,k}];

            end

        end

    end

end

%%  贪心求解

all_dist=0;%总距离

all_route=str;%总路线

all_time=0;%总等待时间

num=numel(target);%顾客数量

judge=ones(1,num);%标记节点

flag=1;

former=str;

while (flag<=num)

    min_dist=1000;

    min_target=1;

    

    for i=1:num%贪心寻找距离former最短的点

        if min_dist>map(former,target(i)) &&judge(i)==1

           min_dist=map(former,target(i));

           min_target=i;

        end

    end

      judge(min_target)=0;

      all_route=[all_route route{former,target(min_target)} target(min_target)];

      all_dist=all_dist+min_dist;

      former=target(min_target);

      flag=flag+1;

index = 1:size(map,1);

names = {};

for ii = index

    names{ii} = num2str(index(ii));

end

% 定义图像G

G = graph(map,names);

%% 指定每个点的坐标

x = randperm(10);

y = randperm(20,10);

figure

p = plot(G,'go-','LineWidth',0.000001,'MarkerSize',10);

highlight(p,all_route, 'EdgeColor', 'r')

highlight(p,all_route,'NodeColor','r')

end

%% 输出结果

fprintf("\nvip客户最短距离是:")

fprintf("%d",vip_distance)

fprintf("\nvip客户最短路径是:")

fprintf("%5d ",vip_route)

fprintf("\n普通客户最优路径是:")

fprintf("%5d",all_route)

fprintf("\n普通客户最短距离是:")

fprintf("%d",all_dist)





同时第三题我们还定义了一个叫vip的函数

%代码如下

function [distance,path] = vip( W,st,e )

%vip函数中w为距离矩阵,st为起点,e为终点

n=length(W);

D = W(st,:);

visit= ones(1,n); visit(st)=0;

parent = zeros(1,n);

path =[];

for i=1:n-1

    temp = [];

    for j=1:n

       if visit(j)

           temp =[temp D(j)];

       else

           temp =[temp inf];

       end

       

    end

    

    [value,index] = min(temp);

    visit(index) = 0;

    for k=1:n

        if D(k)>D(index)+W(index,k)

           D(k) = D(index)+W(index,k);

           parent(k) = index;

        end

    end

    

   

end



distance = D(e);

t = e;

while t~=st && t>0

 path =[t,path];

  p=parent(t);t=p;

end

path =[st,path];

End

(4)平衡策略,总送餐时间和总等待时间达到平衡,最优路径如何?

注:这个计算过程采用了遍历的方法,运行时间很长,但是很有逻辑

%主代码如下

tf=eye(200,200);

map=randi(50,200,200);

pre=zeros(200,200);

for i=1:200

    map(i,i)=0;

end

for i=1:200

    for j=(i+1):200

        tf(i,j)=1;

    end

    for j=1:(i-1)

        tf(i,j)=randi([0,1],1,1);

        if tf(i,j)==1

            map(i,j)=map(j,i);

        else

            map(i,j)=10000;

        end

    end

end

for i=1:200

    for j=1:200

        map(i,j)=map(j,i);

    end

end

dis=zeros(200,200);

for i=1:200

    for j=1:200

        dis(i,j)=map(i,j);

    end

end

for i=1:200

    for j=1:200

        pre(i,j)=i;

    end

end

for k=1:200

    for i=1:200

       for j=1:200

           if dis(i,k)+dis(k,j)<dis(i,j)

               dis(i,j)=dis(i,k)+dis(k,j);

               pre(i,j)=k;

           end

       end

    end

end

global mid pos perm visit dis min road min_diliver min_wait;

min=10000;

min_diliver=10000;

min_wait=10000;

visit=zeros(1,10);

perm=zeros(1,10);

road=[];

pos=randperm(200);

pos=pos(1:11);

dfs(1,10);

road=[pos(1) road];

for i=1:10

    mid=road(i+1);

    while mid~=road(i)

        mid=pre(road(i),mid);

        if mid==road(i)

            break;

        end

        road=[road(1:i),mid,road(i+1:end)];

    end

end

index = 1:size(map,1);

names = {};

for ii = index

    names{ii} = num2str(index(ii));

end

% 定义图像G

G = graph(map,names);

%% 指定每个点的坐标

x = randperm(10);

y = randperm(20,10);

figure

p = plot(G,'go-','LineWidth',0.000001,'MarkerSize',10);

highlight(p,road, 'EdgeColor', 'r')

highlight(p,road,'NodeColor','r')

fprintf("最短送餐时间是:")

fprintf("%d",min_diliver)

fprintf("最短等待时间是:")

fprintf("%d",min_wait)











%定义的函数

function f=dfs(step,n)

global mid pos perm visit dis min road min_diliver min_wait;

if step==n+1

    temp=(n-1)*dis(pos(1),perm(1));

    temp_diliver=dis(pos(1),perm(1));

    temp_wait=temp+temp_diliver;

    for j=1:n-1

        temp=temp+(n-j-1)*dis(perm(j),perm(j+1));

        temp_diliver=temp_diliver+dis(perm(j),perm(j+1));

        temp_wait=temp_wait+(n-j)*dis(perm(j),perm(j+1));

    end

    if temp<min

        min=temp;

        min_diliver=temp_diliver;

        min_wait=temp_wait;

        road=perm;

    end

else

    for i=1:n

        if visit(i)==0

            visit(i)=1;

            perm(step)=pos(i+1);

            dfs(step+1,n);

            visit(i)=0;

        end

    end

end



  • 8
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的q-learning算法栅格最短路径MATLAB代码示例: ``` clear all; clc; %定义初始状态和目标状态 start_state = [1,1]; goal_state = [10,10]; %定义行动空间和奖励矩阵 action_space = ['N','S','E','W']; reward_matrix = -ones(10,10); reward_matrix(goal_state(1),goal_state(2)) = 100; %定义Q矩阵和学习参数 Q = zeros(10,10,4); alpha = 0.5; gamma = 0.9; epsilon = 0.1; %开始训练 for episode = 1:10000 %将智能体放在起点 current_state = start_state; while (~isequal(current_state,goal_state)) %选择行动 if rand < epsilon action = randi(4); else [~,action] = max(Q(current_state(1),current_state(2),:)); end %执行行动 next_state = current_state + [0,-1;0,1;1,0;-1,0](action,:); next_state = min(max(next_state,1),10); %更新Q矩阵 Q(current_state(1),current_state(2),action) = (1-alpha)*Q(current_state(1),current_state(2),action) + alpha*(reward_matrix(next_state(1),next_state(2))+gamma*max(Q(next_state(1),next_state(2),:))); %更新当前状态 current_state = next_state; end end %使用Q矩阵执行最短路径 current_state = start_state; path = [current_state]; while (~isequal(current_state,goal_state)) [~,action] = max(Q(current_state(1),current_state(2),:)); next_state = current_state + [0,-1;0,1;1,0;-1,0](action,:); next_state = min(max(next_state,1),10); path = [path;next_state]; current_state = next_state; end %绘制结果 figure(); plot(path(:,2),path(:,1),'-o'); grid on; xlim([0.5 10.5]); ylim([0.5 10.5]); xlabel('X'); ylabel('Y'); title('Q-Learning Algorithm for Shortest Path Problem in Grid World'); ``` 该代码使用了一个简单的4个行动空间(北、南、东、西)和一个-1的奖励矩阵,表示无论走哪个方向都会受到一点惩罚。Q矩阵是一个三维矩阵,其中前两个维度表示状态,第三个维度表示行动。在训练过程中,智能体随机选择行动或者根据当前Q值选择最优行动,并更新Q矩阵。在执行最短路径时,智能体根据当前Q值选择最优行动,直到到达目标状态。最终,代码将路径可视化并绘制出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值