Menu
×

Được chứng nhận

Ghi lại kiến ​​thức của bạn

Đăng nhập Đăng ký

Tạo Tài khoản Example.com.vn miễn phí để cải thiện trải nghiệm học tập của bạn

Người tìm đường và việc học của tôi

Theo dõi tiến độ học tập của bạn tại Example.com.vn và thu thập phần thưởng

Nâng cấp

Trở thành người dùng PLUS và mở khóa các tính năng mạnh mẽ (không có quảng cáo, lưu trữ, hỗ trợ, ..)

Bắt đầu từ đâu

Bạn không chắc chắn muốn bắt đầu từ đâu? Đi theo con đường được hướng dẫn của chúng tôi

Trình chỉnh sửa mã (Dùng thử)

Với trình chỉnh sửa mã trực tuyến của chúng tôi, bạn có thể chỉnh sửa mã và xem kết quả trong trình duyệt của mình

Video

Tìm hiểu những điều cơ bản về HTML qua video hướng dẫn thú vị và hấp dẫn

Mẫu

Chúng tôi đã tạo một loạt mẫu trang web đáp ứng mà bạn có thể sử dụng - miễn phí!

Web hosting

Lưu trữ trang web của riêng bạn và chia sẻ nó với mọi người với Example.com.vn Spaces

Tạo một máy chủ

Tạo máy chủ của riêng bạn bằng Python, PHP, React.js, Node.js, Java, C#, v.v.

Làm thế nào để

Bộ sưu tập lớn các đoạn mã cho HTML, CSS và JavaScript

Khung CSS

Xây dựng các trang web nhanh và phản hồi bằng cách sử dụng khung W3.CSS miễn phí của chúng tôi

Thống kê trình duyệt

Đọc xu hướng dài hạn của việc sử dụng trình duyệt

Tốc độ gõ

Kiểm tra tốc độ đánh máy của bạn

Đào tạo AWS

Tìm hiểu dịch vụ web của Amazon

Bộ chọn màu

Sử dụng công cụ chọn màu của chúng tôi để tìm các màu RGB, HEX và HSL khác nhau. Bánh xe màu hình tròn thể hiện sự chuyển màu trong quang phổ

Trò chơi mã

Trò chơi mã hóa W3Schools! Giúp linh miêu thu thập nón thông Logo Lynx

Đặt mục tiêu

Nhận hành trình học tập được cá nhân hóa dựa trên các kỹ năng và mục tiêu hiện tại của bạn

Bản tin

Tham gia bản tin của chúng tôi và có quyền truy cập vào nội dung độc quyền mỗi tháng

Việc làm

Thuê những tài năng công nghệ hàng đầu. Hợp lý hóa quy trình tuyển dụng của bạn để có đội ngũ phù hợp hoàn hảo

Lớp học

Hãy liên hệ để sử dụng Example.com.vn Plus và các chứng chỉ với tư cách là một tổ chức giáo dục

×
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP CÁCH W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS AN NINH MẠNG DỮ LIỆU KHOA HỌC

Hướng dẫn DSA

DSA TRANG CHỦ DSA Giới thiệu Thuật toán đơn giản DSA

Mảng

Mảng DSA Sắp xếp bong bóng DSA Sắp xếp lựa chọn DSA Sắp xếp chèn DSA Sắp xếp nhanh DSA Sắp xếp đếm DSA Sắp xếp cơ số DSA Sắp xếp hợp nhất DSA Tìm kiếm tuyến tính DSA Tìm kiếm nhị phân DSA

Danh sách liên kết

Danh sách liên kết DSA Danh sách liên kết DSA trong bộ nhớ Danh sách liên kết DSA Các loại Danh sách liên kết Hoạt động

Ngăn xếp & hàng đợi

Ngăn xếp DSA Hàng đợi DSA

Bảng băm

Bảng băm DSA Bộ hàm băm DSA Bản đồ hàm băm DSA

Cây

Cây DSA Cây nhị phân DSA DSA Traversal đặt hàng trước DSA Traversal theo thứ tự DSA Traversal DSA sau thực hiện mảng DSA Cây tìm kiếm nhị phân DSA Cây AVL DSA

Đồ thị

Đồ thị DSA Thực hiện đồ thị Đồ thị DSA Phát hiện chu trình DSA truyền tải

Con đường ngắn nhất

Đường đi ngắn nhất DSA DSA Bellman-Ford của DSA Dijkstra

Cây bao trùm tối thiểu

Cây khung tối thiểu DSA Prim's DSA Kruskal's

Lưu lượng cực đại

DSA Lưu lượng tối đa DSA Ford-Fulkerson DSA Edmonds-Karp

Độ phức tạp thời gian

Giới thiệu Sắp xếp bong bóng Lựa chọn Sắp xếp Chèn Sắp xếp Sắp xếp nhanh Đếm Sắp xếp Cơ số Sắp xếp Hợp nhất Sắp xếp Tìm kiếm tuyến tính Tìm kiếm nhị phân

Tham chiếu DSA

Thuật toán Euclide DSA Thuật toán tham lam DSA Ghi nhớ DSA DSA Người bán hàng du lịch

Ví dụ về DSA

Ví dụ về DSA Bài tập DSA Câu hỏi DSA Chứng chỉ DSA

Thuật toán DSA Ford-Fulkerson

Thuật toán Ford-Fulkerson giải bài toán luồng cực đại.

Việc tìm kiếm luồng tối đa có thể hữu ích trong nhiều lĩnh vực: tối ưu hóa lưu lượng mạng, sản xuất, chuỗi cung ứng và hậu cần hoặc lập lịch trình hàng không.

Thuật toán Ford-Fulkerson

Thuật toán Ford-Fulkerson giải bài toán luồng cực đại cho đồ thị có hướng.

Luồng xuất phát từ đỉnh nguồn (\(s\)) và kết thúc ở đỉnh chìm (\(t\)) và mỗi cạnh trong biểu đồ cho phép một luồng, bị giới hạn bởi dung lượng.

{{edge.flow}}/{{edge.capacity}} {{vertex.name}}

Lưu lượng tối đa: {{maxFlow}}

{{statusText}}

Thuật toán Ford-Fulkerson hoạt động bằng cách tìm kiếm một đường dẫn có dung lượng khả dụng từ nguồn đến đích (được gọi là đường dẫn tăng cường ), sau đó gửi càng nhiều luồng càng tốt qua đường dẫn đó.

Thuật toán Ford-Fulkerson tiếp tục tìm ra những đường dẫn mới để gửi nhiều luồng hơn cho đến khi đạt được luồng tối đa.

Trong mô phỏng ở trên, thuật toán Ford-Fulkerson giải quyết vấn đề luồng tối đa: Nó tìm ra lượng luồng có thể được gửi từ đỉnh nguồn \(s\), đến đỉnh đích \(t\) và luồng tối đa đó là số 8.

Các số trong mô phỏng ở trên được viết dưới dạng phân số, trong đó số đầu tiên là luồng và số thứ hai là dung lượng (luồng tối đa có thể có ở cạnh đó). Vì vậy, ví dụ: 0/7 trên cạnh \(s \rightarrow v_2\), nghĩa là có 0 luồng, với dung lượng là 7 trên cạnh đó.

Lưu ý: Thuật toán Ford-Fulkerson thường được mô tả như một phương pháp thay vì một thuật toán , bởi vì nó không chỉ định cách tìm đường dẫn mà luồng có thể tăng lên. Điều này có nghĩa là nó có thể được thực hiện theo nhiều cách khác nhau, dẫn đến độ phức tạp về thời gian khác nhau. Nhưng đối với hướng dẫn này, chúng tôi sẽ gọi nó là một thuật toán và sử dụng Tìm kiếm theo chiều sâu để tìm đường dẫn.

Bạn có thể xem mô tả cơ bản từng bước về cách hoạt động của thuật toán Ford-Fulkerson bên dưới, nhưng sau này chúng ta cần đi sâu vào chi tiết hơn để thực sự hiểu nó.

Làm thế nào nó hoạt động:

  1. Bắt đầu với dòng chảy bằng 0 trên tất cả các cạnh.
  2. Tìm một đường dẫn tăng cường để có thể gửi nhiều luồng hơn.
  3. Thực hiện tính toán nút cổ chai để tìm hiểu xem có thể gửi bao nhiêu luồng thông qua đường dẫn tăng cường đó.
  4. Tăng luồng được tìm thấy từ tính toán nút cổ chai cho mỗi cạnh trong đường dẫn tăng cường.
  5. Lặp lại các bước 2-4 cho đến khi tìm thấy lưu lượng tối đa. Điều này xảy ra khi không thể tìm thấy đường dẫn tăng cường mới nữa.

Mạng lưới dư ở Ford-Fulkerson

Thuật toán Ford-Fulkerson thực sự hoạt động bằng cách tạo và sử dụng một thứ gọi là mạng dư , là biểu diễn của biểu đồ gốc.

Trong mạng dư, mọi cạnh đều có dung lượng dư , là dung lượng ban đầu của cạnh, trừ đi luồng trong cạnh đó. Dung lượng dư có thể được coi là dung lượng còn sót lại ở một cạnh có dòng chảy nào đó.

Ví dụ: nếu có luồng 2 ở cạnh \( v_3 \rightarrow v_4 \) và dung lượng là 3 thì luồng dư là 1 ở cạnh đó, vì có chỗ để gửi thêm 1 đơn vị luồng qua cạnh đó bờ rìa.


Các cạnh đảo ngược ở Ford-Fulkerson

Thuật toán Ford-Fulkerson cũng sử dụng một thứ gọi là các cạnh đảo ngược để gửi luồng ngược lại. Điều này rất hữu ích để tăng tổng lưu lượng.

Ví dụ: đường dẫn tăng cường cuối cùng \(s \rightarrow v_2 \rightarrow v_4 \rightarrow v_3 \rightarrow t\) trong hoạt ảnh ở trên và trong hướng dẫn chạy qua bên dưới cho thấy tổng luồng được tăng thêm một đơn vị như thế nào, bằng cách thực sự gửi luồng ngược lại trên cạnh \( v_4 \rightarrow v_3 \), gửi luồng theo hướng ngược lại.

Gửi luồng ngược lại trên cạnh \( v_3 \rightarrow v_4 \) trong ví dụ của chúng tôi có nghĩa là 1 đơn vị luồng này đi ra khỏi đỉnh \( v_3 \), hiện rời khỏi \( v_3 \) trên cạnh \( v_3 \ rightarrow t \) thay vì \( v_3 \rightarrow v_4 \).

Để gửi luồng ngược lại, theo hướng ngược lại của cạnh, một cạnh ngược được tạo cho mỗi cạnh ban đầu trong mạng. Thuật toán Ford-Fulkerson sau đó có thể sử dụng các cạnh ngược này để gửi luồng theo hướng ngược lại.

Cạnh đảo ngược không có dòng chảy hoặc dung lượng, chỉ có dung lượng dư. Dung lượng dư của cạnh đảo ngược luôn bằng lưu lượng ở cạnh ban đầu tương ứng. Trong ví dụ của chúng tôi, cạnh \( v_3 \rightarrow v_4 \) có luồng 2, nghĩa là có dung lượng dư là 2 trên cạnh đảo ngược tương ứng \( v_4 \rightarrow v_3 \).

Điều này chỉ có nghĩa là khi có luồng 2 trên cạnh ban đầu \( v_3 \rightarrow v_4 \), thì có khả năng gửi cùng một lượng luồng đó trở lại cạnh đó, nhưng theo hướng ngược lại. Việc sử dụng cạnh đảo ngược để đẩy lùi luồng cũng có thể được coi là hoàn tác một phần của luồng đã được tạo.

Ý tưởng về mạng dư với dung lượng dư trên các cạnh và ý tưởng về các cạnh đảo ngược là trọng tâm trong cách hoạt động của thuật toán Ford-Fulkerson và chúng tôi sẽ đi sâu vào chi tiết hơn về điều này khi chúng tôi triển khai thuật toán sâu hơn trên trang này.


Chạy qua thủ công

Không có luồng nào trong biểu đồ để bắt đầu.

Để tìm luồng tối đa, thuật toán Ford-Fulkerson phải tăng luồng, nhưng trước tiên nó cần tìm ra nơi có thể tăng luồng: nó phải tìm một đường dẫn tăng cường.

Thuật toán Ford-Fulkerson thực sự không chỉ định cách tìm thấy đường dẫn tăng cường như vậy (đó là lý do tại sao nó thường được mô tả như một phương pháp thay vì thuật toán), nhưng chúng tôi sẽ sử dụng Tìm kiếm theo chiều sâu (DFS) để tìm các đường dẫn tăng cường cho Thuật toán Ford-Fulkerson trong hướng dẫn này.

Đường dẫn mở rộng đầu tiên mà Ford-Fulkerson tìm thấy khi sử dụng DFS là \(s \rightarrow v_1 \rightarrow v_3 \rightarrow v_4 \rightarrow t\).

Và bằng cách sử dụng phép tính thắt cổ chai, Ford-Fulkerson nhận thấy rằng 3 là luồng cao nhất có thể được gửi qua đường dẫn tăng cường, do đó luồng được tăng thêm 3 cho tất cả các cạnh trong đường dẫn này.

{{edge.flow}}/{{edge.capacity}} {{vertex.name}}

Lần lặp tiếp theo của thuật toán Ford-Fulkerson là thực hiện lại các bước sau:

  1. Tìm một con đường tăng cường mới
  2. Tìm xem luồng trong đường dẫn đó có thể tăng lên bao nhiêu
  3. Tăng luồng dọc theo các cạnh trong đường dẫn đó cho phù hợp

Đường dẫn tăng cường tiếp theo được tìm thấy là \(s \rightarrow v_2 \rightarrow v_1 \rightarrow v_4 \rightarrow v_3 \rightarrow t\), bao gồm cạnh đảo ngược \(v_4 \rightarrow v_3\) , nơi luồng được gửi trở lại.

Khái niệm Ford-Fulkerson về các cạnh đảo ngược rất hữu ích vì nó cho phép phần tìm đường đi của thuật toán tìm đường dẫn tăng cường trong đó các cạnh đảo ngược cũng có thể được đưa vào.

Trong trường hợp cụ thể này, điều đó có nghĩa là luồng 2 có thể được gửi trở lại cạnh \(v_3 \rightarrow v_4\), thay vào đó sẽ đi vào \(v_3 \rightarrow t\).

Luồng chỉ có thể tăng thêm 2 trong đường dẫn này vì đó là dung lượng ở cạnh \( v_3 \rightarrow t \).

{{edge.flow}}/{{edge.capacity}} {{vertex.name}}

Đường dẫn mở rộng tiếp theo được tìm thấy là \(s \rightarrow v_2 \rightarrow v_1 \rightarrow v_4 \rightarrow t\).

Lưu lượng có thể tăng thêm 2 trong đường dẫn này. Nút cổ chai (cạnh giới hạn) là \( v_1 \rightarrow v_4 \) vì chỉ còn chỗ để gửi thêm hai đơn vị luồng ở cạnh đó.

{{edge.flow}}/{{edge.capacity}} {{vertex.name}}

Đường dẫn tăng cường tiếp theo và cuối cùng là \(s \rightarrow v_2 \rightarrow v_4 \rightarrow t\).

Luồng chỉ có thể tăng thêm 1 trong đường dẫn này do cạnh \( v_4 \rightarrow t \) là nút cổ chai trong đường dẫn này chỉ có không gian cho thêm một đơn vị luồng (\(capacity-flow=1\)).

{{edge.flow}}/{{edge.capacity}} {{vertex.name}}

Tại thời điểm này, không thể tìm thấy đường dẫn tăng cường mới (không thể tìm thấy đường dẫn có thể gửi nhiều luồng hơn từ \(s\) đến \(t\)), có nghĩa là luồng tối đa đã được tìm thấy, và thuật toán Ford-Fulkerson đã hoàn thành.

Luồng tối đa là 8. Như bạn có thể thấy trong hình trên, luồng (8) đi ra khỏi đỉnh nguồn \(s\), giống như luồng đi vào đỉnh đích \(t\).

Ngoài ra, nếu bạn lấy bất kỳ đỉnh nào khác ngoài \(s\) hoặc \(t\), bạn có thể thấy rằng lượng dòng chảy đi vào một đỉnh cũng giống như lượng dòng chảy đi ra khỏi đỉnh đó. Đây là cái mà chúng ta gọi là bảo toàn luồng và điều này phải đúng cho tất cả các mạng luồng như vậy (đồ thị có hướng trong đó mỗi cạnh có một luồng và dung lượng).


Triển khai thuật toán Ford-Fulkerson

Để triển khai thuật toán Ford-Fulkerson, chúng tôi tạo một lớp Graph . Graph biểu thị đồ thị với các đỉnh và cạnh của nó:

 class Graph:
    def __init__(self, size):
        self.adj_matrix = [[0] * size for _ in range(size)]
        self.size = size
        self.vertex_data = [''] * size

    def add_edge(self, u, v, c):
        self.adj_matrix[u][v] = c

    def add_vertex_data(self, vertex, data):
        if 0 <= vertex < self.size:
            self.vertex_data[vertex] = data

Dòng 3: Chúng ta tạo adj_matrix để chứa tất cả các cạnh và dung lượng của cạnh. Giá trị ban đầu được đặt thành 0 .

Dòng 4: size là số đỉnh của đồ thị.

Dòng 5: vertex_data chứa tên của tất cả các đỉnh.

Dòng 7-8: Phương thức add_edge được sử dụng để thêm một cạnh từ đỉnh u đến đỉnh v , với dung lượng c .

Dòng 10-12: Phương thức add_vertex_data được sử dụng để thêm tên đỉnh vào biểu đồ. Chỉ mục của đỉnh được đưa ra cùng với đối vertexdata là tên của đỉnh.

Lớp Graph cũng chứa phương thức dfs để tìm các đường dẫn mở rộng, sử dụng Depth-First-Search:

    def dfs(self, s, t, visited=None, path=None):
        if visited is None:
            visited = [False] * self.size
        if path is None:
            path = []

        visited[s] = True
        path.append(s)

        if s == t:
            return path

        for ind, val in enumerate(self.adj_matrix[s]):
            if not visited[ind] and val > 0:
                result_path = self.dfs(ind, t, visited, path.copy())
                if result_path:
                    return result_path

        return None

Dòng 15-18: Mảng visited giúp tránh việc xem lại các đỉnh giống nhau trong quá trình tìm kiếm đường dẫn tăng cường. Các đỉnh thuộc đường dẫn tăng cường được lưu trữ trong mảng path .

Dòng 20-21: Đỉnh hiện tại được đánh dấu là đã ghé thăm và sau đó được thêm vào đường dẫn.

Dòng 23-24: Nếu đỉnh hiện tại là nút đích, chúng ta đã tìm thấy một đường dẫn tăng cường từ đỉnh nguồn đến đỉnh đích, do đó đường dẫn đó có thể được trả về.

Dòng 26-30: Lặp qua tất cả các cạnh trong ma trận kề bắt đầu từ đỉnh hiện tại s , ind đại diện cho một nút liền kề và val là dung lượng còn lại trên cạnh tới đỉnh đó. Nếu đỉnh liền kề không được thăm và còn dung lượng dư trên cạnh của nó, hãy đi tới nút đó và tiếp tục tìm kiếm đường đi từ đỉnh đó.

Dòng 32: None trả về giá trị nào nếu không tìm thấy đường dẫn.

Phương thức fordFulkerson là phương thức cuối cùng chúng ta thêm vào lớp Graph :

    def fordFulkerson(self, source, sink):
        max_flow = 0

        path = self.dfs(source, sink)
        while path:
            path_flow = float("Inf")
            for i in range(len(path) - 1):
                u, v = path[i], path[i + 1]
                path_flow = min(path_flow, self.adj_matrix[u][v])

            for i in range(len(path) - 1):
                u, v = path[i], path[i + 1]
                self.adj_matrix[u][v] -= path_flow
                self.adj_matrix[v][u] += path_flow

            max_flow += path_flow

            path_names = [self.vertex_data[node] for node in path]
            print("Path:", " -> ".join(path_names), ", Flow:", path_flow)

            path = self.dfs(source, sink)

        return max_flow

Ban đầu, max_flow0 và vòng lặp while tiếp tục tăng max_flow miễn là có đường dẫn tăng cường để tăng lưu lượng vào.

Dòng 37: Đã tìm thấy đường dẫn tăng cường.

Dòng 39-42: Mỗi cạnh trong đường dẫn tăng cường được kiểm tra để tìm ra lượng luồng có thể được gửi qua đường dẫn đó.

Dòng 44-46: Dung lượng dư (dung lượng trừ lưu lượng) cho mỗi cạnh phía trước bị giảm do lưu lượng tăng lên.

Dòng 47: Dòng này thể hiện cạnh đảo ngược, được sử dụng bởi thuật toán Ford-Fulkerson để luồng có thể được gửi trở lại (hoàn tác) trên các cạnh chuyển tiếp ban đầu. Điều quan trọng là phải hiểu rằng các cạnh đảo ngược này không có trong biểu đồ gốc, chúng là các cạnh hư cấu được Ford-Fulkerson giới thiệu để làm cho thuật toán hoạt động.

Dòng 49: Mỗi khi luồng tăng lên trên một đường dẫn tăng cường, max_flow được tăng cùng một giá trị.

Dòng 51-52: Dòng này chỉ để in đường dẫn tăng cường trước khi thuật toán bắt đầu lần lặp tiếp theo.

Sau khi xác định lớp Graph , các đỉnh và cạnh phải được xác định để khởi tạo biểu đồ cụ thể và mã hoàn chỉnh cho ví dụ về thuật toán Ford-Fulkerson trông như thế này:

Ví dụ

Trăn:

 class Graph:
    def __init__(self, size):
        self.adj_matrix = [[0] * size for _ in range(size)]
        self.size = size
        self.vertex_data = [''] * size

    def add_edge(self, u, v, c):
        self.adj_matrix[u][v] = c

    def add_vertex_data(self, vertex, data):
        if 0 <= vertex < self.size:
            self.vertex_data[vertex] = data

    def dfs(self, s, t, visited=None, path=None):
        if visited is None:
            visited = [False] * self.size
        if path is None:
            path = []

        visited[s] = True
        path.append(s)

        if s == t:
            return path

        for ind, val in enumerate(self.adj_matrix[s]):
            if not visited[ind] and val > 0:
                result_path = self.dfs(ind, t, visited, path.copy())
                if result_path:
                    return result_path

        return None

    def fordFulkerson(self, source, sink):
        max_flow = 0

        path = self.dfs(source, sink)
        while path:
            path_flow = float("Inf")
            for i in range(len(path) - 1):
                u, v = path[i], path[i + 1]
                path_flow = min(path_flow, self.adj_matrix[u][v])

            for i in range(len(path) - 1):
                u, v = path[i], path[i + 1]
                self.adj_matrix[u][v] -= path_flow
                self.adj_matrix[v][u] += path_flow

            max_flow += path_flow

            path_names = [self.vertex_data[node] for node in path]
            print("Path:", " -> ".join(path_names), ", Flow:", path_flow)

            path = self.dfs(source, sink)

        return max_flow

g = Graph(6)
vertex_names = ['s', 'v1', 'v2', 'v3', 'v4', 't']
for i, name in enumerate(vertex_names):
    g.add_vertex_data(i, name)

g.add_edge(0, 1, 3)  # s  -> v1, cap: 3
g.add_edge(0, 2, 7)  # s  -> v2, cap: 7
g.add_edge(1, 3, 3)  # v1 -> v3, cap: 3
g.add_edge(1, 4, 4)  # v1 -> v4, cap: 4
g.add_edge(2, 1, 5)  # v2 -> v1, cap: 5
g.add_edge(2, 4, 3)  # v2 -> v4, cap: 3
g.add_edge(3, 4, 3)  # v3 -> v4, cap: 3
g.add_edge(3, 5, 2)  # v3 -> t,  cap: 2
g.add_edge(4, 5, 6)  # v4 -> t,  cap: 6

source = 0; sink = 5

print("The maximum possible flow is %d " % g.fordFulkerson(source, sink))
Chạy ví dụ »

Độ phức tạp thời gian của thuật toán Ford-Fulkerson

Độ phức tạp về thời gian của Ford-Fulkerson thay đổi theo số đỉnh \(V\), số cạnh \(E\) và nó thực tế cũng thay đổi theo luồng tối đa \(f\) trong biểu đồ.

Lý do tại sao độ phức tạp thời gian thay đổi theo luồng tối đa \(f\) trong biểu đồ là vì trong biểu đồ có thông lượng cao, sẽ có nhiều đường dẫn tăng cường hơn làm tăng lưu lượng và điều đó có nghĩa là phương pháp DFS tìm thấy những đường dẫn tăng cường này path sẽ phải chạy nhiều lần hơn.

Tìm kiếm theo chiều sâu (DFS) có độ phức tạp về thời gian \(O(V+E)\).

DFS chạy một lần cho mỗi đường dẫn tăng cường mới. Nếu chúng tôi giả định rằng mỗi biểu đồ tăng cường tăng luồng thêm 1 đơn vị thì DFS phải chạy \(f\) lần, gấp nhiều lần giá trị của luồng tối đa.

Điều này có nghĩa là độ phức tạp về thời gian đối với thuật toán Ford-Fulkerson, sử dụng DFS, là

\[ O( (V+E) \cdot f ) \]

Đối với các đồ thị dày đặc , trong đó \( E > V \), độ phức tạp về thời gian cho DFS có thể được đơn giản hóa thành \(O(E)\), điều đó có nghĩa là độ phức tạp về thời gian của thuật toán Ford-Fulkerson cũng có thể được đơn giản hóa thành

\[ O( E \cdot f ) \]

Đồ thị dày đặc không có định nghĩa chính xác nhưng nó là đồ thị có nhiều cạnh.

Thuật toán tiếp theo mà chúng tôi sẽ mô tả để tìm luồng cực đại là thuật toán Edmonds-Karp .

Thuật toán Edmonds-Karp rất giống với Ford-Fulkerson, nhưng nó sử dụng BFS thay vì DFS để tìm các đường dẫn tăng cường, dẫn đến ít lần lặp hơn để tìm luồng tối đa.



×

Liên hệ bán hàng

Nếu bạn muốn sử dụng dịch vụ của Example.com.vn với tư cách là một tổ chức giáo dục, nhóm hoặc doanh nghiệp, hãy gửi email cho chúng tôi:
[email được bảo vệ]

Báo cáo lỗi

Nếu bạn muốn báo cáo lỗi hoặc nếu bạn muốn đưa ra đề xuất, hãy gửi email cho chúng tôi:
[email được bảo vệ]

Example.com.vn được tối ưu hóa cho việc học tập và đào tạo. Các ví dụ có thể được đơn giản hóa để cải thiện khả năng đọc và học. Các hướng dẫn, tài liệu tham khảo và ví dụ liên tục được xem xét để tránh sai sót, nhưng chúng tôi không thể đảm bảo tính chính xác hoàn toàn của mọi nội dung. Khi sử dụng W3Schools, bạn đồng ý đã đọc và chấp nhận các điều khoản sử dụng , chính sách cookie và quyền riêng tư của chúng tôi.

Bản quyền 1999-2024 của Refsnes Data. Đã đăng ký Bản quyền. Example.com.vn được cung cấp bởi W3.CSS .