我已经做了一些关于如何在拓扑排序中检测循环的搜索,我也完成了寻找循环的编码,这里是代码:
--print the sort message
IF Kn = 0 THEN
Put("The sorting is complete!!");
RETURN;
ELSE
Put("The Sorting is not complete, loops occur!!");
FOR K IN 1 .. NA LOOP
SortStructure(K).Count:= 0;
END LOOP;
END IF;
-- Find the loop
for K in 1 .. NA loop
P := SortStructure(K).Top;
SortStructure(K).Top := ITN(0);
--when count = 0 and top /= 0, the loop occur
while P /= ITN(0) and then SortStructure(SortElement'Pos(P.suc)).count= 0 loop
SortStructure(SortElement'Pos(P.suc)).count:= k;
IF P /= Itn(0) THEN
P := P.Next;
END IF;
END LOOP;
END LOOP;
--use K determine a part of the loop
K:=1;
WHILE Sortstructure(K).Count= 0 LOOP
K:= K+1;
END LOOP;
--Mark the loop
LOOP
Sortstructure(K).Top := ITN(1);
K:= Sortstructure(K).Count;
EXIT WHEN SortStructure(K).Top /= ITN(0);
END LOOP;
--Print the loop
Put_Line("The loop is: ");
WHILE SortStructure(K).Top /= ITN(0) LOOP
--SortElement'Val(K) will return the value of K, make this also work for Enumeration
Put(SortElement'Val(K));
Put(", ");
SortStructure(K).Top := ITN(0);
K:= SortStructure(K).Count;
END LOOP;
Put(SortElement'Val(K));
New_Line;
如果发生循环,此代码从打印消息开始,然后标记循环的开头和循环结束然后打印它。它适用于检测单循环,但如何使它可以检测多个循环并打印它们?
例如:给定关系(格式“Pre&lt; Suc”): 1 <2,2 <3,3(1个环),1 <4,4&lt; 3(第二个环)。
任何想法都会受到赞赏。
答案 0 :(得分:0)
我不确定拓扑排序是否可以帮助您检测所有周期。它绝对可以帮助您测试图形是否是非循环的。
为什么不简单地在图表上运行DFS并查找后边缘。每次遇到后沿时,都会打印循环路径。打印任务有点棘手,但我相信是可行的(见this)
答案 1 :(得分:0)
我想,你会像All path问题一样。如果拓扑排序是您要检测多个循环的目的,那么无论何时检测到循环,都要将当前堆栈添加到列表中并继续下一个可用节点,然后递归上去。