Tìm kiểu dữ liệu bị thiếu
- Đồ thị là một tập hợp các nút, được kết nối bằng các mũi tên (cạnh).
- Nút và cạnh có thể chứa dữ liệu.
- Trong kỹ thuật phần mềm, đồ thị xuất hiện dưới nhiều dạng như phụ thuộc gói, liên kết Internet, không gian trạng thái của phần mềm, cơ sở dữ liệu quan hệ, danh sách liên kết, cây nhị phân, bảng băm, v.v.
- Trong logic nghiệp vụ, đồ thị cũng được dùng cho tham chiếu trích dẫn, mạng lưới giao thông, mạng xã hội, v.v.
- Nếu làm phát triển phần mềm đủ lâu, rất có thể bạn sẽ gặp đồ thị ở khắp mọi nơi.
Suy nghĩ về việc dùng đồ thị
- Đồ thị rất hữu ích, nhưng việc sử dụng đồ thị trong mã thực tế lại khá nặng nề.
- Trong phần lớn các ngôn ngữ chủ đạo, đồ thị không được hỗ trợ như một kiểu dựng sẵn; ngay cả trong thư viện chuẩn cũng hiếm thấy, và số thư viện bên thứ ba đủ vững chắc cũng không nhiều.
- Trong nhiều trường hợp, bạn phải tự cài đặt đồ thị.
- Có một khoảng cách giữa tần suất mà kỹ sư phần mềm có thể dùng đồ thị và mức độ hỗ trợ dành cho nó trong hệ sinh thái lập trình.
Vì sao không có kiểu đồ thị
Có quá nhiều lựa chọn về thiết kế
- Có rất nhiều loại đồ thị khác nhau: đồ thị có hướng và vô hướng, đồ thị đơn và đa đồ thị, siêu đồ thị, ubergraph, v.v.
- Với từng loại, còn phải quyết định có gán ID cho nút và cạnh hay không, sẽ lưu kiểu dữ liệu nào, v.v.
- Một thư viện đồ thị hoàn hảo hỗ trợ mọi khả năng sẽ tốn rất nhiều thời gian để xây dựng.
- Hiệu năng của các thuật toán đồ thị rất quan trọng, và các trường hợp đặc thù cũng rất quan trọng.
- Các thuật toán đồ thị rất khó cài đặt cho đúng.
Có quá nhiều lựa chọn về cách triển khai
- Ngay cả khi chỉ giả sử hỗ trợ một đồ thị có hướng đơn giản, vẫn có nhiều cách để biểu diễn đồ thị ở bên trong.
- Có nhiều cách lưu trữ như danh sách cạnh, danh sách kề, ma trận kề, tập hợp các struct, v.v.
- Những phép toán đồ thị khác nhau sẽ có đặc tính hiệu năng khác nhau tùy theo cách biểu diễn.
- Tùy vào độ thưa hay độ dày của đồ thị mà cách biểu diễn nội bộ tối ưu sẽ khác nhau.
- Việc triển khai dữ liệu của nút, dữ liệu của cạnh, cũng như nhiều kiểu nút và cạnh khác nhau còn làm mọi thứ phức tạp hơn.
Hiệu năng quá quan trọng
- Nhiều thuật toán đồ thị là bài toán NP-đầy đủ hoặc còn khó hơn.
- Đồ thị có thể trở thành những bài toán cực lớn, và hiệu năng có thể khác biệt rất nhiều tùy theo cách biểu diễn và chi tiết cài đặt thuật toán.
- Cần có nhiều quyền kiểm soát đối với biểu diễn dữ liệu và thuật toán.
Quan điểm thống nhất
- Sự đa dạng của loại đồ thị, cách biểu diễn, thuật toán, độ nhạy với hiệu năng, và chi phí chạy các thuật toán đắt đỏ trên đồ thị lớn là những lý do khiến hỗ trợ cho đồ thị không phổ biến rộng rãi.
- Điều này giải thích vì sao các ngôn ngữ không hỗ trợ đồ thị trong thư viện chuẩn.
- Điều này cũng giải thích vì sao lập trình viên thường tránh các thư viện đồ thị bên thứ ba.
- Vì dùng đồ thị là việc khó, nên trừ những trường hợp cực đoan, người ta không muốn phải suy nghĩ theo hướng đồ thị.
Ý kiến của GN⁺
- Bài viết này mang lại góc nhìn về lý do vì sao đồ thị chưa trở thành một kiểu dữ liệu cơ bản trong ngôn ngữ lập trình và thư viện.
- Lý thuyết đồ thị là một lĩnh vực quan trọng của khoa học máy tính và được ứng dụng trong nhiều mảng như thuật toán, phân tích mạng, cơ sở dữ liệu, v.v.
- Để sử dụng đồ thị hiệu quả, tối ưu hiệu năng và lựa chọn cấu trúc dữ liệu phù hợp là rất quan trọng.
- Một số thư viện bên thứ ba như NetworkX, Boost Graph Library, Graph-tool có thể được dùng để giải quyết nhiều bài toán đồ thị khác nhau.
- Khi dùng đồ thị, điều quan trọng là chọn loại đồ thị và thuật toán phù hợp với đặc tính của bài toán, vì điều này ảnh hưởng trực tiếp đến hiệu năng của hệ thống.
1 bình luận
Ý kiến trên Hacker News
Graphviz có thư viện đồ thị riêng của mình, và thư viện này không được dùng trong các dự án khác. Thư viện đó có cả ưu và nhược điểm.
Nếu bạn lập trình trên .NET, tôi khuyên nên thử Arborescence, một thư viện đồ thị nhỏ và không quá nhiều tính năng.
Đồ thị không phải là cấu trúc dữ liệu hay kiểu dữ liệu, mà là một phép trừu tượng.
Tôi đã nhận được rất nhiều câu hỏi về lý do không có kiểu dữ liệu đồ thị được tích hợp sẵn trong ngôn ngữ lập trình.
Trở ngại trung tâm là như sau:
Bài viết này phần lớn trả lời câu hỏi vì sao thuật toán đồ thị không được hỗ trợ tốt hơn trong ngôn ngữ lập trình.
Các công cụ vẽ đồ thị cũng rất đáng thất vọng.
Bài viết này thực sự rất hay.
Electric Clojure dùng chính Clojure (s-expression) làm cú pháp để biên soạn đồ thị.
Có một kiểu dữ liệu hữu ích khác giống như bảng, chẳng hạn bảng trong cơ sở dữ liệu.