最短路径算法。
对最优化路径的一般性论述, 这条论述也称为 最优化原则 ( optimality principle )
如果路由器J是在从路由器 I 到路由器 K 的最优路径上,那么J到K的最优路径也必定沿着同样的路由路径。
工作节点
暂时性节点
永久性节点
struct state { /* the path being worked on */
int predecessor; /* length from sorurce to this node */
int length;
enum { permanent, tentative } label; /* label state */
} state[MAX_NODES];
表示节点的数据结构
predecessor 当前节点的前一个节点 (到目前为止[不一定是最优,除非状态是permanent],从开始节点到当前节点的最短路径中,当前节点的前一个节点,一直往前回溯可到达开始节点)
length 到当前节点的长度 (到目前为止[不一定是最优,除非状态是permanent],从开始节点到当前节点的最短路径 )
label 当前节点的状态, (如果为 permanent 的话,表示沿着 predecessor 路径 从开始节点到当前节点(反过来)必定最短 )
1、选首节点作为工作节点(如 A ( -1, 0, tentative ))。计算工作节点和相邻节点的距离,更新相邻节点的数据结构 B( A, 3, tentative )。
2、找出所有 状态为 tentative 的节点中 length 最小的 节点,作为工作节点,如果此节点为终点,结束计算,从最终节点一直找predecessor可找到最短路径。
如果不是,则重复第一步。
#define MAX_NODES 1024 /*maximum number of nodes */
#define INFINITY 100000000 /* a number larger than every maximum path */
#define INY 100000000
int n = 8;
int dist[MAX_NODES][MAX_NODES] = { /* dist[i][j] is the distance from i to j */
{ 0, 2, INY, INY, INY, INY, 6, INY },
{ 2, 0, 7, INY, INY, 2, INY, INY },
{ INY, 7, 0, 3, INY, 3, INY, INY },
{ INY, INY, 3, 0, INY, INY, INY, 2 },
{ INY, 2, INY, INY, 0, 2, 1, INY },
{ INY, INY, 3, INY, 2, 0, INY, 2 },
{ 6, INY, INY, INY, 1, INY, 0, 2 },
{ INY, INY, INY, 2, INY, 2, 2, 0 }
};
void shortest_path( int s, int t, int path[] ) {
struct state { /* the path being worked on */
int predecessor; /* length from sorurce to this node */
int length;
enum { permanent, tentative } label; /* label state */
} state[MAX_NODES];
int i, k, min;
struct state *p;
for( p = &state[0]; p < &state[n]; p++ ) { /* initialize state */
p->predecessor = -1;
p->length = INFINITY;
p->label = state::tentative;
}
state[t].length = 0; state[t].label = state::permanent;
k = t; /* k is the initial working node */
do
{ /* is there a better path from k */
for( i = 0; i < n; i++ ) /* 更新当前选择的永久性节点 共有n个。 */
if( dist[k][i] != 0 && state[i].label == state::tentative ) {
if( state[k].length + dist[k][i] < state[i].length ) {
state[i].predecessor = k;
state[i].length = state[k].length + dist[k][i];
}
}
/* Find the tentatively labeled node with the smallest label */
k = 0; min = INFINITY;
/*找最小的tentatively node */
for( i = 0; i < n; i++ )
if( state[i].label == state::tentative && state[i].length < min ) {
min = state[i].length;
k = i;
}
state[k].label = state::permanent;
} while ( k != s );
/* Copy the path into the output array. */
i = 0; k = s;
do { path[i++] = k; k = state[k].predecessor; }
while( k >= 0 );
}