Hướng dẫn how do you make a graph in python data structure? - làm thế nào để bạn tạo một biểu đồ trong cấu trúc dữ liệu python?

Lưu ý: Mặc dù JavaScript không cần thiết cho trang web này, nhưng sự tương tác của bạn với nội dung sẽ bị hạn chế. Vui lòng bật JavaScript để có kinh nghiệm đầy đủ. While JavaScript is not essential for this website, your interaction with the content will be limited. Please turn JavaScript on for the full experience.

Cảnh báo

Trang này ở đây vì lý do lịch sử và nó có thể chứa thông tin lỗi thời hoặc không chính xác.

Thay đổi ghi chú: 2/22/98, 3/2/98, 12/4/00: Phiên bản này của bài luận này sửa một số lỗi trong mã. 6/10/19: rút lại
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
0 là "gần như tối ưu". 8/11/19: Khắc phục việc sử dụng tình cờ
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
1 thay vì
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
2
Copyright (c) 1998, 2000, 2003, 2019 Python Software Foundation.
All rights reserved.
Licensed under the PSF license.

Đồ thị là các mạng bao gồm các nút được kết nối bởi các cạnh hoặc cung. Trong các biểu đồ định hướng, các kết nối giữa các nút có một hướng và được gọi là cung; Trong các biểu đồ không mong muốn, các kết nối không có hướng và được gọi là các cạnh. Chúng tôi chủ yếu thảo luận về các biểu đồ có hướng. Các thuật toán trong các biểu đồ bao gồm tìm một đường dẫn giữa hai nút, tìm đường dẫn ngắn nhất giữa hai nút, xác định các chu kỳ trong biểu đồ (một chu kỳ là một đường dẫn không trống từ một nút đến chính nó), tìm đường dẫn đến tất cả các nút ( "Vấn đề nhân viên bán hàng du lịch"), v.v. Đôi khi các nút hoặc cung của biểu đồ có trọng số hoặc chi phí liên quan đến chúng và chúng tôi quan tâm đến việc tìm đường đi rẻ nhất.

Có các tài liệu đáng kể trên các thuật toán đồ thị, là một phần quan trọng của toán học riêng biệt. Đồ thị cũng có nhiều sử dụng thực tế trong các thuật toán máy tính. Các ví dụ rõ ràng có thể được tìm thấy trong việc quản lý các mạng, nhưng các ví dụ rất nhiều trong nhiều lĩnh vực khác. Chẳng hạn, các mối quan hệ caller-callee trong một chương trình máy tính có thể được xem như một biểu đồ (trong đó các chu kỳ biểu thị các nút đệ quy và các nút không thể truy cập đại diện cho mã chết).

Rất ít ngôn ngữ lập trình cung cấp hỗ trợ trực tiếp cho các biểu đồ dưới dạng kiểu dữ liệu và Python cũng không ngoại lệ. Tuy nhiên, đồ thị dễ dàng được xây dựng từ danh sách và từ điển. Chẳng hạn, đây là một biểu đồ đơn giản (tôi không thể sử dụng các bản vẽ trong các cột này, vì vậy tôi viết ra các cung của biểu đồ):

    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
Biểu đồ này có sáu nút (A-F) và tám cung. Nó có thể được biểu diễn bằng cấu trúc dữ liệu Python sau:
    graph = {'A': ['B', 'C'],
             'B': ['C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F'],
             'F': ['C']}
Đây là một từ điển có các khóa là các nút của biểu đồ. Đối với mỗi khóa, giá trị tương ứng là một danh sách chứa các nút được kết nối bởi một cung trực tiếp từ nút này. Điều này đơn giản như nó được (thậm chí đơn giản hơn, các nút có thể được biểu diễn bằng các số thay vì tên, nhưng tên thuận tiện hơn và có thể dễ dàng thực hiện để mang thêm thông tin, chẳng hạn như tên thành phố).

Hãy viết một hàm đơn giản để xác định đường dẫn giữa hai nút. Nó lấy một biểu đồ và các nút bắt đầu và kết thúc làm đối số. Nó sẽ trả về một danh sách các nút (bao gồm các nút bắt đầu và kết thúc) bao gồm đường dẫn. Khi không có đường dẫn có thể được tìm thấy, nó không trả lại. Cùng một nút sẽ không xảy ra nhiều hơn một lần trên đường dẫn được trả về (nghĩa là nó sẽ không chứa các chu kỳ). Thuật toán sử dụng một kỹ thuật quan trọng được gọi là quay lại: nó lần lượt thử từng khả năng cho đến khi tìm thấy một giải pháp.

    def find_path(graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return path
        if not graph.has_key(start):
            return None
        for node in graph[start]:
            if node not in path:
                newpath = find_path(graph, node, end, path)
                if newpath: return newpath
        return None
Một lần chạy mẫu (sử dụng biểu đồ ở trên):
    >>> find_path(graph, 'A', 'D')
    ['A', 'B', 'C', 'D']
    >>>
Câu lệnh 'IF' thứ hai chỉ cần thiết trong trường hợp có các nút được liệt kê là điểm cuối cho các cung nhưng không có vòng cung hướng dẫn và không được liệt kê đồ thị ở tất cả. Các nút như vậy cũng có thể được chứa trong biểu đồ, với một danh sách trống của các vòng cung gửi đi, nhưng đôi khi thuận tiện hơn khi không yêu cầu điều này.

Lưu ý rằng trong khi người dùng gọi

    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
2 với ba đối số, nó sẽ tự gọi với đối số thứ tư: đường dẫn đã bị đi qua. Giá trị mặc định cho đối số này là danh sách trống, '[]', có nghĩa là chưa có nút nào được chuyển qua. Đối số này được sử dụng để tránh các chu kỳ (lần đầu tiên 'IF' bên trong vòng 'cho'). Đối số 'đường dẫn' không được sửa đổi: gán "đường dẫn = đường dẫn + [start]" tạo một danh sách mới. Nếu chúng tôi đã viết "Path.Append (bắt đầu)" thay vào đó, chúng tôi đã sửa đổi 'đường dẫn' biến trong người gọi, với kết quả thảm hại. . biểu hiện.)

Thật đơn giản để thay đổi chức năng này để trả về danh sách tất cả các đường dẫn (không có chu kỳ) thay vì đường dẫn đầu tiên mà nó tìm thấy:

    def find_all_paths(graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return [path]
        if not graph.has_key(start):
            return []
        paths = []
        for node in graph[start]:
            if node not in path:
                newpaths = find_all_paths(graph, node, end, path)
                for newpath in newpaths:
                    paths.append(newpath)
        return paths
Chạy mẫu:
    >>> find_all_paths(graph, 'A', 'D')
    [['A', 'B', 'C', 'D'], ['A', 'B', 'D'], ['A', 'C', 'D']]
    >>>
Một biến thể khác tìm thấy đường dẫn ngắn nhất:
    def find_shortest_path(graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return path
        if not graph.has_key(start):
            return None
        shortest = None
        for node in graph[start]:
            if node not in path:
                newpath = find_shortest_path(graph, node, end, path)
                if newpath:
                    if not shortest or len(newpath) < len(shortest):
                        shortest = newpath
        return shortest
Chạy mẫu:
    >>> find_shortest_path(graph, 'A', 'D')
    ['A', 'C', 'D']
    >>>
Các chức năng này đơn giản như chúng nhận được. Tuy nhiên, chúng gần như tối ưu (đối với mã được viết bằng Python). Trong một cột mẫu Python khác, tôi sẽ cố gắng phân tích tốc độ chạy của chúng và cải thiện hiệu suất của chúng, với chi phí nhiều mã hơn.

CẬP NHẬT: Eryk Kopczyński chỉ ra rằng các chức năng này không tối ưu. Ngược lại, "Chương trình này chạy trong thời gian theo cấp số nhân, trong khi Find_Shortest_Path có thể được thực hiện trong thời gian tuyến tính bằng cách sử dụng BFS [Tìm kiếm đầu tiên trên chiều rộng]. Hơn nữa, BFS tuyến tính đơn giản hơn:" Eryk Kopczyński pointed out that these functions are not optimal. To the contrary, "this program runs in exponential time, while find_shortest_path can be done in linear time using BFS [Breadth First Search]. Furthermore a linear BFS is simpler:"

    # Code by Eryk Kopczyński
    def find_shortest_path(graph, start, end):
        dist = {start: [start]}
        q = deque(start)
        while len(q):
            at = q.popleft()
            for next in graph[at]:
                if next not in dist:
                    dist[next] = [dist[at], next]
                    q.append(next)
        return dist.get(end)
Lưu ý rằng điều này trả về đường dẫn theo định dạng kỳ lạ, ví dụ:
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
4. Cụ thể,
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
5 sẽ đưa ra câu trả lời không chính xác (2, vì danh sách bên ngoài có độ dài 2). Điều này là do phần phụ được thực hiện là
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
6 thay vì
    A -> B
    A -> C
    B -> C
    B -> D
    C -> D
    D -> C
    E -> F
    F -> C
7. Phương pháp thứ hai sẽ sử dụng thời gian và bộ nhớ bậc hai, nhưng vẫn sẽ ổn đối với các biểu đồ tương đối nhỏ; Nếu không, thật dễ dàng để biến danh sách thành định dạng chính xác.

Một biến thể khác sẽ là thêm nhiều trừu tượng dữ liệu: tạo một lớp để biểu thị các biểu đồ, có các phương thức thực hiện các thuật toán khác nhau. Mặc dù điều này hấp dẫn mong muốn lập trình có cấu trúc, nhưng nó không làm cho mã hiệu quả hơn (ngược lại). Nó giúp việc thêm các nhãn khác nhau vào các nút hoặc cung dễ dàng hơn và thêm các thuật toán đưa các nhãn đó vào tài khoản (ví dụ: để tìm tuyến đường ngắn nhất giữa hai thành phố trên bản đồ). Điều này cũng vậy, sẽ là chủ đề của một cột khác.

Làm thế nào để bạn tạo một biểu đồ trong cấu trúc dữ liệu Python?

Cấu trúc dữ liệu đồ thị..
Đỉnh. Một đỉnh là phần cơ bản nhất của biểu đồ và nó còn được gọi là nút. ....
Bờ rìa. Một cạnh là một phần cơ bản khác của biểu đồ và nó kết nối hai đỉnh/ cạnh có thể là một chiều hoặc hai chiều. ....
Trọng lượng. Các cạnh có thể được cân để cho thấy rằng có một chi phí để đi từ đỉnh này sang đỉnh khác. ....
Đồ thị. ....
Đường dẫn. ....
Cycle..

Có cấu trúc dữ liệu đồ thị trong Python không?

Cấu trúc dữ liệu mà tôi thấy là hữu ích và hiệu quả nhất cho các biểu đồ trong Python là một điều kiện của các bộ.Đây sẽ là cấu trúc cơ bản cho lớp đồ thị của chúng tôi.Bạn cũng phải biết liệu các kết nối này là ARC (được định hướng, kết nối một chiều) hoặc các cạnh (không được mong muốn, kết nối cả hai cách).a dict of sets. This will be the underlying structure for our Graph class. You also have to know if these connections are arcs (directed, connect one way) or edges (undirected, connect both ways).

Làm thế nào để bạn bắt đầu một biểu đồ trong Python?

Tạo biểu đồ bằng từ điển trong Python ..
Đồ thị và các biểu diễn của nó ..
Thực hiện đồ thị bằng STL để lập trình cạnh tranh |Đặt 2 (đồ thị có trọng số).
Thực hiện đồ thị bằng STL để lập trình cạnh tranh |Đặt 1 (DFS của không có trọng số và không bị ảnh hưởng).
N Nữ hoàng vấn đề |Backtracking-3 ..

Làm thế nào để bạn đại diện cho một biểu đồ trong cấu trúc dữ liệu?

Một biểu đồ có thể được biểu diễn bằng cách sử dụng 3 cấu trúc dữ liệu- Ma trận liền kề, danh sách kề và tập hợp liền kề.Một ma trận kề có thể được coi là một bảng với các hàng và cột.Các nhãn hàng và nhãn cột biểu thị các nút của biểu đồ.adjacency matrix, adjacency list and adjacency set. An adjacency matrix can be thought of as a table with rows and columns. The row labels and column labels represent the nodes of a graph.