Розглянемо пов'язаний непрямий графік. Відповідний набір ребер на цьому графіку визначається як набір ребер таким чином, що жоден з двох ребер у множині не має спільної вершини. Наприклад, ліва цифра позначає відповідний набір зеленим кольором, тоді як права цифра позначає невідповідний набір червоним кольором.
Кажуть, що збігається набір maximally matching
, або maximal matching
якщо неможливо додати інший край графіка до відповідного набору. Отже, обидва приклади, наведені вище, - це не максимальні відповідні множини, але обидва наведені нижче набори синього кольору - це максимальні відповідники. Зауважте, що максимальні відповідники не обов'язково є унікальними. Крім того, не потрібно вимагати, щоб розмір кожного можливого максимального відповідності для графа дорівнював іншому збігу.
Мета цього завдання - написати програму / функцію, щоб знайти максимальну відповідність графіка.
Вхідні дані
Припустимо, що всі вершини вхідного графіка мають деяку послідовну цілу нумерацію, починаючи з будь-якого початкового цілого значення на ваш вибір. Ребро описується не упорядкованою парою цілих чисел, що позначають вершини, з якими з'єднується край. Наприклад, графік, показаний вище, може бути описаний із наступним не упорядкованим набором ребер (якщо припустити, що нумерація вершин починається з 0):
[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
Альтернативний спосіб опису графіка - це список суміжності. Ось приклад списку сумісності для наведеного вище графіка:
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
Ваша програма / функція повинна приймати як вхідний графік з будь-якого джерела (stdio, параметр функції тощо). Ви можете використовувати будь-які потрібні позначення до тих пір, поки додаткова нетривіальна інформація не буде передана вашій програмі. Наприклад, наявність додаткового параметра, що позначає кількість вхідних ребер, цілком прийнятна. Аналогічно, добре проходити в не упорядкованому безлічі ребер, списку суміжності або матриці суміжності.
Ви можете припустити:
- Графік пов'язаний (наприклад, можна досягти будь-якої вершини з будь-якою початковою вершиною).
- Є хоча б один край.
- Край ніколи не з'єднує вершину безпосередньо до себе (наприклад, край
(1,1)
не буде вказаний як вхідний). Зауважте, що цикли все ще можливі (напр .: наведені вище графіки). - Вам може знадобитися, щоб вершини введення починалися з будь-якого індексу (наприклад, перша вершина може бути 0, 1, -1 тощо).
- Нумерація вершин послідовно збільшується від обраного вихідного індексу (напр .:
1,2,3,4,...
або0,1,2,3,...
).
Вихідні дані
Ваша програма / функція повинна виводити список ребер, що позначають максимальний набір відповідності. Ребро визначається двома вершинами, які з'єднують цей край. Вих. вихід для лівого синього набору (використовуючи приклад впорядкування вершин вхідних даних):
[(1,4), (2,3), (5,6)]
Зауважте, що порядок вершин не важливий; Отже, наступний вихід описує той самий набір відповідності:
[(4,1), (2,3), (6,5)]
Виходом може бути stdout, файл, значення повернення функції тощо.
Приклади
Ось кілька прикладів входів (використовуючи формат списку суміжності). Ці приклади трапляються для початку підрахунку вершин на 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)