Trova una serie di bordi di corrispondenza massimi


13

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.

inserisci qui la descrizione dell'immagine

Si dice che sia maximally matchingun set di corrispondenza , o un maximal matchingse è 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.inserisci qui la descrizione dell'immagine

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:

  1. Il grafico è collegato (ad es. È possibile raggiungere qualsiasi vertice dato qualsiasi vertice iniziale).
  2. C'è almeno un vantaggio.
  3. 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).
  4. Potrebbe essere necessario che i vertici di input inizino da qualsiasi indice (ad es. Il primo vertice può essere 0, 1, -1, ecc.).
  5. La numerazione dei vertici aumenta sequenzialmente dall'indice iniziale scelto (es .: 1,2,3,4,..., o 0,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.

Risposte:


9

CJam (16 caratteri)

{M\{_2$&!*+}/2/}

Demo online

Questo è un approccio avido che accumula bordi che non hanno alcun vertice in comune con i bordi precedentemente accumulati.


Sono abbastanza sicuro che questo fallisca nel terzo esempio, dando [[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)
ETHproductions

@ETHproductions, stai confondendo il massimo con il massimo.
Peter Taylor,

3
Dangit, mi dispiace per quello ... Lascerò il mio commento per aiutare tutti gli altri che sono confusi, se non ti dispiace, dal momento che questo sembra essere un problema ricorrente :-P
ETHproductions

7

Pyth , 8 byte

ef{IsTty
       y  power set (gerenate all set of edges)
      t   remove the first one (the first one is
          empty and will cause problems)
 f        filter for sets T satisfying:
     T        T
    s         flatten
  {I          is invariant under deduplicate, i.e. contains no
              duplicating vertices, as the elements represent vertices
e         pick the last one (the power set is ordered from
          smallest to largest)

Provalo online!

Specifiche

  • Ingresso: [(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
  • Produzione: [(1, 4), (2, 3), (5, 6)]

6

Wolfram Language, 25 22 byte

Salvato 3 byte grazie a @MartinEnder

FindIndependentEdgeSet

Questo accetta input come Graphoggetto (definito come Graph[{1<->2,2<->3,1<-3>}]ecc.)


Non hai bisogno del @#&.
Martin Ender,

@MartinEnder Grazie.
Scott Milner,

Pfft. import solve_problem; run(). Ora qualcuno deve solo scrivere un plugin per Wolfram che contiene un URL di sfida codegolf e produce l'output desiderato. Chiamatela Golf.
Draco18s non si fida più di SE

5

Brachylog , 5 byte

 ⊇.c≠∧

?⊇.cL≠   implicit ? at the beginning;
         ∧ breaks implicit . at the end;
         temporary variable inserted.
?⊇.      input is a superset of output
  .cL    output concatenated is L
    L≠   L contains distinct elements

Provalo online!

Questo è garantito per essere massimo, poiché Brachylog cerca dal sottoinsieme più grande.


Penso che la tua spiegazione abbia un codice diverso da quello reale.
Erik the Outgolfer,

@EriktheOutgolfer Questo perché ho inserito caratteri impliciti nella mia spiegazione. Il codice originale è nella prima riga. Brachylog è piuttosto conciso in questo aspetto.
Leaky Nun,

Non intendo questo, ma il primo codice finisce ≠∧, mentre il secondo codice finisce L≠.
Erik the Outgolfer,

Senza , ci sarebbe un implicito .alla fine. Tutto qui significa che .non deve essere inserito alla fine.
Leaky Nun,

La Lè una variabile temporanea utilizzata nessuna parte, quindi la sua capacità di essere omesso.
Leaky Nun,

0

JavaScript (ES6), 67 byte

let f =
a=>a.map(b=>r.some(c=>c.some(d=>~b.indexOf(d)))||r.push(b),r=[])&&r

let g = a => console.log("[%s]", f(a).map(x => "[" + x + "]").join(", "))
g([[0,1]])
g([[0,1], [0,2], [1,3], [1,4], [2,3], [3,4], [3,5], [5,6]])
g([[0,1], [0,2], [1,2], [1,3], [1,4], [1,5]])
g([[0,1], [0,2], [1,2], [1,3], [2,4], [3,4], [3,5]])

Utilizza l'approccio avido per il massimo golfismo.


0

JavaScript (ES6), 68 66 byte

f=a=>a[0]?[a[0],...f(a.filter(b=>!a[0].some(c=>~b.indexOf(c))))]:a
f=([b,...a])=>b?[b,...f(a.filter(c=>!c.some(c=>~b.indexOf(c))))]:a

Ho pensato di provare l'approccio ricorsivo e rubando il trucco di intersezione impostato di @ ETHproduzione sono riuscito a ridurre la sua risposta!

Non sono stato il primo a fraintendere la domanda originale e stavo per presentare la seguente funzione ricorsiva che trova un insieme massimo di bordi corrispondenti, piuttosto che un insieme di bordi massimi corrispondenti. Differenza sottile, lo so!

f=a=>a.map(([b,c])=>[[b,c],...f(a.filter(([d,e])=>b-d&&b-e&&c-d&&c-e))]).sort((d,e)=>e.length-d.length)[0]||[]

Semplice approccio ricorsivo. Per ciascun elemento di input, elimina tutti gli spigoli in conflitto dall'insieme e trova l'insieme massimo di spigoli corrispondenti del sottoinsieme rimanente, quindi trova il risultato massimo su ciascun elemento di input. Un po 'inefficiente per set di grandi dimensioni (possibile accelerazione di 9 byte).


0

Gelatina , 12 11 byte

FQ⁼F
ŒPÇÐfṪ

Provalo online!

Input di esempio: [0,1],[0,2],[1,3],[1,4],[2,3],[3,4],[3,5],[5,6]

Uscita campione: [[1, 4], [2, 3], [5, 6]]

Come funziona

FQ⁼F    - Helper function, returns 1 if a set of edges is non-matching
F       - Flatten input
 Q      - Remove repeated elements
  ⁼     - Return boolean value. Is this equal to
   F    - The flattened input list

ŒPÇÐfṪ - Main link.
ŒP     - Power set of input list of edges
   Ðf  - Remove all elements which return 1 if
  Ç    - (Helper function) it is a non-matching set
     Ṫ - Get the last element in the resultant list (the longest). 
           Always maximal because it is the longest, so any
           edge added would not be in this list (not matching)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.