Hãy xem xét một đồ thị vô hướng được kết nối. Một tập hợp các cạnh trên biểu đồ này được định nghĩa là một tập hợp các cạnh sao cho không có hai cạnh nào trong tập hợp có chung một đỉnh. Ví dụ, hình bên trái biểu thị một bộ so khớp màu xanh lá cây, trong khi hình bên phải biểu thị một bộ không khớp màu đỏ.
Một bộ phù hợp được gọi là maximally matching
hoặc maximal matching
nếu không thể thêm một cạnh khác của biểu đồ vào bộ phù hợp. Vì vậy, cả hai ví dụ trên không phải là bộ khớp tối đa, nhưng cả hai bộ dưới đây có màu xanh là khớp tối đa. Lưu ý rằng kết hợp tối đa không nhất thiết phải là duy nhất. Hơn nữa, không có yêu cầu rằng kích thước của mỗi kết hợp tối đa có thể có cho một biểu đồ bằng với một kết hợp khác.
Mục tiêu của thử thách này là viết một chương trình / hàm để tìm sự khớp tối đa của đồ thị.
Đầu vào
Giả sử tất cả các đỉnh của đồ thị đầu vào có một số đánh số nguyên liên tiếp bắt đầu từ bất kỳ giá trị số nguyên bắt đầu nào bạn chọn. Một cạnh được mô tả bởi một cặp số nguyên không có thứ tự biểu thị các đỉnh mà cạnh đó kết nối. Ví dụ, biểu đồ hiển thị ở trên có thể được mô tả với tập hợp các cạnh không có thứ tự sau đây (giả sử việc đánh số các đỉnh bắt đầu từ 0):
[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
Một cách khác để mô tả biểu đồ là thông qua danh sách kề. Dưới đây là danh sách kề kề ví dụ cho biểu đồ trên:
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
Chương trình / chức năng của bạn phải lấy làm biểu đồ đầu vào từ bất kỳ nguồn nào (stdio, tham số hàm, v.v.). Bạn có thể sử dụng bất kỳ ký hiệu nào mong muốn miễn là không có thông tin không tầm thường nào được truyền đạt tới chương trình của bạn. Ví dụ, có thêm một tham số biểu thị số cạnh đầu vào là hoàn toàn chấp nhận được. Tương tự như vậy, chuyển qua một đa cạnh không có thứ tự, danh sách kề hoặc ma trận kề là tốt.
Bạn có thể giả sử:
- Biểu đồ được kết nối (ví dụ: có thể đạt tới bất kỳ đỉnh nào cho bất kỳ đỉnh bắt đầu nào).
- Có ít nhất một cạnh.
- Một cạnh không bao giờ kết nối một đỉnh trực tiếp với chính nó (ví dụ: cạnh
(1,1)
sẽ không được cung cấp làm đầu vào). Lưu ý rằng các chu kỳ vẫn có thể (ví dụ: các biểu đồ trên). - Bạn có thể yêu cầu các đỉnh đầu vào bắt đầu tại bất kỳ chỉ mục nào (ví dụ: đỉnh đầu tiên có thể là 0, 1, -1, v.v.).
- Đánh số Vertex đang tăng liên tục từ chỉ số bắt đầu đã chọn của bạn (ví dụ:
1,2,3,4,...
hoặc0,1,2,3,...
).
Đầu ra
Chương trình / chức năng của bạn sẽ xuất ra một danh sách các cạnh biểu thị một bộ khớp tối đa. Một cạnh được xác định bởi hai đỉnh mà cạnh đó kết nối. Ví dụ. đầu ra cho tập hợp màu xanh bên trái (sử dụng thứ tự đỉnh đầu vào ví dụ):
[(1,4), (2,3), (5,6)]
Lưu ý rằng thứ tự của các đỉnh không quan trọng; Vì vậy, đầu ra sau đây mô tả cùng một bộ phù hợp:
[(4,1), (2,3), (6,5)]
Đầu ra có thể là thiết bị xuất chuẩn, một tệp, giá trị trả về của hàm, v.v.
Ví dụ
Dưới đây là một vài ví dụ đầu vào (sử dụng định dạng danh sách kề). Những ví dụ này xảy ra để bắt đầu đếm đỉnh tại 0
.
Lưu ý rằng không có kết quả đầu ra nào được đưa ra, thay vào đó tôi đã bao gồm mã xác thực Python 3.
[0:(1), 1:(0)]
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
[0:(1,2), 1:(0,2,3,4,5), 2:(0,1), 3:(1), 4:(1), 5:(1)]
[0:(1,2), 1:(0,2,3), 2:(0,1,4), 3:(1,4,5), 4:(2,3), 5:(3)]
Xác thực mã Python 3
Đây là mã xác thực Python 3, lấy một biểu đồ và tập hợp các cạnh và in ra xem tập hợp đó có khớp tối đa hay không. Mã này hoạt động với bất kỳ chỉ số bắt đầu đỉnh.
def is_maximal_matching(graph, edges):
'''
Determines if the given set of edges is a maximal matching of graph
@param graph a graph specified in adjacency list format
@param edges a list of edges specified as vertex pairs
@return True if edges describes a maximal matching, False otherwise.
Prints out some diagnostic text for why edges is not a maximal matching
'''
graph_vtxs = {k for k,v in graph.items()}
vtxs = {k for k,v in graph.items()}
# check that all vertices are valid and not used multiple times
for e in edges:
if(e[0] in graph_vtxs):
if(e[0] in vtxs):
vtxs.remove(e[0])
else:
print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[0]))
return False
else:
print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
return False
if(e[1] in graph_vtxs):
if(e[1] in vtxs):
vtxs.remove(e[1])
else:
print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[1]))
return False
else:
print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
return False
if(e[1] not in graph[e[0]]):
print('edge (%d,%d): edge not in graph'%(e[0],e[1]))
return False
# check that any edges can't be added
for v in vtxs:
ovtxs = graph[v]
for ov in ovtxs:
if(ov in vtxs):
print('could add edge (%d,%d) to maximal set'%(v,ov))
return False
return True
Ví dụ sử dụng:
graph = {0:[1,2], 1:[0,3,4], 2:[0,3], 3:[1,2,4,5], 4:[1,3], 5:[3,6], 6:[5]}
candidate = [(0,1),(2,3)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6),(0,1)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6)]
is_maximal_matching(graph, candidate) // True
Chấm điểm
Đây là mã golf; mã ngắn nhất thắng. Tiêu chuẩn áp dụng. Bạn có thể sử dụng bất kỳ tích hợp nào mong muốn.
[[0 1] [3 4]]
thay vì tập tối đa[[0 2] [1 4] [3 5]]
. (Tôi đang bỏ qua các(1, 1)
cạnh dường như ở trong đó do nhầm lẫn)