Tôi đang gặp khó khăn khi tìm cách phân loại chính xác các cạnh trong khi tìm kiếm theo chiều rộng trên biểu đồ được chỉ dẫn.Phân loại cạnh trong quá trình tìm kiếm theo chiều rộng đầu tiên trên đồ thị có hướng
Trong một tìm kiếm theo chiều rộng hoặc chiều sâu-đầu tiên, bạn có thể phân loại các cạnh gặp với 4 lớp:
- TREE
- LẠI
- CHÉO
- HƯỚNG
Skiena [1] đưa ra một triển khai. Nếu bạn di chuyển dọc theo một cạnh từ v1 đến v2, đây là một cách để trả về lớp trong một DFS trong java, để tham khảo. Bản đồ cha mẹ trả về đỉnh mẹ cho tìm kiếm hiện tại và phương thức timeOf()
, thời gian mà đỉnh đã được phát hiện.
if (v1.equals(parents.get(v2))) { return EdgeClass.TREE; }
if (discovered.contains(v2) && !processed.contains(v2)) { return EdgeClass.BACK; }
if (processed.contains(v2))
{
if (timeOf(v1) < timeOf(v2))
{
return EdgeClass.FORWARD;
}
else
{
return EdgeClass.CROSS;
}
}
return EdgeClass.UNCLASSIFIED;
Vấn đề của tôi là tôi không thể làm cho nó phù hợp với một Chiều rộng tìm kiếm đầu tiên trên một đồ thị có hướng. Ví dụ:
sau Đồ thị - đó là một vòng lặp - là ok:
A -> B
A -> C
B -> C
BFSing từ A, B sẽ được phát hiện, sau đó C. cạnh EAB và EAC là cạnh TREE, và khi EBC vượt qua cuối cùng, B và C được xử lý và phát hiện, và cạnh này được phân loại đúng là CROSS.
Nhưng một vòng lặp đơn giản không hoạt động:
A -> B
B -> C
C -> A
Khi mép ECA được vượt qua, A được xử lý và khám phá. Vì vậy, cạnh này được gắn nhãn không chính xác là CROSS, cho dù nó có phải là một cạnh BACK hay không.
Không có sự khác biệt nào về cách xử lý hai trường hợp, ngay cả khi hai cạnh có các lớp khác nhau.
Làm cách nào để bạn triển khai phân loại cạnh thích hợp cho BFS trên biểu đồ được chỉ dẫn?
EDIT
đây một thực hiện bắt nguồn từ @redtuna câu trả lời. Tôi vừa thêm một kiểm tra không tìm nạp phụ huynh gốc. Tôi có JUnits xét nghiệm cho thấy nó hoạt động cho đồ thị có hướng và vô hướng, trong trường hợp của một vòng lặp, một đường thẳng, một ngã ba, một ví dụ tiêu chuẩn, một lợi thế cạnh duy nhất, vv ....
@Override
public EdgeClass edgeClass(final V from, final V to)
{
if (!discovered.contains(to)) { return EdgeClass.TREE; }
int toDepth = depths.get(to);
int fromDepth = depths.get(from);
V b = to;
while (toDepth > 0 && fromDepth < toDepth)
{
b = parents.get(b);
toDepth = depths.get(b);
}
V a = from;
while (fromDepth > 0 && toDepth < fromDepth)
{
a = parents.get(a);
fromDepth = depths.get(a);
}
if (a.equals(b))
{
return EdgeClass.BACK;
}
else
{
return EdgeClass.CROSS;
}
}
Tôi đã triển khai và thử nghiệm giải pháp này thành công. Nó hoạt động bất kể định hướng/undirected-ness của đồ thị. Tôi đã thực hiện một vài thay đổi nhỏ mà tôi sẽ đăng bên dưới câu hỏi. Cảm ơn! –