问题描述
我有一个作业来实现 Bellman Ford 的算法并在一些图表上对其进行测试。我实现了该算法,在 3 个图中的 2 个上对其进行了测试,并且它有效。但是在第三张图中,我在调用函数时没有输出。
Graph* temaTrecuta = createGraph(10,12);
addOrientedEdge(temaTrecuta,1,5);
addOrientedEdge(temaTrecuta,2,3);
addOrientedEdge(temaTrecuta,3,4,9,5,1);
addOrientedEdge(temaTrecuta,6,7,8,10,11,1);
这部分创建图形及其边。 createGraph
函数将顶点数和边数作为参数。
void addOrientedEdge(Graph* graph,int index,int source,int destination,int cost) {
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->matrix[source][destination] = cost;
}
这是添加新边的函数。
以下是我对 Bellman Ford 算法的实现。
void bellmanFord(Graph* gr,int src) {
int* dist = (int*)malloc(sizeof(int) * gr->V);
int* path = (int*)malloc(sizeof(int) * gr->V);
if (!path || !dist) {
printf("Nu am putut aloca.\n");
exit(1);
}
for (int i = 0; i < gr->V; ++i) {
dist[i] = INT_MAX;
path[i] = 0;
}
path[src] = -1;
dist[src] = 0;
for (int i = 1; i <= gr->V - 1; ++i) {
for (int j = 0; j < gr->E; ++j) {
int m = gr->edge[j].src;
int n = gr->edge[j].dest;
int cost = gr->edge[j].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
dist[n] = dist[m] + cost;
path[n] = m;
}
}
}
for (int i = 0; i < gr->E; ++i) {
int m = gr->edge[i].src;
int n = gr->edge[i].dest;
int cost = gr->edge[i].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
printf("Exista un ciclu negativ.");
return;
}
}
printBellmanSol(dist,gr->V,path);
free(dist);
free(path);
}
解决方法
由于没有引用边缘索引,只要它是唯一且连续的,就应该考虑自动递增。除了边索引E
,还有一个新的边容量。这是传递给 createGraph
的数字,最初设置计数器 E = 0
。你可以用少一个参数来写你的 addOrientedEdge
;取下一个边索引。
static void addOrientedEdge(struct Graph* graph,int source,int destination,int cost) {
const int index = graph->E;
assert(graph && graph->E < graph->E_capacity);
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->E++;
graph->matrix[source][destination] = cost;
}
这样您就不必担心边数了。
,缺少导致问题的边缘。感谢@user3386109 看到它。