Considera un grafico non indirizzato connesso. Un insieme corrispondente di spigoli su questo grafico è definito come un insieme di spigoli in modo tale che due spigoli dell'insieme non condividano un vertice comune. Ad esempio, la figura a sinistra indica un set corrispondente in verde, mentre la figura a destra indica un set non corrispondente in rosso.
Si dice che sia maximally matching
un set di corrispondenza , o un maximal matching
se è impossibile aggiungere un altro bordo del grafico al set di corrispondenza. Quindi entrambi gli esempi sopra non sono insiemi di corrispondenza massimi, ma entrambi gli insiemi di seguito in blu sono abbinamenti massimi. Nota che gli abbinamenti massimi non sono necessariamente unici. Inoltre, non è necessario che la dimensione di ogni possibile corrispondenza massima per un grafico sia uguale a un'altra corrispondenza.
L'obiettivo di questa sfida è quello di scrivere un programma / funzione per trovare una corrispondenza massima di un grafico.
Ingresso
Supponiamo che tutti i vertici del grafico di input abbiano una numerazione di numeri interi consecutivi a partire da qualsiasi valore intero iniziale di vostra scelta. Un bordo è descritto da una coppia di numeri interi non ordinata che indica i vertici a cui si collega il bordo. Ad esempio, il grafico mostrato sopra potrebbe essere descritto con il seguente set di bordi non ordinati (supponendo che la numerazione dei vertici inizi da 0):
[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
Un modo alternativo per descrivere un grafico è tramite un elenco di adiacenza. Ecco un esempio di elenco di adiacenza per il grafico sopra:
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
Il tuo programma / funzione deve prendere come input un grafico da qualsiasi sorgente (stdio, parametro di funzione, ecc.). È possibile utilizzare qualsiasi notazione desiderata purché non vengano comunicate al programma informazioni aggiuntive non banali. Ad esempio, avere un parametro aggiuntivo che indica il numero di fronti di input è perfettamente accettabile. Allo stesso modo, il passaggio in un multiset di bordi, elenco di adiacenza o matrice di adiacenza non ordinati va bene.
Puoi presumere:
- Il grafico è collegato (ad es. È possibile raggiungere qualsiasi vertice dato qualsiasi vertice iniziale).
- C'è almeno un vantaggio.
- Un bordo non collega mai un vertice direttamente a se stesso (es. Il bordo
(1,1)
non verrà fornito come input). Si noti che i cicli sono ancora possibili (es .: i grafici sopra). - Potrebbe essere necessario che i vertici di input inizino da qualsiasi indice (ad es. Il primo vertice può essere 0, 1, -1, ecc.).
- La numerazione dei vertici aumenta sequenzialmente dall'indice iniziale scelto (es .:
1,2,3,4,...
, o0,1,2,3,...
).
Produzione
Il tuo programma / funzione dovrebbe generare un elenco di spigoli che indicano un set di corrispondenza massimo. Un bordo è definito dai due vertici che quel bordo collega. Ex. output per il set blu di sinistra (usando l'esempio di ordinamento dei vertici di input):
[(1,4), (2,3), (5,6)]
Si noti che l'ordine dei vertici non è importante; Quindi il seguente output descrive lo stesso set di corrispondenza:
[(4,1), (2,3), (6,5)]
L'output può essere su stdout, un file, valore di ritorno della funzione, ecc.
Esempi
Ecco alcuni input di esempio (utilizzando il formato dell'elenco di adiacenza). Questi esempi iniziano a contare i vertici su 0
.
Si noti che non vengono forniti esempi di output, ma ho incluso un codice di convalida 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)]
Convalida codice Python 3
Ecco un codice di convalida di Python 3 che contiene un grafico e un set di spigoli e stampa se tale set corrisponde al massimo o meno. Questo codice funziona con qualsiasi indice di inizio vertici.
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
Esempio di utilizzo:
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
punteggio
Questo è il codice golf; vince il codice più breve. Si applicano scappatoie standard. È possibile utilizzare qualsiasi componente incorporato desiderato.
[[0 1] [3 4]]
invece del set massimo[[0 2] [1 4] [3 5]]
. (Sto ignorando il(1, 1)
limite che sembra essere lì per errore)