Clique cực đại
Kiến thức nền tảng: Khái niệm về Clique (Đoàn)
Giới thiệu
Trong khoa học máy tính, bài toán clique (đoàn) là bài toán tìm một clique (tập con các đỉnh mà mọi cặp đều kề nhau, còn gọi là đồ thị con đầy đủ) trong một đồ thị cho trước.
Bài toán clique cũng xuất hiện trong thực tế. Ví dụ, xét một mạng xã hội, mỗi đỉnh là một người dùng, mỗi cạnh là hai người quen biết nhau. Khi tìm được một clique, tức là tìm được một nhóm người mà ai cũng quen biết nhau.
Nếu muốn tìm nhóm lớn nhất mà mọi người đều quen biết nhau trong mạng xã hội này, ta cần thuật toán tìm clique lớn nhất.
Khái niệm clique cực đại đã được giới thiệu, clique lớn nhất là clique cực đại có số đỉnh nhiều nhất.
Giải thích
Ý tưởng là sử dụng đệ quy và quay lui (backtrack), dùng một danh sách lưu các đỉnh, mỗi lần thêm một đỉnh vào đều kiểm tra xem các đỉnh này còn tạo thành một clique không. Nếu thêm vào mà không còn là clique, thì quay lui về trạng thái trước, thử đỉnh khác.
Lý do dùng quay lui là vì ta không biết trước một đỉnh \(v\) cuối cùng có thuộc clique lớn nhất hay không. Nếu chọn \(v\) mà không tìm được clique lớn nhất, cần quay lui và thử nghiệm các clique không chứa \(v\).
Quy trình
Thuật toán Bron–Kerbosch tối ưu hóa ý tưởng này. Dạng cơ bản là đệ quy với ba tập hợp: \(R\), \(P\), \(X\). Các bước như sau:
- Khởi tạo \(R, X\) rỗng, \(P\) là tập tất cả các đỉnh của đồ thị.
- Mỗi lần lấy một đỉnh \(v\) từ \(P\), khi cả \(P\) và \(X\) đều rỗng thì có hai trường hợp:
- \(R\) là một clique cực đại, khi đó \(X\) rỗng
- Không phải clique cực đại, khi đó quay lui
- Với mỗi đỉnh \(v\) lấy từ \(P\):
- Thêm \(v\) vào \(R\), sau đó đệ quy với \(R, P, X\)
- Xóa \(v\) khỏi \(P\), thêm \(v\) vào \(X\)
- Nếu cả \(P\) và \(X\) đều rỗng, \(R\) là clique lớn nhất
Phương pháp này còn có thể tối ưu thêm. Để tăng tốc quay lui, có thể chọn đỉnh chốt (pivot vertex) để tìm kiếm. Một cách khác là sắp xếp các đỉnh ngay từ đầu, khi liệt kê thì theo thứ tự chỉ số để tránh lặp lại.
Cài đặt
Pseudocode
1 2 3 4 5 6 7 8 9 10 11 | |
C++ Implementation
Mã nguồn minh họa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
Bài tập ví dụ
POJ 2989: All Friends
Đề bài: Có \(n\) người, \(m\) cặp bạn bè, hỏi số lượng clique lớn nhất.
Ý tưởng: Bài mẫu, dùng thuật toán Bron–Kerbosch.
Pseudocode:
1 2 3 4 5 6 7 8 | |
Để tăng tốc và giảm lặp, có thể chọn pivot \(v\) để tối ưu.
Như đã nói, thuật toán trên có nhiều phép tính lặp lại các clique cực đại đã xét.
Xét ba tập \(R, P, X\):
Chọn một đỉnh \(u\) trong \(P\cup X\), muốn cùng \(R\) tạo thành clique cực đại thì chỉ cần xét các đỉnh trong \(P\cap N(u)\) (\(N(u)\) là tập đỉnh kề \(u\)).
Nếu sau khi chọn \(u\) mà các đỉnh kề \(u\) như \(v\) cũng có thể vào clique cực đại, thì chỉ cần chọn \(u\) là đủ. Như vậy giảm được lặp lại với \(v\). Sau đó chỉ cần xét các đỉnh không kề \(u\).
Cài đặt C++ tối ưu hóa:
Mã nguồn minh họa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Bài tập
Tài liệu tham khảo
- Clique problem - Wikipedia
- Cực đại đoàn, đoàn lớn nhất (Bron–Kerbosch)
- Bài toán clique lớn nhất — Bron–Kerbosch
- Bài toán clique lớn nhất
Last updated on this page:, Update history
Found an error? Want to help improve? Edit this page on GitHub!
Contributors to this page:Persdre
All content on this page is provided under the terms of the CC BY-SA 4.0 and SATA license, additional terms may apply