พิจารณากราฟที่ไม่ได้ทำการเชื่อมต่อ ชุดการจับคู่ของขอบบนกราฟนี้ถูกกำหนดให้เป็นชุดของขอบเช่นว่าไม่มีสองขอบในส่วนแบ่งชุดจุดสุดยอดที่พบบ่อย ตัวอย่างเช่นรูปด้านซ้ายแสดงชุดการจับคู่เป็นสีเขียวในขณะที่รูปขวาแสดงถึงชุดการจับคู่ที่ไม่ใช่สีแดง
มีการกล่าวถึงชุดการจับคู่maximally matching
หรือmaximal matching
ถ้าไม่สามารถเพิ่มขอบของกราฟลงในชุดการจับคู่ได้ ดังนั้นทั้งสองตัวอย่างข้างต้นไม่ใช่ชุดการจับคู่สูงสุด แต่ชุดทั้งสองด้านล่างเป็นสีน้ำเงินเป็นการจับคู่สูงสุด โปรดทราบว่าการจับคู่สูงสุดไม่จำเป็นต้องซ้ำกัน นอกจากนี้ยังไม่มีข้อกำหนดว่าขนาดของการจับคู่สูงสุดที่เป็นไปได้สำหรับกราฟนั้นเท่ากับการจับคู่อื่น
เป้าหมายของความท้าทายนี้คือการเขียนโปรแกรม / ฟังก์ชั่นเพื่อค้นหาการจับคู่สูงสุดของกราฟ
อินพุต
สมมติว่าจุดยอดทั้งหมดของกราฟป้อนข้อมูลมีจำนวนเต็มต่อเนื่องเริ่มต้นที่ค่าจำนวนเต็มเริ่มต้นที่คุณเลือก ขอบถูกอธิบายโดยคู่เลขจำนวนเต็มที่ไม่เรียงลำดับซึ่งหมายถึงจุดยอดที่ขอบเชื่อมต่อ ตัวอย่างเช่นกราฟที่แสดงด้านบนสามารถอธิบายได้ด้วยชุดของขอบที่ไม่เรียงลำดับดังต่อไปนี้ (สมมติว่าจำนวนของจุดยอดเริ่มต้นที่ 0):
[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
อีกทางเลือกหนึ่งในการอธิบายกราฟคือผ่านรายการ adjacency นี่คือตัวอย่างของรายการ adjacency สำหรับกราฟด้านบน:
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
โปรแกรม / ฟังก์ชั่นของคุณจะต้องใช้กราฟอินพุตจากแหล่งใด ๆ (stdio, พารามิเตอร์ฟังก์ชั่น ฯลฯ ) คุณสามารถใช้สัญลักษณ์ใดก็ได้ที่ต้องการตราบใดที่ไม่มีการสื่อสารข้อมูลที่ไม่สำคัญเพิ่มเติมกับโปรแกรมของคุณ ตัวอย่างเช่นการมีพารามิเตอร์พิเศษเพื่อแสดงว่าจำนวนของขอบอินพุตนั้นเป็นที่ยอมรับได้อย่างสมบูรณ์ ในทำนองเดียวกันการส่งผ่านหลายเซ็ตของขอบรายการคำนำหรือเมทริกซ์ adjacency ก็ดี
คุณอาจจะ:
- กราฟเชื่อมต่ออยู่ (เช่นเป็นไปได้ที่จะไปถึงจุดสุดยอดใดก็ตามที่มีจุดเริ่มต้นใด ๆ )
- มีอย่างน้อยหนึ่งขอบ
- ขอบไม่เคยเชื่อมต่อจุดยอดโดยตรงกับตัวเอง (เช่นขอบ
(1,1)
จะไม่ได้รับเป็นอินพุต) โปรดทราบว่ารอบยังคงเป็นไปได้ (เช่น: กราฟด้านบน) - คุณอาจต้องการให้จุดยอดอินพุทเริ่มต้นที่ดัชนีใด ๆ (เช่นจุดยอดแรกอาจเป็น 0, 1, -1 และอื่น ๆ )
- การกำหนดหมายเลข Vertex จะเพิ่มขึ้นตามลำดับจากดัชนีเริ่มต้นที่คุณเลือก (เช่น:
1,2,3,4,...
หรือ0,1,2,3,...
)
เอาท์พุต
โปรแกรม / ฟังก์ชั่นของคุณควรแสดงรายการขอบที่แสดงถึงชุดการจับคู่สูงสุด ขอบถูกกำหนดโดยจุดยอดสองจุดที่ขอบนั้นเชื่อมต่อ อดีต เอาท์พุทสำหรับชุดสีฟ้าซ้าย (โดยใช้การสั่งซื้อจุดยอดอินพุทตัวอย่าง):
[(1,4), (2,3), (5,6)]
โปรดทราบว่าลำดับของจุดยอดไม่สำคัญ ดังนั้นเอาต์พุตต่อไปนี้จะอธิบายชุดการจับคู่ที่เหมือนกัน:
[(4,1), (2,3), (6,5)]
เอาต์พุตอาจเป็น stdout, ไฟล์, ค่าส่งคืนของฟังก์ชัน
ตัวอย่าง
นี่คือตัวอย่างเล็ก ๆ น้อย ๆ (ใช้รูปแบบรายการ adjacency) 0
ตัวอย่างเหล่านี้เกิดขึ้นที่จะเริ่มต้นนับจุดที่
โปรดทราบว่าไม่มีการแสดงตัวอย่างให้ แต่ฉันได้รวมรหัสตรวจสอบ 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)]
การตรวจสอบรหัส Python 3
ต่อไปนี้เป็นรหัสตรวจสอบความถูกต้องของ Python 3 ซึ่งใช้กราฟและชุดของขอบและพิมพ์ออกมาว่าชุดนั้นมีการจับคู่กันมากที่สุดหรือไม่ รหัสนี้ใช้ได้กับดัชนีเริ่มต้นที่จุดยอด
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
ตัวอย่างการใช้งาน:
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
เกณฑ์การให้คะแนน
นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุดชนะ ช่องโหว่มาตรฐานใช้ คุณสามารถใช้บิวด์อินที่ต้องการได้
[[0 1] [3 4]]
[[0 2] [1 4] [3 5]]
(ฉันเพิกเฉยต่อ(1, 1)
ขอบที่ดูเหมือนจะอยู่ในนั้นโดยไม่ได้ตั้งใจ)