Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我要实施Dijkstra';s算法的行为不正常吗?_C_Graph_Shortest Path_Dijkstra_Graph Traversal - Fatal编程技术网

C 为什么我要实施Dijkstra';s算法的行为不正常吗?

C 为什么我要实施Dijkstra';s算法的行为不正常吗?,c,graph,shortest-path,dijkstra,graph-traversal,C,Graph,Shortest Path,Dijkstra,Graph Traversal,我正在写一个Dijkstra算法的实现来学习酷图算法(仅供参考,这不是家庭作业)。我使用维基百科的算法作为我的主要资源 我测试了不同的遍历路径,得到了以下结果((foo,bar)表示foo到bar): 我正在使用的图形如下所示: F - H | | A ---- B - C | / | / E - G - D 通过跟踪从E到F的路径,我大致了解了代码失败的原因。另一个问题是,我不知道如何用我的方法实现算法。下面是从E到F的跟踪: 在

我正在写一个Dijkstra算法的实现来学习酷图算法(仅供参考,这不是家庭作业)。我使用维基百科的算法作为我的主要资源

我测试了不同的遍历路径,得到了以下结果(
(foo,bar)
表示
foo到bar
):

我正在使用的图形如下所示:

       F - H
       |   |
A ---- B - C
|         /
|        /
E - G - D
通过跟踪从
E
F
的路径,我大致了解了代码失败的原因。另一个问题是,我不知道如何用我的方法实现算法。下面是从
E
F
的跟踪:

在节点
E
,我的邻居是
A
G
。最短的暂定距离是
G
,因此这是下一个当前节点
G
的邻居是
E
D
,但是
E
已经被遍历,所以
C
是下一个。对于
C
,它的邻居
D
被遍历,因此我们现在到达
B
B
H
是等距的,但它是在
C
的边列表中首先选择的)。这就是我的问题所在:

A
的暂定距离已由
E
计算为2。由于从
B
A
的新的暂定距离远大于两个,因此其距离保持在
2
。对于
F
,它的距离被设置为暂定距离,因为它被初始化为
无限
A
的距离较小,因此选择它作为下一个节点
A
的唯一邻居是
E
B
,它们已经被遍历,所以它周围的所有节点都已经被遍历过了。变量
最近的
(参见下面的我的代码)被初始化为一个节点,除了
无限
距离
,没有其他填充字段,因此在下一次迭代中,它没有边,我得到了一个分段错误

我知道这就是我的代码中发生的事情,因为它的输出如下所示:

Current: e
New neighbor: a
New neighbor: g
g, closest, distance of 1
Current: g
New neighbor: d
d, closest, distance of 2
Current: d
New neighbor: c
c, closest, distance of 4
Current: c
New neighbor: b
New neighbor: h
b, closest, distance of 5
Current: b
New neighbor: a
New neighbor: f
a, closest, distance of 2
Current: a
?, closest, distance of 1000
Current: ?
Segmentation fault: 11
在实现这个算法的过程中,我哪里做错了?我试着非常仔细地遵循维基百科的6步描述。它们的描述和我的描述之间的唯一区别是,我没有使用集合来跟踪已探测和未探测的节点(相反,数据保存在节点本身)。请提供您能提供的任何见解

注意:我在Mac电脑上使用Clang进行编译,没有任何优化(
-O0
)。我注意到,在进行更高的优化时,我的程序会无限递归,然后给我带来另一个分段错误,但在处理之前,我会优先使用我的算法解决中心问题

#包括
#包括
#包括
#定义无限1000
结构节点{
无符号字符值;
到访整数、距离、边数;
int*权重,权重分配索引,释放;
结构节点**边;
};
typedef结构节点;
Node*init_Node(常量无符号字符值,常量int边缘_计数){
Node*Node=malloc(sizeof(Node));
节点->值=值;
节点->访问次数=0;
节点->距离=无穷大;
节点->边缘计数=边缘计数;
节点->权重=malloc(边数*大小(int));
节点->权重\分配\索引=0;
节点->释放=0;
节点->边=malloc(边计数*大小(节点*);
返回节点;
}
无效分配_边(节点*节点,常量整数金额,…){
va_列表边;
va_开始(边缘、数量);
对于(int i=0;i边[i]=va_arg(边,节点*);
va_端(边缘);
}
无效分配权重(节点*节点\ 1,节点*节点\ 2,常量整数权重){
对于(int i=0;iedge_count;i++){
if(节点_1->边[i]==节点_2){
节点_1->权重[节点_1->权重_分配_索引+]=权重;
节点_2->权重[节点_2->权重_分配_索引+]=权重;
}
}
}
void deinit_图(节点*节点){
如果(!节点->已释放){
节点->释放=1;
自由(节点->权重);
对于(int i=0;iedge\u count;i++)
deinit_图(节点->边[i]);
自由(节点->边);
}
}
void dijkstra(节点*当前,节点*目标){
节点局部最近;
局部距离=无穷远;
节点*最近=&local\u最近;
printf(“当前:%c\n”,当前->值);
对于(int i=0;iedge\u count;i++){
节点*邻居=当前->边[i];
如果(!邻居->已访问){
printf(“新邻居:%c\n”,邻居->值);
常量int暂定_距离=当前->距离+当前->权重[i];
if(暂定距离<邻居->距离)
邻居->距离=暂定距离;
如果(邻居->距离<最近->距离)
最近的=邻居;
}
}
printf(“%c,最近,距离为%d\n”,最近->值,最近->距离);
当前->访问=1;
如果(最近==目标)printf(“最短距离为%d\n”,最近->距离);
else dijkstra(最近,目标);
}
int main(){
节点
*a=初始节点('a',2),
*b=初始节点('b',3),
*c=初始节点('c',3),
*d=初始节点('d',2),
*e=初始节点('e',2),
*f=初始节点('f',2),
*g=初始节点('g',2),
*h=初始节点('h',2);
分配_边(a,2,e,b);
分配_边(b,3,a,f,c);
分配_边(c,3,b,h,d);
分配_边(d,2,c,g);
分配_边(e,2,a,g);
指定_边(f,2,b,h);
分配_边(g,2,e,d);
分配_边(h,2,f,c);
分配_权重(a、e、2);
分配_权重(a、b、4);
分配_权重(b,c,1);
分配_权重(b,f,1);
分配_权重(f,h,1);
分配_权重(h、c、1);
分配_权重(c、d、2);
分配_权重(d,g,1);
指派吴伟
Current: e
New neighbor: a
New neighbor: g
g, closest, distance of 1
Current: g
New neighbor: d
d, closest, distance of 2
Current: d
New neighbor: c
c, closest, distance of 4
Current: c
New neighbor: b
New neighbor: h
b, closest, distance of 5
Current: b
New neighbor: a
New neighbor: f
a, closest, distance of 2
Current: a
?, closest, distance of 1000
Current: ?
Segmentation fault: 11