求最短路径(dijkstra)

因为要做一道题牵扯到最小路径的算法,所以就看了看缔结斯特拉算法。
看了算法导论上面的介绍不明白,只好下了一个代码自己去看。

//单源图最短路径求法
int dijkstra(int from,int to ,int map[][N])
{
int *dis=new int[n];//源到n的距离
int *used=new int[n];//n点是否用过
int i,j,u,max=999999;
int mindis;
for(i=0;i<n;i++)
{
dis[i]=map[from][i];
used[i]=0;
}
used[from]=1;
while(!used[to])//目的地点已经加入后就停止.
{
mindis=max;
u=-1;
for(i=0;i<n;i++)
{
if(used[i]==0&&mindis>dis[i])
{
mindis=dis[i];
u=i;
}
}
s[u]=1;
for(i=0;i<n;i++)
{
if(s[i]==0)
{
if(dis[u]+masp[u][i]<dis[i])
dis[i]=dis[u]+map[u][i];
}
}
}
mindis=dis[to];
delete[] dis;
delete[] used;
return mindis;
}


看了之后自己总结的一点点的经验:

缔结斯特拉算法的步骤是这样的:

1.将点集分成两类,第一类是用过的一类是没有用过的。

2.在没有用过的点集中找到离远点距离最小的点。

3.将此点加入已用点的集合中,因为这个点的加入,源点和未用过的点的最短路径发生了变化。

4.重复上面的三项,直到终点被用了为止,即可得到源点到其他任意点的最短路径。

觉得这像是一种贪心,可是感觉又不是,因为在找最优的过程中,每个点的dis一直在变化.不知道为什么最小的路径的长度就出来了.觉得这好像是一个不可思议的事情.但求出来的确实是最短路径.让我们仔细的考虑一下这个算法的过程.当除了源点其余所有的点都没有用的时候,这些点离源点的距离就是图中真实的距离.找到最短的点放到已用的集合中,那么毋庸置疑源点到这个点的路径就定了下来就是源点直接到这个点的路径,并不需要经过其他的点来达到这个点.这是已用集合中就有了两个点,那么源点就可以经过这个点到达或不经过这个点到达其他的点(这里没有不可到达的点,不可到达的点就是路径比较长的点)。这其中做一个选择,看是经过这个点路径短一些还是不经过这个点路径短一些。所有的点做好选择后就可以形成一个新的数组,这个数组记录了源点到未用过的点的距离,同样选择一个最小的点加入到已用点中。就这样已用点集合中有了三个点,源点到其余两个点到距离已经确定。下面反复一下就可以得到源点到所有点的最短路径,线面的代码不仅可以求出路径的长度,亦可以求出路径的依次经过的点。

[4] 最短路径
(1)单源最短路径,dijkstra算法,邻接阵形式,复杂度O(n^2)
//求出源s到所有点的最短路经,传入图的顶点数n,(有向)邻接矩阵mat
//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1
//可更改路权类型,但必须非负!
#define MAXN 200
#define inf 1000000000
typedef int elem_t;

void dijkstra(int n,elem_t mat[][MAXN],int s,elem_t* min,int* pre){
int v[MAXN],i,j,k;
for (i=0;i<n;i++)
min[i]=inf,v[i]=0,pre[i]=-1;
for (min[s]=0,j=0;j<n;j++){
for (k=-1,i=0;i<n;i++)
if (!v[i]&&(k==-1||min[i]<min[k]))
k=i;
for (v[k]=1,i=0;i<n;i++)
if (!v[i]&&min[k]+mat[k][i]<min[i])
min[i]=min[k]+mat[pre[i]=k][i];
}
}

pre[i]中存储了i点的上一个点是那个。求路径的话可以这样依次的找上一个点,知道找到源点结束即可。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Dijkstra算法是一种用于计算一个节点到其他所有节点的最短路径算法。在MATLAB中实现Dijkstra算法可以使用现成的函数,如graphshortestpath()或dijkstra()。也可以自己编写代码来实现。 ### 回答2: Dijkstra算法解带权有向图最短路径问题的经典算法之一,也是Matlab中常用的算法之一。Dijkstra算法的基本思想是:从一个起点开始,通过不断更新节点的距离信息,在未遍历的节点中选取当前距起点最近的节点,然后以该节点为起点,继续遍历直到到达目标节点或无法继续遍历为止。 在Matlab中,可以使用graph对象来表示带权有向图,使用shortestpath函数来最短路径。具体步骤如下: 1. 构建带权有向图 在Matlab中,可以使用graph函数创建一个带权有向图对象。graph函数的输入为邻接矩阵或邻接表,表示图中各点之间的连接关系。邻接矩阵中每个元素表示相应边的权重,若边不存在则为0。例如,对于以下的有向图: ![image-20211215094858573](https://i.loli.net/2021/12/15/MXQFigwL5sekzRO.png) 可以使用如下代码创建graph对象: ```matlab G = graph([1 1 2 2 3 3 3 4 4],[2 3 3 4 4 5 6 5 6],[3 2 6 1 5 4 2 4 6]); LWidths = 5*G.Edges.Weight/max(G.Edges.Weight); figure; H = plot(G,'LineWidth',LWidths); ``` 2. 使用dijkstra算法最短路径 在Matlab中,可以使用shortestpath函数来最短路径。该函数的输入为起点和终点的节点编号,以及表示有向图的graph对象。例如,将以上图中1号节点为起点,6号节点为终点的最短路径出: ```matlab path = shortestpath(G,1,6); highlight(H,path,'LineWidth',2) ``` 最终输出结果为: ![image-20211215095119398](https://i.loli.net/2021/12/15/qt3K9bsJ5kwRX4H.png) 可以看到,从1号节点到6号节点的最短路径为[1 3 6],路径长度为8。 ### 回答3: Dijkstra算法是一种经典的最短路径算法,适用于所有边的非负权值图。在MATLAB中,我们可以使用Dijkstra算法来寻找图中指定两个点之间的最短路径。 首先,需要定义一个图的邻接矩阵表示。对于一个n个节点的图,邻接矩阵A,表示节点i和j之间的权值为wij。如果节点i和j之间没有边相连,则wij为无穷大。 接下来,我们需要定义一个起点。我们将起点的最短路径设置为0,其他点的最短路径初始化为无穷大。 然后,我们可以开始使用Dijkstra算法来寻找最短路径。在每次迭代中,我们选择当前未被访问的节点中最短路径最小的一个节点。然后,我们更新与该节点相邻的节点的最短路径,如果新路径比原路径更短,则更新该节点的最短路径。我们将这个被更新的节点标记为已访问。 重复上述步骤,直到我们找到了终点或没有更多节点可以访问。 最后,我们可以通过检查终点节点的最短路径来确定最短路径的长度,以及使用存储已访问节点的列表来确定最短路径的具体路径。 在MATLAB中,我们可以通过编写Dijkstra算法的代码来实现这个过程。具体实现的步骤可以参考以下示例代码: function [path, shortest_dist] = dijkstra(A, start_node, end_node) n = size(A, 1); dist = inf(1, n); visited = false(1, n); dist(start_node) = 0; for i = 1 : n-1 curr_node = find_node(dist, visited); visited(curr_node) = true; if visited(end_node) break; end for j = 1 : n if ~visited(j) && A(curr_node,j) > 0 && dist(curr_node) + A(curr_node,j) < dist(j) dist(j) = dist(curr_node) + A(curr_node,j); end end end shortest_dist = dist(end_node); % reconstructing the path path = end_node; curr_node = end_node; while curr_node ~= start_node for j = 1 : n if A(j, curr_node) > 0 && dist(j) + A(j,curr_node) == dist(curr_node) path = [j path]; curr_node = j; break; end end end end function curr_node = find_node(dist, visited) n = length(dist); min_dist = inf; curr_node = -1; for i = 1 : n if dist(i) < min_dist && ~visited(i) curr_node = i; min_dist = dist(i); end end end 此代码使用邻接矩阵A、起点和终点节点来计算最短路径,并返回路径和最短距离。在上面的代码中,我们使用了find_node函数来寻找当前未被访问的节点中最短路径最小的一个节点。 综上所述,使用Dijkstra算法最短路径问题是一种有效和常用的方法,Matlab中也提供了丰富的函数和工具来简化这一过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值