用Dijkstra算法求最短路径的MATLAB程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Dijkstra算法求最短路径的MATLAB程序相关的知识,希望对你有一定的参考价值。

问题描述:边界的范围是a*b,把这a*b的范围网格化,将这介质剖面剖分成M*N个矩形网格单元,从网格的x轴上某一点激发射线,在网格的y轴上接收到从激发点激发的射线(x轴是正方向的,y轴是负方向的)
基本要求:
一 用DIJKSTRA算法求从某一激发点到某一接收点的最短路径(为了提高计算精度,需要在每个网格单元边界上内插S*T个节点),激发点为X轴上某点(源点),接收点可以是y轴上的任一点(目标点)。
二 用户输入源点和目标点后,程序应输出源点到目标点的最短路径,并画出射线穿越图,计算出这条射线经过每个网格的长度和所穿越网格的编号(共有M*N个网格)。
在线等!~ Q859413982

你对图论的知识有了解吧~W是关联矩阵,s和t分别是起始点和终止节点的序号。返回的d为最短的加权路径长度,p为最优路径节点的序号向量。注意,这里W矩阵为0的点权值已经自动设为无穷大了。请参考《高等应用数学问题的 MATLAB一书》。我吧程序赋给你。
你做一个M函数用吧。
function [d,path]=dijkstra(W,s,t)
[n,m]=size(W);ix=(W==0);W(ix)=inf;
if n~=m,error('Square W required');end
visited(1:n)=0; dist(1:n)=inf;parent(1:n)=0;dist(s)=0;d=inf;
for i=1:(n-1),%求出每个节点与起始点的关系
ix=(visited==0);vec(1:n)=inf;vec(ix)=dist(ix);
[a,u]=min(vec);visited(u)=1;
for v=1:n,if (W(u,v)+dist(u)<dist(v)),
dist(v)=dist(u)+W(u,v);parent(v)=u;
end;end;end
if parent(t)~=0,path=t;d=dist(t);%回溯最短路径
while t~=s,p=parent(t);path=[p path];t=p;end;
end;
希望对你有用
是否可以解决您的问题?追问

不要复制粘贴的

参考技术A 这个挺好做的,有现有的算法,递归一下就好了,我现在没有现成的.m文件,不过可以告诉你怎么弄,你自己写一下就好了,c++ 大概3 4百行追问

我要MATLAB程序写的,会吗?

追答

MATLAB不熟,可以给你传本书看看,是c的,我想很容易转成matlab语言的吧,具体不知道,这个对你很重要吗?

编写的迪杰斯特拉算法求最短路径,运行不正确?

求高手!!!
在用c程序时包含文件#include<iostream>后边用加上.h吗。程序我差不多搞懂了谢谢!

你没有附上你的程序,就不方便帮你分析了。说到Dijkstra算法,大体思想就是每次从一个已找到最短路径的顶点集开始,寻找下一个可以确定最短路径的顶点。但应该注意,此算法有不足之处,就是边的权值必须为正数,否则可能结果出错。
说道具体程序呢,必然要建立在图的数据结构的基础上进行。我们一般的图的数据结构,可以用邻接矩阵,或者邻接表来实现。详情请参阅严蔚敏的《数据结构》。这里有我以前编的C++的程序,用到了STL库。不知道你们学过C++没。包含了两种图的数据结构下的Dijkstra算法。本人调试通过。

dijkstra.cpp文件
#include<iostream>
#include<vector>
#include"graph.h"

using namespace ds;
using namespace std;

typedef vector<int> PathMatrix[MAX_VERTEX_NUM];
typedef int ShortestPathTable[MAX_VERTEX_NUM];

//-----------------------邻接矩阵表示-------------------------
template<class T>
void ShortestPath_DIJ(MGraph<T> G,int v0,PathMatrix &P,ShortestPathTable &D)
int v,w,i,min;
int final[MAX_VERTEX_NUM];
for(v=0;v<G.vexnum;v++)
final[v]=FALSE;
D[v]=G.arcs[v0][v].adj;
if(D[v]<INFINITY)
P[v].push_back(v0);
P[v].push_back(v);


D[v0]=0;
final[v0]=TRUE;
for(i=1;i<G.vexnum;i++)
min=INFINITY;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&D[w]<min)
v=w;
min=D[w];

final[v]=TRUE;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&min+G.arcs[v][w].adj<D[w])
D[w]=min+G.arcs[v][w].adj;
P[w]=P[v];
P[w].push_back(w);




//================================================================

//----------------------邻接表表示------------------------------

template<class T>
void ShortestPath_DIJ(ALGraph<T> G,int v0,PathMatrix &P,ShortestPathTable &D)
int v,w,i,min;
int final[MAX_VERTEX_NUM];
ArcNode *p;
for(v=0;v<G.vexnum;v++)
final[v]=FALSE;
D[v]=INFINITY;

for(p=G.vertices[v0].firstarc;p;p=p->nextarc)
D[p->adjvex]=*(int *)(p->info);
P[p->adjvex].push_back(v0);
P[p->adjvex].push_back(p->adjvex);


D[v0]=0;
final[v0]=TRUE;

for(i=1;i<G.vexnum;i++)
min=INFINITY;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&D[w]<min)
v=w;
min=D[w];

final[v]=TRUE;
for(p=G.vertices[v].firstarc;p;p=p->nextarc)
w=p->adjvex;
if(!final[w] && min<INFINITY && min+*(int *)(p->info)<D[w])
D[w]=min+*(int *)(p->info);
P[w]=P[v];
P[w].push_back(w);





//================================================================

调用的graph.h文件比较长,包含了两种图的数据结构的各种基本操作,全文如下:
#include<iostream>
#include<vector>
#include"graph.h"

using namespace ds;
using namespace std;

typedef vector<int> PathMatrix[MAX_VERTEX_NUM];
typedef int ShortestPathTable[MAX_VERTEX_NUM];

//-----------------------邻接矩阵表示-------------------------
template<class T>
void ShortestPath_DIJ(MGraph<T> G,int v0,PathMatrix &P,ShortestPathTable &D)
int v,w,i,min;
int final[MAX_VERTEX_NUM];
for(v=0;v<G.vexnum;v++)
final[v]=FALSE;
D[v]=G.arcs[v0][v].adj;
if(D[v]<INFINITY)
P[v].push_back(v0);
P[v].push_back(v);


D[v0]=0;
final[v0]=TRUE;
for(i=1;i<G.vexnum;i++)
min=INFINITY;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&D[w]<min)
v=w;
min=D[w];

final[v]=TRUE;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&min+G.arcs[v][w].adj<D[w])
D[w]=min+G.arcs[v][w].adj;
P[w]=P[v];
P[w].push_back(w);




//================================================================

//----------------------邻接表表示------------------------------

template<class T>
void ShortestPath_DIJ(ALGraph<T> G,int v0,PathMatrix &P,ShortestPathTable &D)
int v,w,i,min;
int final[MAX_VERTEX_NUM];
ArcNode *p;
for(v=0;v<G.vexnum;v++)
final[v]=FALSE;
D[v]=INFINITY;

for(p=G.vertices[v0].firstarc;p;p=p->nextarc)
D[p->adjvex]=*(int *)(p->info);
P[p->adjvex].push_back(v0);
P[p->adjvex].push_back(p->adjvex);


D[v0]=0;
final[v0]=TRUE;

for(i=1;i<G.vexnum;i++)
min=INFINITY;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&D[w]<min)
v=w;
min=D[w];

final[v]=TRUE;
for(p=G.vertices[v].firstarc;p;p=p->nextarc)
w=p->adjvex;
if(!final[w] && min<INFINITY && min+*(int *)(p->info)<D[w])
D[w]=min+*(int *)(p->info);
P[w]=P[v];
P[w].push_back(w);





//================================================================

这个文件又调用了base.h中的一些基本定义:
#ifndef BASE_H_
#define BASE_H_

#include<stdio.h>

namespace ds

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;


#endif
参考技术A 鉴于最小生成树和最短路径的dijkstra是相似的,我把它们合到一块了,另外下面附了一个用堆优化的dijkstra(优先队列)的代码,看看吧。

最小生成树的普利姆算法和求最短路径的dijkstra算法
算法思想:
1.、先将出发点(对最小生成树来说可以是任意一点)放入集合s中(s为元素为图的顶点的集合,记录已经解决的顶点)。
2、找到s外的所有点到s的距离(即到s中所有点的距离的最小值)最小的点,把这一点加入s集合。
3、由于新加入的一个点会使某些点到s的距离更短,更新s外的其他点到集合s的距离(如果可以更短,则更新之)。
4、返回执行第2步,直到所有的点都加入s中。
注:第二步找到的最短距离会逐步增加,所以此算法也可以解决例如第K远的城市这种问题
算法代码:
int const MAXN = 100;
int i,j;

int n; //记录图的顶点个数

int edge[MAXN][MAXN]; //记录各边权值, 默认无向并且已知,两点之间无边则记为无穷大

int dist[MAXN]; //记录当前各个点到集合s的最小距离,在运行过程中不断更新

int s[MAXN] = 0; //记录已经解决的点的下标,标志着该顶点是否加入最小生成树

//初始化,假设各边权值已知,出发点为0
for(i = 0; i < n; i++)

dist[i] = edge[0][i];


/*执行第一步*/
s[0] = 1;

for(i = 0; i < n - 1; i++)//循环n-1次将剩余的n-1个点加入生成树

/*执行第二步*/
int min = inf; // inf 为可能的最大值
int u = 0; // 记录距离s最短的顶点的下标
for(j = 0; j < n; j++)

if(!s[j] && dist[j] < min)

min = dist[j];
u = j;


s[u] = 1;
/*执行第三步*/
/*************最小生成树的普利姆*********************/
for(j = 0; j < n; j++)

if(!s[j] && edge[u][j] < dist[j])
dist[j] = edge[u][j];

/****************************************************/

/************最短路径的dijstra算法********************/
for(j = 0; j < n; j++)

if( !s[j] && dist[u] + edge[u][j] < dist[j])
dist[j] = dist[u] + edge[u][j];

/***************************************************/


附:
/*dijkstra priority_queue 邻接链表实现*/

#include <iostream>
#include <queue>
using namespace std;

const int MAXN = 110;

int head[MAXN],size;
int dist[MAXN];
int n;

struct enode
int v,cost,next;
enode()
enode(int _v,int _cost):v(_v),cost(_cost)
enode(int _v, int _cost, int _next):v(_v), cost(_cost), next(_next)
bool operator < (const enode &t) const
return cost > t.cost;

;
enode edges[MAXN*MAXN];

void add_edge(int u,int v,int cost)
edges[size] = enode(v,cost,head[u]);
head[u] = size++;


int init()
int m,u,v,c;
memset(head,-1,sizeof(head));
size = 0;
scanf("%d%d",&n,&m); //输入顶点数和边数
if(m == 0 && n == 0)return 0;
for(int i = 0; i < m; i++)
scanf("%d%d%d",&u,&v,&c); //输入边的两个顶点和边的权值
add_edge(u-1,v-1,c);
add_edge(v-1,u-1,c);

return 1;


void Dijkstra(int st)

memset(dist,0x3f,sizeof(dist));
dist[st] = 0;

priority_queue < enode > q;
q.push( enode(st,0) );
while ( !q.empty() )

enode top = q.top();
q.pop();

if(top.cost != dist[top.v]) continue;

int u,v;
u = top.v;
for(int i = head[u] ;i != -1; i = edges[i].next)
v = edges[i].v;
if ( dist[v] > dist[u] + edges[i].cost )

dist[v] = dist[u] + edges[i].cost;
q.push( enode(v,dist[v]) );





int main()
while( init() )
Dijkstra(0);
printf("%d\n",dist[n-1]);

return 0;

以上是关于用Dijkstra算法求最短路径的MATLAB程序的主要内容,如果未能解决你的问题,请参考以下文章

a*算法求最短路径和floyd还有dijsktra算法求最短路径的区别?

用Dijkstra算法求最短路径

编写的迪杰斯特拉算法求最短路径,运行不正确?

求最短路径的三种算法: Ford, Dijkstra和Floyd

Dijkstra算法

求出最短路径,要过程,用Dijkstra算法。。。