单源最短路径问题-Dijkstra

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
////////////////////////////////////////////////////////////
int len = 0;
while( p != startPoint )
{
theway[len] = p;
p = prev[p];
len++;
}
theway[len] = startPoint;
len++;
for( int i = 0 , j = len - 1 ; i < len ; i++ , j-- )
int size;//地图大小
int startPoint;//起点
double dist[maxPoint];//当前图的解
int prev[maxPoint];
};
////////////////////////////////////////////////////////////
// Graph.cpp
{ -1 , -1 , 20 , 0 , 60 } ,
{ -1 , -1 , -1 , -1 , 0 }
}; //邻接矩阵
void main()
{int R[maxpoint]={0},B[maxpoint];
int D[VEX],P[VEX];//定义数组D用来存放结点特殊距离,P数组存放父亲结点
printf( "从%d到%d的最短路径长%.f\n" , g.GetStartPoint() , dest , dist );
printf( "所经结点为:\n" );
for( int i = 0 ; i < pathlen ; i++ )
printf( "%3d" , path[i] );
printf( "\n----------------------------------------\n" );
(3)Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组D作必要的修改。
(4)一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
源程序1:
//Dijkstra算法
#include<iostream>
#include<cstdlib>
//初始时,红点集中仅有源结点0
R[0]=1; B[0]=0;
for(int i=1;i<VEX;i++)
B[i]=1;
//对数组D、P进行初始化
for(i=0;i<VEX;i++)
{D[i]=graph[0][i];
if(D[i]!=-1) P[i]=0;
else P[i]=-1;
}
//输出邻接矩阵
{
if( !s[j] )
{
//如果不是第一次比较,temp、u,都已经赋值,则
if( flag )
{
if( dist[j] > 0 && dist[j] < temp )
{
u = j;
temp = dist[j];
}
}
else
{
u = j;
temp = dist[j];
flag = true;
}
}
}
if(D[j]!=-1&&D[j]<D[min]&&B[j]==1) min=j;
cout<<"min="<<min<<" ";
//将具有最短特殊路长度的结点min添加到红点集中
R[min]=1; B[min]=0;
//对数组D作必要的修改
for(j=1;j<VEX;j++)
if(graph[min][j]!=-1&&min!=j) //结点min到j间有路
CGraph::CGraph(void)
{
for( int i = 0 ; i < maxPoint ; i++ )
{
for( int j = 0 ; j < maxPoint ; j++ )
graph[i][j] = -1;
}
startPoint = -1;
size = -1;
solved = false; //当前图还没有求解
}
CGraph::~CGraph(void)
{
}
//
bool CGraph::SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size )
{
for( int i = 0 ; i < size ; i++ )
{
for( int j = 0 ; j < size ; j++ )
{ -1 , -1 , 20 , 0 , 60 } ,
{ -1 , -1 , -1 , -1 ,0}
};
int size = 5;
int start = 0;
int dest = 1;
int pathlen;
int path[maxPoint];
double dist;
CGraph g;
g.SetGraph( graph , start , size );
bool Dijkstra();
void Display();
int GetStartPoint();
double GetBestWay( int dest , int path[] , int &pathLen );
private:
bool solved;//标志当前图是否已经求解
double graph[maxPoint][maxPoint];//当前图布局
using namespace std;
#define VEX 5//定义结点的个数
#define maxpoint 100
double graph[][maxpoint]={
{ 0 , 10 , -1 , 30 , 100 },
{ -1 , 0 , 50 , -1 , -1 } ,
{ -1 , -1 , 0 , -1 , 10 } ,
cout<<"P["<<i<<"] ";
cout<<endl;
for(int k=1;k<VEX;k++) //每次从蓝点集中取出具有最短特殊路长度的结点min
{ for(int min=0;B[min]==0;) min++;//求蓝点集结点最小下标元素
for(int j=min;j<VEX;j++)
s[u] = true;
for( j = 0 ; j < size ; j++ )
{
if( !s[j] && graph[u][j] > 0 )
{
double newDist = dist[u] + graph[u][j];
if( dist[j] < 0 || newDist < dist[j] )
path[i] = theway[j];
pathLen = len;
return dist[dest];
}
//
//
int CGraph::GetStartPoint()
{
return startPoint;
}
//
////////////////////////////////////////////////////////////
}
//从起点出发
dist[startPoint] = 0;
s[startPoint] = true;
for( int i = 0 ; i < size ; i++ )
{
double temp;
int u = startPoint;
bool flag = false;
for( int j = 0 ; j < size ; j++ )
graph[i][j] = g[i][j];
}
this->startPoint = startPoint;
this->size = size;
solved = false;
Dijkstra();
return true;
}
ቤተ መጻሕፍቲ ባይዱ//
bool CGraph::Dijkstra()
{
bool s[maxPoint];
for(i=0;i<VEX;i++)
cout<<P[i]<<" ";
cout<<endl;
}
}
源程序2:
#include<iostream>
using namespace std;
////////////////////////////////////////////////////////////
{
printf( "%5.f" , graph[i][j] );
}
printf( "\n" );
}
}
//
double CGraph::GetBestWay( int dest , int path[] , int &pathLen )
{
int p = dest;
int theway[maxPoint];
g.Display();
printf( "----------------------------------------\n" );
for( dest = 0 ; dest < size ; dest++ )
{
dist = g.GetBestWay( dest , path , pathlen );
{
dist[j] = newDist;
prev[j] = u;
}
}
}
}
solved = true;
return true;
}
//
void CGraph::Display()
{
printf( "当前地图的邻接矩阵\n" );
for( int i = 0 ; i < size ; i++ )
{
for( int j = 0 ; j < size ; j++ )
// Dijkstra.cpp :定义控制台应用程序的入口点。
void main()
{
double graph[][maxPoint] =
{
{0, 10 , -1 , 30 , 100 } ,
{ -1 , 0 , 50 , -1 , -1 } ,
{ -1 , -1 , 0 , -1 , 10 } ,
if(D[j]>D[min]+graph[min][j]||D[j]==-1)
{D[j]=D[min]+graph[min][j]; //每次迭代求最小值,最后一次即为到源点的最短路径
P[j]=min;
}
//输出最短路径
for(i=0;i<VEX;i++)
cout<<D[i]<<" ";
cout<<" ";
for( int j = 0 ; j < size ; j++ )
{
dist[j] = graph[startPoint][j];
s[j] = false;
if( dist[j] < 0 ) //dist[i]<0,表示没有路径连接结点startPoint与结点j
prev[j] = 0;
else
prev[j] = startPoint;
Dijkstra算法基本思想:设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。
(1)初始时,S中仅含有源节点。
(2)设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,用数组D[i]记录顶点i当前所对应的最短特殊路径长度。
单源最短路径问题
所谓单源最短路径问题是指:已知图G=(V,E),我们希望找出从某给定的源结点S∈V到V中的每个结点的最短路径。
首先,我们可以发现有这样一个事实:如果P是G中从vs到vj的最短路,vi是P中的一个点,那么,从vs沿P到vi的路是从vs到vi的最短路。
对于图G,如果所有Wij≥0的情形下,目前公认的最好的方法是由Dijkstra于1959年提出来的。
// Graph.h
#define maxPoint 100
class CGraph
{
public:
CGraph(void);
~CGraph(void);
bool SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size );
for(i=0;i<VEX;i++)
{for(int j=0;j<VEX;j++)
cout<<graph[i][j]<<"\t";
cout<<endl;
}
//输出D、P表头
cout<<" ";
for(i=0;i<VEX;i++)
cout<<"D["<<i<<"] ";
cout<<" ";
for(i=0;i<VEX;i++)
相关文档
最新文档