Các Algorithm Design Manual mô tả BFS và DFS khá tốt. Mã cho dfs trong sách có vấn đề khi quyết định có nên tránh các cạnh xử lý kép hay không. Tôi tìm thấy các Errata và áp dụng các errata để mã, nhưng tôi vẫn nghĩ rằng mã tinh chế có một vấn đề kiểm tra các cạnh xử lý kép.graph - Làm thế nào để tránh tái xử lý cùng một cạnh hai lần trong Depth First Search?
tôi dán mã tinh tế như sau:
dfs(graph *g, int v) {
edgenode *p;
int y;
if (finished) return;
discovered[v] = TRUE;
time = time + 1;
entry_time[v] = time;
process_vertex_early(v);
p = g->edges[v];
while (p != NULL) {
/* temporary pointer */
/* successor vertex */
/* allow for search termination */
y = p->y;
if (discovered[y] == FALSE) {
parent[y] = v;
process_edge(v,y);
dfs(g,y);
}
else if (**(!processed[y] && parent[v] != y)** || (g->directed))
process_edge(v,y);
if (finished) return;
p = p->next;
}
process_vertex_late(v);
time = time + 1;
exit_time[v] = time;
processed[v] = TRUE;
}
Nơi Tôi nghĩ có một vấn đề được đánh dấu qua ** **.
Vì vậy, nơi đáng ngờ là một trong những điều kiện. Giả sử nó là đồ thị vô hướng, vì vậy chúng ta chỉ có thể bỏ qua điều kiện của (g->directed)
.
Ok, trước tiên hãy tập trung vào parent[v] != y
. nếu parent[v] == y
, tất nhiên, chúng ta không cần xử lý cạnh v-> y một lần nữa vì y-> v đã được xử lý một lần khi xử lý đỉnh y.
Và nếu parent[v] != y
, câu hỏi của tôi là liệu !processed[y] &&
là cần thiết hay không. Vì vậy, nếu y không phải là cha mẹ của v, và processed[y] == false
có nghĩa là y đã được tìm thấy (nếu không thực hiện không thể đạt được else if
một phần) nhưng không được xử lý, vì vậy y phải là một bà hoặc cao hơn của v. một cạnh sau, nhưng không có vấn đề gì, chúng tôi có thể xử lý nó vì nó chưa được xử lý.
Bây giờ nếu processed[y] == true
thì sao? Tôi nghĩ rằng "nếu" sẽ không bao giờ xảy ra và điều kiện này sẽ không bao giờ đúng.
Tại sao? Ok, giả sử processed[y]
có thể đúng. Điều này có nghĩa rằng tất cả các đường dẫn bao gồm y đã được xử lý và tất cả các đỉnh trong các đường dẫn đó đã được xử lý, phải không? Vì vậy, nếu đây là một trường hợp, làm thế nào có thể một "chưa hoàn thành chế biến" vertex v cách tiếp cận y?
Tôi nghĩ rằng trong dfs, không có đỉnh nào sẽ tiếp cận một đỉnh được xử lý, tôi có đúng không?
Vì vậy, nếu chúng ta không bao giờ thịt một đỉnh được xử lý, chúng tôi chỉ có thể xóa !processed[y]
vì nó sẽ luôn đúng.
Nếu tôi không nhầm, 'xử lý [y]' có nghĩa tất cả các cạnh có thể đi ra ngoài của 'y' đã được truy cập, phải không? Trong trường hợp đó, không điều đó không thể xảy ra. Có lẽ nó có nghĩa là '&& 'ed với' g-> đạo diễn'? – Shahbaz