Floyd Warshall 算法和网格图
Floyd Warshall Algorithm and Grid Graphs
使用维基百科上的伪代码在邻接表表示上实现 floyd warshall 算法,创建了以下代码。该图是一个网格,因此如果它是一个 3 x 3 网格,则顶点 0 有两条边,顶点 1 有 3 条,而顶点 2 有两条,依此类推。
self-> V = 图中的顶点数!!
void floyd(Graph *self, int** dist, int** next)
{
int i, j, k;
EdgeNodePtr current;
current = malloc(sizeof(current));
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++) {
dist[i][j] = INT_MAX; // Sets all minimun distances to infintiy
next[i][j] = -1; // Sets all next vertex to a non existant vertex
}
}
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++)
{
current = self->edges[i].head;
while (current != NULL) // Cycles through all the edges in edgelist
{
if (current->edge.to_vertex == j) // If an edge to the correct vertex is found then adds distance
{
dist[i][j] = current->edge.weight;
next[i][j] = j; // Updates next node
}
current = current->next;
}
}
}
PRINT
// Standard implemnation of floyds algorithm
for (k = 0; k < self->V; k++)
{
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++)
{
if (dist[i][j] > dist[i][k] + dist[k][j])
{
dist[i][j] = dist[i][k] + dist[k][j];
next[i][j] = next[i][k];
}
}
}
}
PRINT
}
发生的事情是边缘都被正确地插入到距离数组中,通过简单的打印检查。当算法运行时会遇到问题,它将所有距离变成 INT_MINS 或类似的数字。虽然实际上没有计算距离。
我相信网格的结束距离图应该在数组中填充所有可能的距离,除了从顶点到自身的距离为无穷大。
打印列表图的输出图片,其中显示 PRINT
你需要小心int溢出。 Wikipedia pseudocode(在这个答案的底部)使用 "infinity",其中 "infinity + (anything finite) = infinity"。但是,当你用INT_MAX
表示"infinity"时,由于溢出就不是这样了。尝试将您的 if 语句条件更改为:
if (dist[i][k] != INT_MAX &&
dist[k][j] != INT_MAX &&
dist[i][j] > dist[i][k] + dist[k][j]) {
这将避免 int 溢出向 INT_MAX
添加正距离。
维基百科伪代码:
1 let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
2 for each edge (u,v)
3 dist[u][v] ← w(u,v) // the weight of the edge (u,v)
4 for each vertex v
5 dist[v][v] ← 0
6 for k from 1 to |V|
7 for i from 1 to |V|
8 for j from 1 to |V|
9 if dist[i][j] > dist[i][k] + dist[k][j]
10 dist[i][j] ← dist[i][k] + dist[k][j]
11 end if
使用维基百科上的伪代码在邻接表表示上实现 floyd warshall 算法,创建了以下代码。该图是一个网格,因此如果它是一个 3 x 3 网格,则顶点 0 有两条边,顶点 1 有 3 条,而顶点 2 有两条,依此类推。
self-> V = 图中的顶点数!!
void floyd(Graph *self, int** dist, int** next)
{
int i, j, k;
EdgeNodePtr current;
current = malloc(sizeof(current));
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++) {
dist[i][j] = INT_MAX; // Sets all minimun distances to infintiy
next[i][j] = -1; // Sets all next vertex to a non existant vertex
}
}
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++)
{
current = self->edges[i].head;
while (current != NULL) // Cycles through all the edges in edgelist
{
if (current->edge.to_vertex == j) // If an edge to the correct vertex is found then adds distance
{
dist[i][j] = current->edge.weight;
next[i][j] = j; // Updates next node
}
current = current->next;
}
}
}
PRINT
// Standard implemnation of floyds algorithm
for (k = 0; k < self->V; k++)
{
for (i = 0; i < self->V; i++)
{
for (j = 0; j < self->V; j++)
{
if (dist[i][j] > dist[i][k] + dist[k][j])
{
dist[i][j] = dist[i][k] + dist[k][j];
next[i][j] = next[i][k];
}
}
}
}
PRINT
}
发生的事情是边缘都被正确地插入到距离数组中,通过简单的打印检查。当算法运行时会遇到问题,它将所有距离变成 INT_MINS 或类似的数字。虽然实际上没有计算距离。
我相信网格的结束距离图应该在数组中填充所有可能的距离,除了从顶点到自身的距离为无穷大。
打印列表图的输出图片,其中显示 PRINT
你需要小心int溢出。 Wikipedia pseudocode(在这个答案的底部)使用 "infinity",其中 "infinity + (anything finite) = infinity"。但是,当你用INT_MAX
表示"infinity"时,由于溢出就不是这样了。尝试将您的 if 语句条件更改为:
if (dist[i][k] != INT_MAX &&
dist[k][j] != INT_MAX &&
dist[i][j] > dist[i][k] + dist[k][j]) {
这将避免 int 溢出向 INT_MAX
添加正距离。
维基百科伪代码:
1 let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) 2 for each edge (u,v) 3 dist[u][v] ← w(u,v) // the weight of the edge (u,v) 4 for each vertex v 5 dist[v][v] ← 0 6 for k from 1 to |V| 7 for i from 1 to |V| 8 for j from 1 to |V| 9 if dist[i][j] > dist[i][k] + dist[k][j] 10 dist[i][j] ← dist[i][k] + dist[k][j] 11 end if