Dijkstra 算法 - 无限循环
Dijkstra's Algorithm - Infinite Loop
作为一项家庭作业,我将使用指向每个顶点的链表的指针数组来实现邻接表。每个链表都有一个元素 <destination>
表示邻接表顶点的顶点邻居。
邻接表是无向且未加权的,所以我将所有权重都视为 1。
/* Adjacency List Node data structure (edge)
* Linked List data structure for storing linked vertices
*/
struct adjacencyListNode
{
int destination;
struct adjacencyListNode *next;
};
/* Adjacency List Vertex data structure (vertex)
* <AdjacencyList> consists of pointers to <n> adjacencyListVertex
*/
struct adjacencyListVertex
{
struct adjacencyListNode *head;
};
我正在尝试在邻接表上执行 Dijkstra 算法以找到从 s 到 t 的最小路径。
现在我正在实现以下算法:
/* Prints the length and path taken of the shortest path in adjacency list between s and t.
* Uses Dijkstra’s algorithm to compute shortest path.
* S: source vertex
* V: destination vertex
*/
void shortestPath(int s, int t) {
int known[size]; // shortest distance to vertex is know
int cost[size]; // distance from source <s> to each vertex
int path[size]; //path
// Initialization: Set all distances to infinity (represented by -1), since arrays have not been visited and graph is positively weighted
for (int index = 0; index<size; index++) {
cost[index] = INFINITY;
known[index] = 0;
}
// Set distance from source->source to 0
cost[s-1] = 0;
// Starting at s, traverse towards all reachable unvisited verticies, visit it and repeat
while (isFinished(known, size) == false) {
// Select a vertex from list of unvisited nodes which has the smallest cost
int cheapestVertex, cheapestValue = INFINITY+1;
for (int costCheck = 0; costCheck<size; costCheck++) {
if ((known[costCheck] == 0) && (cost[costCheck] < cheapestValue)) {
// We found a cheaper unvisited vertex
// cout << "Cheapest vertex: " << costCheck << endl;
cheapestVertex = costCheck;
cheapestValue = cost[cheapestVertex];
}
// cout << "found? " << cheapestVertex << " " << cheapestValue << endl;
}
// cout << "Cheapest vertex: " << cheapestVertex << endl;
// For each unvisited neighbor of our cheapest (unvisited) vertex
adjacencyListNode* iterator = A[cheapestVertex].head; // iterator is our first neighbor
while (iterator)
{
// Calculate the new cost from the current vertex <cheapestVertex>
if (cost[cheapestVertex]+1 < cost[iterator->destination] && known[iterator->destination] == 0) {
cost[iterator->destination] = cost[cheapestVertex]+1;
}
iterator = iterator->next; // move to next neighbor, repeat
}
// cout << "Cheapest vertex: " << cheapestVertex << " known." << endl;
// Mark the current vertex <cheapestVertex> as visited
known[cheapestVertex] = 1;
// DEBUG: (REMOVE BEFORE SUBMISSION)
for (int i = 0; i<size; i++) {
cout << "Vertex " << i << " : known? " << known[i] << ", cost? " << cost[i] << endl;
}
cout << endl;
if (cost[t-1] != INFINITY) break; // We already know shortest path, end.
}
// We know the shortest path cost to t
cout << "Cost to t: " << cost[t] << endl;
}
bool isFinished(int array[], int arraySize) {
bool finished = true;
for (int iterator=0; iterator < arraySize; iterator++) {
if (array[iterator] == 0) {
// vertex not known, we're not done.
finished = false;
}
}
return finished;
}
我正在传递以下输入,它只是添加指定的相关顶点并调用我的最短路径算法。
0 1
1 2
1 3
2 4
3 5
5 38
6 7
6 10
8 9
11 12
12 13
12 15
12 21
13 14
14 15
16 17
17 18
18 19
19 20
20 39
21 22
22 23
22 31
23 24
23 32
24 25
24 33
25 26
26 27
27 28
28 29
29 30
31 40
34 35
34 37
35 36
36 37
1
shortest-path
我的代码从0->1->2->3->4->5->38遍历然后无限重复38
有人知道我的问题出在哪里吗?
你有一些问题。由于这是作业,我不会给你完整的答案。
问题 1:如果存在无法从 s 访问的节点,会发生什么情况?这就是您的示例中发生的情况。
提示:您需要计算出何时停止循环(除了您已有的循环)。查看您最便宜的选择 - 您如何确定没有有效的选择?
提示 #2 - 如果所有剩余顶点的成本为 INFINITE
,则当前循环不会为 cheapestVertex
设置值,因此您将使用未初始化的值。也许在继续之前检查一下你找到的最便宜的费用是多少。
第 2 期:cost[iterator->destination] = cost[cheapestVertex]+1;
提示:你确定在任何场合都这样做是正确的吗?如果该节点已经有更便宜的成本,或者已经被访问过怎么办?
问题 3:一旦您知道 t
,您就可以停止寻找了。无需检查整个图表。注意:这是一个您不一定需要的更改,因为您的代码没有它也能正常工作。
作为一项家庭作业,我将使用指向每个顶点的链表的指针数组来实现邻接表。每个链表都有一个元素 <destination>
表示邻接表顶点的顶点邻居。
邻接表是无向且未加权的,所以我将所有权重都视为 1。
/* Adjacency List Node data structure (edge)
* Linked List data structure for storing linked vertices
*/
struct adjacencyListNode
{
int destination;
struct adjacencyListNode *next;
};
/* Adjacency List Vertex data structure (vertex)
* <AdjacencyList> consists of pointers to <n> adjacencyListVertex
*/
struct adjacencyListVertex
{
struct adjacencyListNode *head;
};
我正在尝试在邻接表上执行 Dijkstra 算法以找到从 s 到 t 的最小路径。
现在我正在实现以下算法:
/* Prints the length and path taken of the shortest path in adjacency list between s and t.
* Uses Dijkstra’s algorithm to compute shortest path.
* S: source vertex
* V: destination vertex
*/
void shortestPath(int s, int t) {
int known[size]; // shortest distance to vertex is know
int cost[size]; // distance from source <s> to each vertex
int path[size]; //path
// Initialization: Set all distances to infinity (represented by -1), since arrays have not been visited and graph is positively weighted
for (int index = 0; index<size; index++) {
cost[index] = INFINITY;
known[index] = 0;
}
// Set distance from source->source to 0
cost[s-1] = 0;
// Starting at s, traverse towards all reachable unvisited verticies, visit it and repeat
while (isFinished(known, size) == false) {
// Select a vertex from list of unvisited nodes which has the smallest cost
int cheapestVertex, cheapestValue = INFINITY+1;
for (int costCheck = 0; costCheck<size; costCheck++) {
if ((known[costCheck] == 0) && (cost[costCheck] < cheapestValue)) {
// We found a cheaper unvisited vertex
// cout << "Cheapest vertex: " << costCheck << endl;
cheapestVertex = costCheck;
cheapestValue = cost[cheapestVertex];
}
// cout << "found? " << cheapestVertex << " " << cheapestValue << endl;
}
// cout << "Cheapest vertex: " << cheapestVertex << endl;
// For each unvisited neighbor of our cheapest (unvisited) vertex
adjacencyListNode* iterator = A[cheapestVertex].head; // iterator is our first neighbor
while (iterator)
{
// Calculate the new cost from the current vertex <cheapestVertex>
if (cost[cheapestVertex]+1 < cost[iterator->destination] && known[iterator->destination] == 0) {
cost[iterator->destination] = cost[cheapestVertex]+1;
}
iterator = iterator->next; // move to next neighbor, repeat
}
// cout << "Cheapest vertex: " << cheapestVertex << " known." << endl;
// Mark the current vertex <cheapestVertex> as visited
known[cheapestVertex] = 1;
// DEBUG: (REMOVE BEFORE SUBMISSION)
for (int i = 0; i<size; i++) {
cout << "Vertex " << i << " : known? " << known[i] << ", cost? " << cost[i] << endl;
}
cout << endl;
if (cost[t-1] != INFINITY) break; // We already know shortest path, end.
}
// We know the shortest path cost to t
cout << "Cost to t: " << cost[t] << endl;
}
bool isFinished(int array[], int arraySize) {
bool finished = true;
for (int iterator=0; iterator < arraySize; iterator++) {
if (array[iterator] == 0) {
// vertex not known, we're not done.
finished = false;
}
}
return finished;
}
我正在传递以下输入,它只是添加指定的相关顶点并调用我的最短路径算法。
0 1
1 2
1 3
2 4
3 5
5 38
6 7
6 10
8 9
11 12
12 13
12 15
12 21
13 14
14 15
16 17
17 18
18 19
19 20
20 39
21 22
22 23
22 31
23 24
23 32
24 25
24 33
25 26
26 27
27 28
28 29
29 30
31 40
34 35
34 37
35 36
36 37
1
shortest-path
我的代码从0->1->2->3->4->5->38遍历然后无限重复38
有人知道我的问题出在哪里吗?
你有一些问题。由于这是作业,我不会给你完整的答案。
问题 1:如果存在无法从 s 访问的节点,会发生什么情况?这就是您的示例中发生的情况。
提示:您需要计算出何时停止循环(除了您已有的循环)。查看您最便宜的选择 - 您如何确定没有有效的选择?
提示 #2 - 如果所有剩余顶点的成本为 INFINITE
,则当前循环不会为 cheapestVertex
设置值,因此您将使用未初始化的值。也许在继续之前检查一下你找到的最便宜的费用是多少。
第 2 期:cost[iterator->destination] = cost[cheapestVertex]+1;
提示:你确定在任何场合都这样做是正确的吗?如果该节点已经有更便宜的成本,或者已经被访问过怎么办?
问题 3:一旦您知道 t
,您就可以停止寻找了。无需检查整个图表。注意:这是一个您不一定需要的更改,因为您的代码没有它也能正常工作。