精华内容
下载资源
问答
  • 最短路径的Floyd算法实现,无向图和有向图均适用。1先区别有向图和无向图,2输入顶点数和边数并检查合法性,3输入每边的起点、终点、权重并检查合法性,并初始化邻接矩阵和路径矩阵,4调用自定义函数Floyd
  • 最短路径算法 matlab

    2018-12-31 15:25:29
    利用matlab实现了网络最短路径的搜索算法,通过输入邻接矩阵和需要输出最短路径的始节点和终节点,即可得到这连点间可行的最短路。
  • Dijkstra最短路径算法Matlab实现 包括最短路径的打印子程序
  • matlab 最短路径算法

    2015-06-09 09:46:29
    求两点家 最短路径,已经最短路径经过的其他节点情况
  • 遗传算法解决最短路径问题的matlab程序,并加以注释。
  • dijkstra最短路径算法 matlab
  • 用遗传算法计算最短路径MATLAB程序,在数学建模及其他编程中一种重要的算法思想
  • 关于遗传算法的一个简单例子,在MATLAB中实现搜寻最短路径(最优化)的目的,仅供大家参考学习,谢谢
  • 经过指定的中间节点集的最短路径算法matlab源码,包括三种应用模式: 1、从起点过必经点到达终点; 2、从起点过必经点且不掉头到达终点; 3、有指定朝向点,从起点过必经点且不掉头到达终点。
  • A*算法最短路径万能通用matlab代码

    热门讨论 2013-07-10 11:25:02
    A*算法 最短路径 万能通用 matlab代码
  • 复杂网络中无向无权图的最短路径matalb代码。用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
  • 经典DKS最短路径算法matlab代码,路径长度,序列
  • 最短路径算法dijkstra的matlab实现
  • 图的最短路径算法 Dijkstra算法 Dijkstra算法研究的是从初始点到其他任一结点的最短路径,即单源最短路径问题,其对图的要求是不存在负权值的边。 Dijkstra算法主要特点是以起始点为中心向外层层扩展,直到扩展到...

    图的最短路径算法

    Dijkstra算法

    Dijkstra算法研究的是从初始点到其他任一结点的最短路径,即单源最短路径问题,其对图的要求是不存在负权值的边。

    Dijkstra算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

    举例说明:

    已知图的邻接矩阵为
    [ 0 50 ∞ 40 25 10 50 0 15 20 ∞ 25 ∞ 15 0 10 20 ∞ 40 20 10 0 10 25 25 ∞ 20 10 0 55 10 25 ∞ 25 55 0 ] \left[\begin{array}{cccccc} {0} & {50} & {\infty} & {40} & {25} & {10} \\ {50} & {0} & {15} & {20} & {\infty} & {25} \\ {\infty} & {15} & {0} & {10} & {20} & {\infty} \\ {40} & {20} & {10} & {0} & {10} & {25} \\ {25} & {\infty} & {20} & {10} & {0} & {55} \\ {10} & {25} & {\infty} & {25} & {55} & {0} \end{array}\right] 050402510500152025150102040201001025252010055102525550
    行向量 pb 、 index1、 index2 、d 分别用来存放 P 标号信息、标号顶点顺序、标号顶点索引、最短通路的值,其中
    p b ( i ) = { 1  当i顶点已标号  0  当i顶点未标号  p b(i)=\left\{\begin{array}{ll} {1} & { \text { 当i顶点已标号 } } \\ {0} & {\text { 当i顶点未标号 } } \end{array}\right. pb(i)={10 i顶点已标号  i顶点未标号 
    $index2(i) $存放始点到第i 点最短通路中第i 顶点前一顶点的序号

    d(i)存放由始点到第i 点最短路的长度。

    clc,clear
    a=zeros(6);
    a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;               
    a(2,3)=15;a(2,4)=20;a(2,6)=25;
    a(3,4)=10;a(3,5)=20;
    a(4,5)=10;a(4,6)=25;
    a(5,6)=55;
    a=a+a'  ;                                                
    a(find(a==0))=inf; %将a=0的数全部替换为无强大               
    pb(1:length(a))=0;pb(1)=1;  %当一个点已经求出到原点的最短距离时,其下标i对应的pb(i)赋1
    index1=1; %存放存入S集合的顺序
    index2=ones(1,length(a)); %存放始点到第i点最短通路中第i顶点前一顶点的序号
    d(1:length(a))=inf;d(1)=0;  %存放由始点到第i点最短通路的值
    temp=1;  %temp表示c1,算c1到其它点的最短路。
    while sum(pb)<length(a)  %看是否所有的点都标记为P标号
    tb=find(pb==0); %找到标号为0的所有点,即找到还没有存入S的点
    d(tb)=min(d(tb),d(temp)+a(temp,tb));%计算标号为0的点的最短路,或者是从原点直接到这个点,又或者是原点经过r1,间接到达这个点
    tmpb=find(d(tb)==min(d(tb)));  %求d[tb]序列最小值的下标
    temp=tb(tmpb(1));%可能有多条路径同时到达最小值,却其中一个,temp也从原点变为下一个点
    pb(temp)=1;%找到最小路径的表对应的pb(i)=1
    index1=[index1,temp];  %存放存入S集合的顺序
    temp2=find(d(index1)==d(temp)-a(temp,index1));
    index2(temp)=index1(temp2(1)); %记录标号索引
    end
    d, index1, index2
    

    运算结果为:

    
    d =
    
         0    35    45    35    25    10
    
    
    index1 =
    
         1     6     5     2     4     3
    
    
    index2 =
    
         1     6     5     6     1     1
    

    Floyd算法

    弗洛伊德算法是解决图中任意两点间的最短路径的一种算法,可以正确处理有向图的最短路径问题。

    Floyd算法要求不可存在负权回路。在Floyd算法中一般有两个矩阵,一个距离矩阵D,一个路由矩阵R,其中距离矩阵用于存储任意两点之间的最短距离,而路由矩阵则记录任意两点之间的最短路径信息。

    其思想是:任意两点间的路径存在中转和不中转两种情况,如果可以从一个点进行中转,就进行比较从这个点中转和不中转的距离,存储距离小的情况,并更新距离矩阵和路由矩阵

    从算法思想中可以发现我们要遍历n个中转点,在每个中转点进行操作的时候,需要对任意两点之间的距离进行遍历。那么算法就应该有三重循环,第一重循环是遍历中转点,第二重和第三重循环是遍历任意两个点之间的距离。而更新距离矩阵的条件就是
    D ( i , K ) + D ( K , j ) < D ( i , j ) D(i, K)+D(K, j)<D(i, j) D(i,K)+D(K,j)<D(i,j)
    更新为: D ( i , j ) = D ( i , K ) + D ( K , j ) D(i,j)=D(i, K)+D(K, j) D(i,j)=D(i,K)+D(K,j)

    这个时候就需要更新我们的路由矩阵: R ( i , j ) = R ( i , K ) R(i,j)=R(i,K) R(i,j)=R(i,K)

    路由矩阵很好理解,比如最开始是 R ( 4 , 3 ) = 3 R(4,3) = 3 R(4,3)=3,表示V4到V3一步就可以到达V3,如果现在可以从V2中转到达,那么 R ( 4 , 3 ) = R ( 4 , 2 ) = 2 R(4,3) = R(4,2) =2 R(4,3)=R(4,2)=2,表示V4->V3​要先经过V2才能到达。

    因此,我们就可以给出代码:

    function [D,path,min1,path1]=floyd(a,start,terminal)
    D=a;n=size(D,1);path=zeros(n,n);
    for i=1:n
        for j=1:n
            if D(i,j)~=inf
                path(i,j)=j;
            end
        end
    end
    for k=1:n
        for i=1:n
            for j=1:n
                if D(i,k)+D(k,j)<D(i,j)
                    D(i,j)=D(i,k)+D(k,j);
                    path(i,j)=path(i,k);
                end
            end
        end
    end
    if nargin==3
        min1=D(start,terminal);
        m(1)=start;
        i=1;
        path1=[ ]; 
        while path(m(i),terminal)~=terminal
            k=i+1;
            m(k)=path(m(i),terminal);
            i=i+1;
        end
        m(i+1)=terminal;
        path1=m;
    end
    

    依然使用刚才的矩阵:

    a = [0,50,inf,40,25,10;
        50,0,15,20,inf,25;
        inf,15,0,10,20,inf;
        40,20,10,0,10,25;
        25,inf,20,10,0,55;
        10,25,inf,25,55,0];
    %不相连的顶点间距离设为无穷远
    [D,path]=floyd(a)
    

    可获得结果为:

    D =
    
         0    35    45    35    25    10
        35     0    15    20    30    25
        45    15     0    10    20    35
        35    20    10     0    10    25
        25    30    20    10     0    35
        10    25    35    25    35     0
    
    
    path =
    
         1     6     5     5     5     6
         6     2     3     4     4     6
         5     2     3     4     5     4
         5     2     3     4     5     6
         1     4     3     4     5     1
         1     2     4     4     1     6
    

    Bellman-Ford算法

    Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的。此时,Bellman-Ford算法就是一种可行的方法。

    给定图G(V, E)(其中V、E分别为图G的顶点集与边集),源点s,数组Distant[i]记录从源点s到顶点i的路径长度,初始化数组Distant[n]为inf, Distant[s]为0;

    以下操作循环执行至多n-1次,n为顶点数:
    对于每一条边e(u, v),如果Distant[u] + w(u, v) < Distant[v],则另Distant[v] = Distant[u]+w(u, v)。w(u, v)为边e(u,v)的权值;
    若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环。否则执行下次循环;

    为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在Distant[u] + w(u, v) < Distant[v]的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组Distant[n]中记录的就是源点s到各顶点的最短路径长度。

    Bellman-Ford算法可以大致分为三个部分
    第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。
    第二,进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。
    第三,遍历途中所有的边(e(u,v)),判断是否存在这样情况:
    d ( v ) > d ( u ) + w ( u , v ) d(v) > d (u) + w(u,v) dv>d(u)+w(u,v)
    若存在,则返回错误,表示途中存在从源点可达的权为负的回路。

    以下给出代码实现:

    function Bellman_Ford(d,n,s)
    %d为已知图的邻接矩阵,n为顶点数(各顶点标号为1,2,...,n),s为源点标号
    for i=1:n %初始化dist,pre
        dist(i)=inf; %dist(i)为s,i之间的最短路的长度
        pre(i)=NaN; %pre(i)为s到i的最短路上i的前一个顶点
    end
    dist(s)=0;
    for k=1:n-1
        for i=1:n 
            for j=1:n
                if d(i,j)~=inf
                    if dist(j)>dist(i)+d(i,j)
                        dist(j)=dist(i)+d(i,j);
                        pre(j)=i;
                    end
                end
            end
        end
    end
    for i=1:n
        for j=1:n
            if d(i,j)~=inf
                if dist(i)+d(i,j)<dist(j)%判断有无负权回路
                    error('Negetive WeightCircut');
                end
            end
        end
    end
    dist
    pre
    end
    
    clc;clear
    w=[0 -2 1 8 inf inf inf inf;2 0 inf 6 1 inf inf inf;1 inf 0 7 inf inf 9 inf;...
          8 6 7 0 5 1 2 inf;inf 1 inf 5 0 3 inf 9;inf inf inf 1 3 0 4 6;...
          inf inf 9 2 inf 4 0 3;inf inf inf inf 9 6 3 0];
    i=1;m=8;
    
    Bellman_Ford(w,m,i)
    

    输出结果为:

    dist =
    
         0    -2     1     3    -1     2     5     8
    
    
    pre =
    
       NaN     1     1     6     2     5     4     5
    

    如果在其中添加负权回路

    clc;clear
    w=[0 -2 1 -8 inf inf inf inf;2 0 inf 6 1 inf inf inf;1 inf 0 7 inf inf 9 inf;
          8 6 7 0 5 1 2 inf;inf 1 inf 5 0 3 inf 9;inf inf inf 1 3 0 4 6;
          inf inf 9 2 inf 4 0 3;inf inf inf inf 9 6 3 0];
    i=1;m=8;
    
    Bellman_Ford(w,m,i)
    

    输出为

    错误使用 Bellman_Ford (line 24)
    Negetive WeightCircut
    

    Johnson 算法

    Johnson算法主要用于求稀疏图上的全源最短路径,可以处理存在负权的图,其主体思想是利用重赋权值的方法把一个带负权的图转化为权值非负的图,然后再利用N次Dijkstra算法求出全源最短路径。

    其中,对图的权值进行重赋的过程是:

    在图G中增加一个新结点S,并让其与其他结点相连,形成一幅新图G’,对G’进行Bellman-Ford算法计算从S到各结点的最短路径h,删除结点S,然后根据新权重确定公式:
    w ′ ( u , v ) = w ( u , v ) + h ( u ) − h ( v ) w'(u,v)=w(u,v)+h(u)-h(v) w(u,v)=w(u,v)+h(u)h(v)
    对原图的权重进行修改,使得权重都为正。

    然后进行n次Dijkstra算法即可。

    展开全文
  • 在地图上找到从起始节点到结束节点的最短路径和距离** 2. 找出地图上从起始节点到所有其他节点的最短路径和距离** **地图应由节点和段组成,例如: 1.节点的格式为[ID XY]或[ID XYZ](ID为整数,X,Y,Z代表位置坐标...
  • 蚁群算法最短路径通用Matlab程序(附图)function [ROUTES,PL,Tau]=ACASP(G,Tau,K,M,S,E,Alpha,Beta,Rho,Q)%% --------------------------------------------------------------- % ACASP.m% 蚁群算法动态寻路算法% ...

    蚁群算法最短路径通用Matlab程序(附图)

    ccb1cf5d58041274eb06d54e6b75df49.png

    function [ROUTES,PL,Tau]=ACASP(G,Tau,K,M,S,E,Alpha,Beta,Rho,Q)

    %% --------------------------------------------------------------- % ACASP.m

    % 蚁群算法动态寻路算法

    % ChengAihua,PLA Information Engineering University,ZhengZhou,China % Email:aihuacheng@http://www.doczj.com/doc/35b628aed1f34693daef3e59.html

    % All rights reserved

    %% --------------------------------------------------------------- % 输入参数列表

    % G 地形图为01矩阵,如果为1表示障碍物

    % Tau 初始信息素矩阵(认为前面的觅食活动中有残留的信息素)

    % K 迭代次数(指蚂蚁出动多少波)

    % M 蚂蚁个数(每一波蚂蚁有多少个)

    % S 起始点(最短路径的起始点)

    % E 终止点(最短路径的目的点)

    % Alpha 表征信息素重要程度的参数

    % Beta 表征启发式因子重要程度的参数

    % Rho 信息素蒸发系数

    % Q 信息素增加强度系数

    %

    % 输出参数列表

    % ROUTES 每一代的每一只蚂蚁的爬行路线

    % PL 每一代的每一只蚂蚁的爬行路线长度

    % Tau 输出动态修正过的信息素

    %% --------------------变量初始化---------------------------------- %load

    D=G2D(G);

    N=size(D,1);%N表示问题的规模(象素个数)

    MM=size(G,1);

    a=1;%小方格象素的边长

    Ex=a*(mod(E,MM)-0.5);%终止点横坐标

    if Ex==-0.5

    Ex=MM-0.5;

    end

    Ey=a*(MM+0.5-ceil(E/MM));%终止点纵坐标

    Eta=zeros(1,N);%启发式信息,取为至目标点的直线距离的倒数

    %下面构造启发式信息矩阵

    for i=1:N

    if ix==-0.5

    展开全文
  • 含有各种障碍物的,水平面两点间最短的距离算法。就相当于计算你从一个地方走到另一个地方,最短路径。 注意:不是图论!不是节点!不是Dijkstra!不是Floyd!
  • 求K条最短路径的必要性最短路径问题分为:单源最短路径所有顶点对间的最短路径共同的缺陷:这里的最短路径指两点间最短的那一条路径,不包括次短、再次短等路径。这样的最短路径问题比较狭义。在实际情况中,例如:...

    一、问题介绍

    1.求K条最短路径的必要性

    最短路径问题分为:

    单源最短路径

    所有顶点对间的最短路径

    共同的缺陷:

    这里的最短路径指两点间最短的那一条路径,不包括次短、再次短等路径。这样的最短路径问题比较狭义。

    在实际情况中,例如:用户在使用咨询系统或决策支持系统时,希望得到最优的决策参考外,还希望得到次优、再次优等决策参考,这同样反映在最短路径问题上。因此有必要将最短路径问题予以扩展和延伸,称为K条最短路径问题,即不但要求得最短路径,还要求得次短、再次短等路径。

    2.KSP问题定义

    KSP问题是对最短路径问题的推广,它除了要确定最短路径之外,还要确定次短路径、第三短路径,...,知道找到第K短路径。用Pi表示从起点s到终点t的第i短路径,KSP问题是确定路径集合Pk={p1,p2,p3,...,pk},使得满足以下3个条件:

    1)K条路径是按次序产生的,即对于所有的i(i=1,2,...,K-1),pi是在pi+1之前确定;

    2)K条路径是按长度从小到大排列的,即对于所有的i(i=1,2,...,K-1),都有c(pi)

    3)这K条路径是最短的,即对于所有的p∈Pst-PK,都有c(pk)

    ea0e6894259b

    3.相关概念

    ea0e6894259b

    用于说明偏离概念的图

    设起点为 1 ,终点为 5 。p1、p2、p3 分别表示起点到终点间最短路径、第二短路径、第三短路径。

    1)偏离点

    p3相对于p1的偏离节点为节点 2

    2)偏离边

    p3相对于p1的偏离边为(2,4)

    3)偏离路径

    p3相对于p1的(2,4,5)

    4.KSP算法分类

    1) 一般KSP问题

    对路径没有任何限制

    2) 限定无环KSP问题

    要求所有路径都是简单路径,不能有环

    当路径中所有节点都不同时,称为无环路径

    两类KSP问题具有不同的特征,分别提出了不同的求解算法,分别称之为

    一般的KSP算法

    限定无环KSP算法

    ea0e6894259b

    K最短路径算法分类

    二、思路

    下面列出用Yen's算法求KSP的代码。该算法是Yen在1971年提出的以其名字命名的Yen算法。算法采用了递推法中的偏离路径算法思想,适用于非负权边的有向无环图。

    1.流程图

    ea0e6894259b

    Q:将什么样的点做为偏离点

    在pk的基础上求pk+1时,将pk的路径上除终点d之外的节点分别作为偏离点

    Q:求Vi到终点d的最短路径

    设起点为s,终点为t,偏离点为Vi。求偏离点到终点的最短路径时要注意两个问题

    防止从起点到终点的整体路径有环

    从Vi到t的最短路径不能包含s到Vi的路径上的任何节点

    避免与已经在结果列表中的路径重复

    从Vi发出的边不能与结果列表中的路径p1,p2,...pk,上从Vi发出边的相同

    这个体现在代码上就是:在用Dijkstra算法算最短路径时对数组的初始化要进行特别处理

    // 不能走的边

    if (unavailableEdges != null && unavailableEdges.size() != 0) {

    for (MyPath p: unavailableEdges) {

    int index = p.path.indexOf(startIndex);

    if (index >= 0 && (index + 1) >= 0) {

    dist[index + 1] = Double.MAX_VALUE;

    path[index + 1] = -1;

    }

    }

    }

    // 不能走的点

    if (unavailableNodeIndexs != null && unavailableNodeIndexs.size() != 0) {

    for (Integer point: unavailableNodeIndexs) {

    set[point] = 1;

    }

    }

    Q:每次找到新的最短路径时,需将该路径从候选链列表中移除,并加入到结果列表中

    Q:候选列表中的路径不能重复

    所以选择用Set来存储候选路径,去重

    Q:如何从候选列表中选出合适的路径

    如果只有一条路径权值和最小的路:将该路径返回;

    如果路径权值和最小的路有多条:从其中选出节点数最少的路径。

    2.手工模拟求K最短路径流程

    求C到H的10条最短路径

    ea0e6894259b

    节点加载内存后存储在Node[] nodes数组中,各个节点在数组中的存储位置如下,下面用各个点的数组下标进行说明。表格中括号中备注为路径权重。

    ea0e6894259b

    1)通过最短路径算法Dijkstra得到C到H的最短路径

    p1=C-E-F-H,即0-2-3-5

    2)在p1的基础上求p2

    ea0e6894259b

    遍历完各个偏离点后的情况:

    ea0e6894259b

    从集合B中选出路径0->2->4->5(7)移除,并加入到集合A中,作为p2

    ea0e6894259b

    3)在p2的基础上求p3

    ea0e6894259b

    遍历完各个偏离点后的情况:

    ea0e6894259b

    从集合B中选出路径0->1->3->5(8)移除,并加入到集合A中,作为p3

    ea0e6894259b

    4)在p3的基础上求p4

    ea0e6894259b

    遍历完各个偏离点后的情况:

    ea0e6894259b

    从集合B中选出路径0->1->3->5(8)移除,并加入到集合A中,作为p4

    ea0e6894259b

    5)在p4的基础上求p5

    ea0e6894259b

    遍历完各个偏离点后的情况:

    ea0e6894259b

    从集合B中选出路径0->2->3->4->5(8)移除,并加入到集合A中,作为p5`

    ea0e6894259b

    6)在p5的基础上求p6

    ea0e6894259b

    遍历完各个偏离点后,没有新的候选路径加入集合B中

    ea0e6894259b

    从集合B中选出路径0->1->3->4->5(11)移除,并加入到集合A中,作为p6

    ea0e6894259b

    7)在p6的基础上求p7

    遍历各个偏离点时求最短路径均不存在,故遍历完各个偏离点后,没有新的候选路径加入集合B中,从集合B中选出路径0->2->1->3->4->5(11)移除,并加入到集合A中,作为p7

    ea0e6894259b

    8)在p7的基础上求p8

    遍历各个偏离点时求最短路径均不存在,故遍历完各个偏离点后,没有新的候选路径加入集合B中,候选集合为空,不能再继续向下寻找。故从C到H共有7条路径。

    三、代码

    1.输入上述图

    6 9

    11 C

    12 D

    13 E

    14 F

    15 G

    16 H

    11 12 3

    11 13 2

    12 14 4

    13 12 1

    13 14 2

    13 15 3

    14 15 2

    14 16 1

    15 16 2

    11 16 10

    2.代码

    package road;

    import util.NavigationUtil;

    import java.util.*;

    /**

    *

    
     

    * author : 杨丽金

    * time : 2018/11/14

    * desc : 有关于图的最短路径

    * version: 1.0

    *

    */

    public class ShortestPath {

    public static class MyPath {

    // 路径上的各个节点对应的数组下标(从起点到终点)

    public List < Integer > path;

    // 路径总权值

    public double weight;

    // 路径上节点个数:通过path.size()得到

    public MyPath() {}

    public MyPath(List < Integer > path, double weight) {

    this.path = path;

    this.weight = weight;

    }

    @Override

    public String toString() {

    return "MyPath{" +

    "path=" + path +

    ", weight=" + weight +

    '}';

    }

    @Override

    public boolean equals(Object o) {

    if (this == o) return true;

    if (o == null || getClass() != o.getClass()) return false;

    MyPath path1 = (MyPath) o;

    return path != null ? path.equals(path1.path) : path1.path == null;

    }

    @Override

    public int hashCode() {

    int result;

    long temp;

    result = path != null ? path.hashCode() : 0;

    temp = Double.doubleToLongBits(weight);

    result = 31 * result + (int)(temp ^ (temp >>> 32));

    return result;

    }

    }

    /**

    * 用Yen's KSP算法从图中找出从startIndex到endIndex的K条最短路径

    *

    * @param g

    * @param startIndex:起始节点的数组下标

    * @param endIndex:终止节点的数组下标

    * @param K:要求的最短路径数目

    * @return

    */

    public List < MyPath > KSP_Yen(MyGraph g, int startIndex, int endIndex, int K) {

    // 结果列表

    List < MyPath > result = new ArrayList < > ();

    // 候选路径列表

    Set < MyPath > candidatePaths = new HashSet < > ();

    // 候选路径列表中权值最小的路径,及其对应的节点个数

    // 第一条最短路径

    MyPath p1 = getSingleShortestPath_dijkstra(g, startIndex, endIndex, null, null);

    result.add(p1);

    int k = 1;

    List < Integer > pk = p1.path;

    while (k < K) {

    /*

    求第k+1条最短路径

    */

    // 遍历每一个偏离点

    for (int i = 0; i <= pk.size() - 2; i++) {

    // 1,pk路径中起点到偏离点Vi的路径权值

    double w1 = 0;

    for (int j = 0; j <= i - 1; j++) {

    w1 += NavigationUtil.getEdgeWight(g, pk.get(j), pk.get(j + 1));

    }

    // 2,偏离点到终点的最短路径

    MyPath viToDestinationSP = getSingleShortestPath_dijkstra(g,

    pk.get(i), endIndex, pk.subList(0, i), result);

    if (viToDestinationSP != null) {

    // 说明从这个偏离点可以到达终点

    MyPath temp = new MyPath();

    List < Integer > tempPath = new ArrayList < > (pk.subList(0, i));

    tempPath.addAll(viToDestinationSP.path);

    temp.path = tempPath;

    temp.weight = w1 + viToDestinationSP.weight;

    // 加入候选列表

    if (!candidatePaths.contains(temp)) {

    candidatePaths.add(temp);

    }

    }

    }

    if (candidatePaths == null || candidatePaths.size() == 0) {

    // 没有候选路径,则无需再继续向下求解

    break;

    } else {

    // 从候选路径中选出最合适的一条,移除并加入到结果列表

    MyPath fitPath = getFitPathFromCandidate(candidatePaths);

    candidatePaths.remove(fitPath);

    result.add(fitPath);

    k++;

    pk = fitPath.path;

    }

    }

    return result;

    }

    /**

    * 从候选列表中得到一条路径作为pk+1

    * 要求:1)该路径的权值和最小;2)路径经过节点数最少

    * @param candidatePaths:候选列表

    * @return

    */

    private MyPath getFitPathFromCandidate(Set < MyPath > candidatePaths) {

    MyPath result = new MyPath(null, Double.MAX_VALUE);

    for (MyPath p: candidatePaths) {

    // 对于每一条路径

    if (p.weight < result.weight) {

    result = p;

    }

    if (p.weight == result.weight && p.path.size() < result.path.size()) {

    result = p;

    }

    }

    return result;

    }

    /**

    * 用Dijkstra算法得到从startIndex到endIndex的一条最短路径

    *

    * @param g

    * @param startIndex 起始节点的数组下标

    * @param endIndex 终止节点的数组下标

    * @param unavailableNodeIndexs:求最短路径时不可用的节点(数组下标)

    * @param unavailableEdges:求最短路径时不可用的边

    * @return

    */

    public MyPath getSingleShortestPath_dijkstra(MyGraph g, int startIndex, int endIndex,

    List < Integer > unavailableNodeIndexs, List < MyPath > unavailableEdges) {

    if (startIndex == -1) {

    // throw new Exception("getSingleShortestPath_dijkstra()起始点编号输入错误");

    }

    if (endIndex == -1) {

    // throw new Exception("getSingleShortestPath_dijkstra()终止点编号输入错误");

    }

    int[] set = new int[g.n]; // 是否已并入集合,该点是否已找到最短路径

    // s到i的最短路径长度

    double[] dist = new double[g.n];

    // s到i的最短路径上i的前一个节点编号

    int[] path = new int[g.n];

    // 初始化数组

    set[startIndex] = 1;

    for (int i = 0; i < g.n; i++) {

    if (i == startIndex) { // 源点

    dist[i] = 0;

    path[i] = -1;

    } else {

    if (NavigationUtil.isConnected(g, startIndex, i)) {

    dist[i] = NavigationUtil.getEdgeWight(g, startIndex, i);

    path[i] = startIndex;

    } else {

    dist[i] = Double.MAX_VALUE;

    path[i] = -1;

    }

    }

    }

    // 不能走的边

    if (unavailableEdges != null && unavailableEdges.size() != 0) {

    for (MyPath p: unavailableEdges) {

    int index = p.path.indexOf(startIndex);

    if (index >= 0 && (index + 1) >= 0) {

    dist[p.path.get(index + 1)] = Double.MAX_VALUE;

    path[p.path.get(index + 1)] = -1;

    }

    }

    }

    // 不能走的点

    if (unavailableNodeIndexs != null && unavailableNodeIndexs.size() != 0) {

    for (Integer point: unavailableNodeIndexs) {

    set[point] = 1;

    }

    }

    // 需进行n-2轮循环

    for (int i = 0; i < g.n - 2; i++) {

    int k = -1;

    double min = Double.MAX_VALUE;

    // 找出dist[]中最小的(太贪心了)

    for (int j = 0; j < g.n; j++) {

    if (set[j] == 1) {

    continue;

    }

    if (dist[j] < min) {

    min = dist[j];

    k = j;

    }

    }

    if (k == -1) {

    // 说明从源点出发与其余节点不连通,无法再向下进行扩展

    break;

    }

    set[k] = 1; // 把节点k并入

    // 修改dist[]、path[]

    for (int j = 0; j < g.n; j++) {

    if (set[j] == 1) {

    continue;

    }

    if (NavigationUtil.isConnected(g, k, j)) {

    double temp = dist[k] + NavigationUtil.getEdgeWight(g, k, j);

    if (temp < dist[j]) {

    dist[j] = temp;

    path[j] = k;

    }

    }

    }

    }

    System.out.println("运行Dijkstra算法后的数组情况为:");

    System.out.print("set[]:");

    for (int i = 0; i < g.n; i++) {

    System.out.print(set[i] + "\t");

    }

    System.out.println();

    System.out.print("dist[]:");

    for (int i = 0; i < g.n; i++) {

    System.out.print(dist[i] + "\t");

    }

    System.out.println();

    System.out.print("path[]:");

    for (int i = 0; i < g.n; i++) {

    System.out.print(path[i] + "\t");

    }

    System.out.println();

    // 输出

    if (dist[endIndex] == Double.MAX_VALUE) {

    // 说明没有最短路径,两点不连通

    System.out.println("两点之间不连通");

    return null;

    } else {

    System.out.println("节点" + g.nodes[startIndex].nodeId + "到节点" +

    g.nodes[endIndex].nodeId + "的最短路径长度为:" + dist[endIndex] + ",具体路径是:");

    MyPath result = new MyPath();

    result.path = getMinimumPath(g, startIndex, endIndex, path);

    result.weight = dist[endIndex];

    return result;

    }

    }

    /**

    * 输出从节点S到节点T的最短路径

    *

    * @param sIndex:起始节点在数组中下标

    * @param tIndex:终止节点在数组中下标

    */

    private List < Integer > getMinimumPath(MyGraph g, int sIndex, int tIndex, int[] path) {

    List < Integer > result = new ArrayList < > ();

    Stack < Integer > stack = new Stack < > ();

    stack.push(tIndex);

    int i = path[tIndex];

    while (i != -1) {

    stack.push(i);

    i = path[i];

    }

    while (!stack.isEmpty()) {

    System.out.print(g.nodes[stack.peek()].nodeId + ":" + g.nodes[stack.peek()].nodeName + "-->");

    result.add(NavigationUtil.getIndex(g, g.nodes[stack.pop()].nodeId));

    }

    System.out.println();

    return result;

    }

    }

    3.输出

    sps: [MyPath {

    path = [0, 2, 3, 5], weight = 5.0

    }, MyPath {

    path = [0, 2, 4, 5], weight = 7.0

    }, MyPath {

    path = [0, 1, 3, 5], weight = 8.0

    }, MyPath {

    path = [0, 2, 1, 3, 5], weight = 8.0

    }, MyPath {

    path = [0, 2, 3, 4, 5], weight = 8.0

    }, MyPath {

    path = [0, 1, 3, 4, 5], weight = 11.0

    }, MyPath {

    path = [0, 2, 1, 3, 4, 5], weight = 11.0

    }]

    参考文献

    [1]K条最短路径问题综述

    [2]韩海玲. 基于城市路网的最短路径算法研究与应用[D]. 中北大学, 2017.

    [3]徐涛, 丁晓璐, 李建伏. K最短路径算法综述[J]. 计算机工程与设计, 2013, 34(11):3900-3906.

    [4]K条最短路径算法(KSP, k-shortest pathes):Yen's Algorithm

    展开全文
  • 基于蚁群算法寻求最短路径matlab仿真
  • 粒子群算法 实现 最短路径,解决TSL多旅行商问题,以此为基础解决VRP问题
  • MATLAB-K最短路径算法(KSP,K-shortest pathes)

    千次阅读 热门讨论 2020-10-16 17:30:12
    MATLAB-K最短路径算法(KSP,K-shortest pathes) MATLAB代码封装成函数,直接使用。 参考: k最短路径算法之Yen’s Algorithm 基于网络流量的SDN最短路径转发应用 算法背景 K 最短路径问题是最短路径问题的扩展和变形...

    MATLAB-K最短路径算法(KSP,K-shortest pathes)

    MATLAB代码封装成函数,直接使用。

    参考:

    k最短路径算法之Yen’s Algorithm
    基于网络流量的SDN最短路径转发应用

    算法背景

    K 最短路径问题是最短路径问题的扩展和变形。1959 年,霍夫曼(Hoffman) 和帕夫雷(Pavley)在论文中第一次提出k 最短路径问题。 k 最短路径问题通常包括两类:有限制的k 最短路问题和无限制的K 最短路问题。 前者要求最短路径集合不含有回路,而后者对所求得的最短路径集合无限制。

    算法简介

    Yen’s算法是Yen 在1971 年提出的以其名字命名 的Yen 算法。Yen’s算法采用了递推法中的偏离路径算法思想,适用于非负权边的有向无环图结构。

    算法思想

    算法可分为两部分,算出第1条最短路径P(1),然后在此基础上依次依次算出其他的K-1条最短路径。在求P(i+1) 时,将P(i)上除了终止节点外的所有节点都视为偏离节点,并计算每个偏离节点到终止节点的最短路径,再与之前的P(i)上起始节点到偏离节点的路径拼接,构成候选路径,进而求得最短偏离路径。
    ##算法实例
    在这里插入图片描述
    根据个人的理解,我归纳出了以下步骤:

    调用K条最短路径算法,源C,目的H,K为3。B为偏离路径集合。

    1.通过Dijkstra算法计算得到最短路径A^1:C-E-F-H,其中,花费为5,A[1] = C-E-F-H

    2.将A[1]作为迭代路径,进行第一次迭代:

    (1)以部分迭代路径(即A[1])C路径中,C点为起点,将C-E路径之间的权值设为无穷大,进行一次Dijkstra,得到路径A^2-1:C-D-F-H,花费为8,将A^2-1路径加入B;

    (2)以部分迭代路径(即A[1])C-E路径中,E为起点,将E-F路径之间的权值设为无穷大,进行一次Dijkstra,得到路径A^2-2:C-E-G-H,花费为7,将A^2-2路径加入B;

    (3)以部分迭代路径(即A[1])C-E-F路径中,F为起点,将F-H路径之间的权值设为无穷大,进行一次Dijkstra,得到路径A^2-3:C-E-F-G-H,花费为8,将A^2-3路径加入B;

    迭代完成,B集合中有三条路径:C-D-F-H,C-E-G-H,C-E-F-G-H;选出花费最小的偏离路径C-E-G-HA[2] = C-E-G-H,移出B集合。

    3.将A[2]作为迭代路径,进行第二次迭代:

    (1)以部分迭代路径(即A[2])C路径中,C点为起点,将C-E路径之间的权值设为无穷大,进行一次Dijkstra,得到路径A^3-1:C-D-F-H,但B集合已存在该路径,故不存在偏移路径;

    (2)以部分迭代路径(即A[2])C-E路径中,E点为起点,将E-G、E-F路径之间的权值设为无穷大 (注意,这里设置两条路径的权值原因是这两条路径分别存在于A[1]和A[2]中),进行一次Dijkstra,得到路径A^3-2:C-E-D-F-H,花费为8,将A^3-2加入B;

    (3)以部分迭代路径(即A[2])C-E-G路径中,G点为起点,将C-H路径之间的权值设为无穷大,不存在偏移路径。

    迭代完成,B集合中有三条路径:C-D-F-H,C-E-F-G-H,C-E-D-F-H;由于三条路径花费均为8,则根据最小节点数进行判断,选出偏离路径C-D-F-H,A[3] = C-D-F-H

    此时,选出了三条最短路径,分别是:

    A[1] = C-E-F-H
    
    A[2] = C-E-G-H
    
    A[3] = C-D-F-H
    

    matlab代码:

    函数已封装成模块,可直接使用。

    % 文件名:kShortestPath.m
    % 时间:20201016% 作者:乐观的阿锡
    % 功能:K最短路径算法
    function [shortestPaths, totalCosts] = kShortestPath(netCostMatrix, source, destination, k_paths)  
      
    if source > size(netCostMatrix,1) || destination > size(netCostMatrix,1)  
        warning('The source or destination node are not part of netCostMatrix');  
        shortestPaths=cell(1,k_paths);        %定义最短路径为元胞数组
        totalCosts=zeros(1,k_paths);  
    else  
        %---------------------INITIALIZATION---------------------  
        k=1;  
        [path cost] = dijkstra(netCostMatrix, source, destination);  
        %P is a cell array that holds all the paths found so far:  
        if isempty(path)  
            shortestPaths=cell(1,k_paths);  
            totalCosts=zeros(1,k_paths);  
        else  
            path_number = 1;   
            P{path_number,1} = path; P{path_number,2} = cost;   
            current_P = path_number;  
            %X is a cell array of a subset of P (used by Yen's algorithm below):  
            size_X=1;    
            X{size_X} = {path_number; path; cost};  
      
            %S path_number x 1  
            S(path_number) = path(1); %deviation vertex is the first node initially  偏离顶点是最初的第一个顶点
      
            % K = 1 is the shortest path returned by dijkstra():  
            shortestPaths{k} = path ;  
            totalCosts(k) = cost;  
      
            %--------------------------------------------------------  
            while (k < k_paths   &&   size_X ~= 0 )  
                %remove P from X  
                for i=1:length(X)  
                    if  X{i}{1} == current_P  
                        size_X = size_X - 1;  
                        X(i) = [];%delete cell  
                        break;  
                    end  
                end  
      
                %---------------------------------------  
                P_ = P{current_P,1}; %P_ is current P, just to make is easier for the notations  
      
                %Find w in (P_,w) in set S, w was the dev vertex(偏离顶点) used to found P_  
                w = S(current_P);  
                for i = 1: length(P_)  
                    if w == P_(i)  
                        w_index_in_path = i;  
                    end  
                end  
      
      
                for index_dev_vertex= w_index_in_path: length(P_) - 1   %index_dev_vertex is index in P_ of deviation vertex  
                    temp_netCostMatrix = netCostMatrix;  
                    %------  
                    %Remove vertices in P before index_dev_vertex and there incident edges 
                    for i = 1: index_dev_vertex-1  
                        v = P_(i);  
                        temp_netCostMatrix(v,:)=inf;  
                        temp_netCostMatrix(:,v)=inf;  
                    end  
                    %------  
                    %remove incident edge of v if v is in shortestPaths (K) U P_  with similar sub_path to P_....  
                    SP_sameSubPath=[];  
                    index =1;  
                    SP_sameSubPath{index}=P_;  
                    for i = 1: length(shortestPaths)  
                        if length(shortestPaths{i}) >= index_dev_vertex  
                            if P_(1:index_dev_vertex) == shortestPaths{i}(1:index_dev_vertex)  
                                index = index+1;  
                                SP_sameSubPath{index}=shortestPaths{i};  
                            end  
                        end              
                    end         
                    v_ = P_(index_dev_vertex);  
                    for j = 1: length(SP_sameSubPath)  
                        next = SP_sameSubPath{j}(index_dev_vertex+1);  
                        temp_netCostMatrix(v_,next)=inf;     
                    end  
                    %------  
      
                    %get the cost of the sub path before deviation vertex v  
                    sub_P = P_(1:index_dev_vertex);  
                    cost_sub_P=0;  
                    for i = 1: length(sub_P)-1  
                        cost_sub_P = cost_sub_P + netCostMatrix(sub_P(i),sub_P(i+1));  
                    end  
      
                    %call dijkstra between deviation vertex to destination node      
                    [dev_p c] = dijkstra(temp_netCostMatrix, P_(index_dev_vertex), destination);  
                    if ~isempty(dev_p)  
                        path_number = path_number + 1;  
                        P{path_number,1} = [sub_P(1:end-1) dev_p] ;  %concatenate sub path- to -vertex -to- destination  
                        P{path_number,2} =  cost_sub_P + c ;  
      
                        S(path_number) = P_(index_dev_vertex);  
      
                        size_X = size_X + 1;   
                        X{size_X} = {path_number;  P{path_number,1} ;P{path_number,2} };  
                    else  
                        %warning('k=%d, isempty(p)==true!\n',k);  
                    end        
                end  
                %---------------------------------------  
                %Step necessary otherwise if k is bigger than number of possible paths  
                %the last results will get repeated !  
                if size_X > 0  
                    shortestXCost= X{1}{3};  %cost of path  
                    shortestX= X{1}{1};        %ref number of path  
                    for i = 2 : size_X  
                        if  X{i}{3} < shortestXCost  
                            shortestX= X{i}{1};  
                            shortestXCost= X{i}{3};  
                        end  
                    end  
                    current_P = shortestX;  
                    %******  
                    k = k+1;  
                    shortestPaths{k} = P{current_P,1};  
                    totalCosts(k) = P{current_P,2};  
                    %******  
                else  
                    %k = k+1;  
                end  
            end  
        end  
    end  
    

    算法演示

    网络拓扑图如下:
    在这里插入图片描述
    在这里插入图片描述

    算法步骤

    作为Dijkstra 最短路径算法的扩展,K 最短路径算法可以在给定有向图中确定K条候选路径且每条路径可提供从源节点到目的节点的最小权重和。为了实现K最短路径算法,应用Dijkstra算法和路径偏离的思想,更具体地说,首先通过Dijkstra算法找出源节点和目的节点之间的最短路径,再依次移除最短路径上的每条链路,重新计算源节点和目的节点之间的最短路径,重复该过程,直到找到K条路径。
    基于K最短路径算法的路由选择过程的步骤可总结如下:
    (1) 表征考虑的网络图为一个权重图,设置K=1;
    (2) 在图 中应用Dijkstra算法获得单用户流的从源交换机到目的交换机的一条候选最短路径;
    (3) 依次移除最短路径上的每条链路,应用Dijkstra算法重新计算到的最短路径;
    (4) 根据获得的候选路径,选择提供最小 的一条路径;
    (5) 重复步骤(3)和步骤(4),直到 k=K;
    (6) 获得的K条路径集合置为且第K条路径对应的路由。

    参考文献

    展开全文
  • 关于动态规划最短路径求解的matlab学习例子
  • 内含最短路径算法代码及实验报告。本次实验要求利用MATLAB分别实现Dijkstra算法和Floyd算法,可对输入的邻接距离矩阵计算图中任意两点间的最短距离矩阵和路由矩阵,且能查询任意两点间的最短距离和路由。
  • matlab实现的最短路径算法Dijkstra
  • DQN最短路径MATLAB.zip

    2020-05-26 21:25:03
    不用强化学习工具箱的DQN算法案例与matlab代码,方便大家学习使用。可以在此基础上直接更改编写自己的项目
  • 此代码获取节点数的输入。 然后使用matlab中的传记工具生成节点之间距离的空间节点。 源节点和目标节点由用户给出,然后代码计算到达目的地的最短路径
  • 最短路径算法dijkstra的matlab程序。
  • Dijkstra算法最短路径代码,包括43个案例分析
  • 蚁群算法最短路径MATLAB代码实现,比较完整,需要的可以下载试一下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,861
精华内容 1,544
关键字:

最短路径算法matlab

matlab 订阅