Câu hỏi:

11/07/2024 168 Lưu

Hàm DFS(Adj,u) có thể viết theo một cách khác, việc kiểm tra đỉnh u đã đánh dấu chưa được đưa vào bên trong hàm như sau:

Hàm DFS(Adj,u) có thể viết theo một cách khác, việc kiểm tra đỉnh u đã đánh dấu chưa được đưa vào bên trong hàm như sau: (ảnh 1)

a) Trong trường hợp này, phần chương trình chính cần viết lại như thế nào?

b) Viết lại toàn bộ chương trình duyệt đồ thị theo chiều sâu theo hàm mô tả trên. Cách duyệt này có tương đương với cách đã thực hiện trong Hoạt động 2 không?

Quảng cáo

Trả lời:

verified Giải bởi Vietjack

a) Phần chương trình chính cần viết lại:

Phần chính của chương trình sẽ khởi tạo danh sách đánh dấu (mark) và gọi hàm DFS từ đỉnh bắt đầu.

def main(graph, start):

    # Khởi tạo mảng đánh dấu cho tất cả các đỉnh

    mark = {node: False for node in graph}

    # Gọi hàm DFS từ đỉnh bắt đầu

    DFS(graph, start, mark)

b) Viết lại toàn bộ chương trình duyệt đồ thị theo chiều sâu:

Dưới đây là toàn bộ chương trình với hàm DFS kiểm tra và đánh dấu đỉnh bên trong hàm:

def DFS(graph, u, mark):

    if not mark[u]:

       mark[u] = True  # Đánh dấu đỉnh u

       print("Visit:", u)  # In ra đỉnh đang được thăm

       for v in graph[u]:

           DFS(graph, v, mark)

def main(graph, start):

    # Khởi tạo mảng đánh dấu cho tất cả các đỉnh

    mark = {node: False for node in graph}

    # Gọi hàm DFS từ đỉnh bắt đầu

   DFS(graph, start, mark)

# Đồ thị mẫu dưới dạng danh sách kề

graph = {

    'A': ['B', 'C'],

    'B': ['A', 'D', 'E'],

    'C': ['A', 'F'],

    'D': ['B'],

    'E': ['B', 'F'],

    'F': ['C', 'E']

}

# Thực hiện DFS từ đỉnh 'A'

main(graph, 'A')

Giải thích:

1. Hàm DFS:

Kiểm tra nếu đỉnh u chưa được đánh dấu.

Đánh dấu đỉnh u và in ra đỉnh đang được thăm.

Duyệt qua các đỉnh kề của u và gọi đệ quy hàm DFS cho từng đỉnh kề đó.

2. Hàm main:

Khởi tạo danh sách đánh dấu (mark) cho tất cả các đỉnh trong đồ thị.

Gọi hàm DFS từ đỉnh bắt đầu (start).

So sánh với cách đã thực hiện trong Hoạt động 2:

Cách duyệt này về cơ bản là tương đương với cách đã thực hiện trong Hoạt động 2 (không đệ quy) về mặt chức năng, tức là cả hai đều thực hiện duyệt đồ thị theo chiều sâu và đảm bảo tất cả các đỉnh đều được thăm một lần. Tuy nhiên, cách đệ quy này dễ hiểu và ngắn gọn hơn, nhưng có thể gặp vấn đề về ngăn xếp đệ quy nếu đồ thị quá lớn (vượt quá giới hạn ngăn xếp của Python). Trong khi đó, cách không đệ quy thường sử dụng ngăn xếp tự quản lý và phù hợp với các đồ thị lớn hơn trong thực tế.

CÂU HỎI HOT CÙNG CHỦ ĐỀ

Lời giải

Ý tưởng chính của DFS: 

DFS hoạt động bằng cách bắt đầu từ một đỉnh nguồn, đánh dấu nó là đã thăm, sau đó tiếp tục đi sâu vào các đỉnh kề chưa thăm cho đến khi không thể đi tiếp được nữa. Khi không thể đi tiếp, thuật toán quay lui về các đỉnh trước đó để tiếp tục tìm kiếm các đường đi mới.

Lời giải

Để sửa đổi chương trình của thuật toán DFS không đệ quy sao cho nó in ra thông tin ngăn xếp hiện thời, phần tử được lấy ra từ ngăn xếp, và phần tử được đánh dấu để chuẩn bị cho bước sau, bạn có thể thực hiện như sau:

def dfs(graph, start):

   stack = [start]  # Ngăn xếp khởi tạo với đỉnh bắt đầu

   visited = set()  # Tập hợp các đỉnh đã được thăm

   while stack:

       # In thông tin ngăn xếp hiện thời

       print("Stack hiện thời:", stack)

       vertex = stack.pop()  # Lấy phần tử từ ngăn xếp

       print("Phần tử lấy ra từ ngăn xếp:", vertex)

       if vertex not in visited:

           print("Phần tử được đánh dấu để chuẩn bị cho bước sau (mark):", vertex)

           visited.add(vertex)  # Đánh dấu phần tử đã thăm

           # Thêm các đỉnh kề vào ngăn xếp

           for neighbor in reversed(graph[vertex]):

               if neighbor not in visited:

                    stack.append(neighbor)

   return visited

# Đồ thị mẫu dưới dạng danh sách kề

graph = {

    'A': ['B', 'C'],

    'B': ['A', 'D', 'E'],

    'C': ['A', 'F'],

    'D': ['B'],

    'E': ['B', 'F'],

    'F': ['C', 'E']

}

# Thực hiện DFS từ đỉnh 'A'

dfs(graph, 'A')

Giải thích:

- Ngăn xếp (Stack): Ban đầu ngăn xếp chứa đỉnh bắt đầu. Mỗi vòng lặp, bạn in ra ngăn xếp hiện thời.

- Phần tử được lấy ra từ ngăn xếp (vertex): Phần tử trên đỉnh ngăn xếp được lấy ra và in ra.

- Phần tử được đánh dấu (mark): Nếu phần tử chưa được thăm, nó được đánh dấu (thêm vào tập visited) và in ra.

Các bước thực hiện:

- Khởi tạo ngăn xếp với đỉnh bắt đầu (start).

- Trong khi ngăn xếp không rỗng:

In thông tin ngăn xếp hiện thời.

Lấy phần tử từ ngăn xếp và in ra.

Nếu phần tử chưa được thăm:

+ Đánh dấu phần tử đã thăm và in ra.

+ Thêm các đỉnh kề vào ngăn xếp theo thứ tự ngược lại để duyệt đúng thứ tự DFS.

Lời giải

Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.

Nâng cấp VIP

Lời giải

Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.

Nâng cấp VIP

Lời giải

Bạn cần đăng ký gói VIP ( giá chỉ từ 199K ) để làm bài, xem đáp án và lời giải chi tiết không giới hạn.

Nâng cấp VIP