È bipartito?


13

Un grafico bipartito è un grafico i cui vertici possono essere divisi in due insiemi disgiunti, in modo tale che nessun bordo colleghi due vertici nello stesso insieme. Un grafico è bipartito se e solo se è bicolore.


Sfida

Il tuo compito è, data la matrice di adiacenza di un grafico semplice non indirizzato, determinare se si tratta di un grafico bipartito. Cioè, se un bordo collega i vertici i e j, entrambe le voci (i, j) e (j, i) della matrice sono 1.

Poiché il grafico non è diretto e semplice, la sua matrice di adiacenza è simmetrica e contiene solo 0 e 1.

specifiche

Dovresti prendere una matrice N-by-N come input (in qualsiasi forma, ad esempio un elenco di elenchi, un elenco di stringhe, un C-like int**e dimensioni, un array appiattito, un input non elaborato, ecc.).

La funzione / programma dovrebbe restituire / generare un valore di verità se il grafico è bipartito e falsare diversamente.

Casi test

['00101',
 '00010',
 '10001',
 '01000',
 '10100'] : False
['010100',
 '100011',
 '000100',
 '101000',
 '010000',
 '010000'] : True (divide into {0, 2, 4, 5} and {1, 3})
['00',
 '00'] : True

punteggio

I builtin che calcolano direttamente la risposta sono vietati.

Questo è , quindi vince il programma più breve (in byte) entro la fine di questo mese!


Correlati , e di fatto borderline dupe, perché essere bipartiti equivale a non avere cicli dispari, e la maggior parte delle risposte a quella domanda funzionano enumerando tutti i cicli ed esaminandone la lunghezza.
Peter Taylor,

@PeterTaylor Sì, ma ci sono modi più semplici per risolvere questo problema.
Colera il

@ColeraSu Invece di verità / falsità, possiamo tornare -1per falsità e qualsiasi numero intero non negativo per verità?
Mr. Xcoder,

@MishaLavrov 0-> Falsy, >0-> La verità è generalmente consentita dalle regole standard di verità / falsità. -1e ≥ 0non è così comune, ecco perché l'ho chiesto.
Mr. Xcoder,

@ Mr.Xcoder Va bene.
Colera,

Risposte:


4

Buccia , 17 byte

§V¤=ṁΣṠMSȯDfm¬ṀfΠ

Stampa un numero intero positivo se il grafico è bipartito, in 0caso contrario. Provalo online!

Spiegazione

Questo è un approccio a forza bruta: scorre tutti i sottoinsiemi S di vertici e verifica se tutti i bordi nel grafico si trovano tra S e il suo complemento.

§V¤=ṁΣṠMSȯDfm¬ṀfΠ  Implicit input: binary matrix M.
                Π  Cartesian product; result is X.
                   Elements of X are binary lists representing subsets of vertices.
                   If M contains an all-0 row, the corresponding vertex is never chosen,
                   but it is irrelevant anyway, since it has no neighbors.
                   All-1 rows do not occur, as the graph is simple.
      ṠM           For each list S in X:
              Ṁf   Filter each row of M by S, keeping the bits at the truthy indices of S,
        S  fm¬     then filter the result by the element-wise negation of S,
         ȯD        and concatenate the resulting matrix to itself.
                   Now we have, for each subset S, a matrix containing the edges
                   from S to its complement, twice.
§V                 1-based index of the first matrix
  ¤=               that equals M
    ṁΣ             by the sum of all rows, i.e. total number of 1s.
                   Implicitly print.

@ Mr.Xcoder Bene, supponiamo M = [[1,2,3],[4,5,6],[7,8,9]]e S = [1,0,1]( Mè sempre una matrice binaria nel programma, ma è più facile da spiegare in questo modo). Filtrando ogni riga di Mby S[[1,3],[4,6],[7,9]]: per ogni riga, rimuovo gli elementi in quegli indici in cui Sha uno 0. Quindi nego l' Selemento per quanto riguarda ottenere [0,1,0], e filtro Mper quello per ottenere [[4,6]]: la prima e l'ultima riga hanno 0 negli indici corrispondenti , quindi vengono rimossi.
Zgarb,

17

Wolfram Language (Mathematica) , 26 25 byte

Tr[#//.x_:>#.#.Clip@x]<1&

Provalo online!

Come funziona

Data una matrice di adiacenza A, troviamo il punto fisso di partire con B = A e poi sostituendo B da A 2 B, occasionalmente clipping valori superiori a 1 a 1. Il k esimo passo di questo processo è fino equivalente al Clipdi trovare poteri A 2k + 1 , in cui la voce (i, j) conta il numero di percorsi di lunghezza 2k + 1 dal vertice i a j; pertanto il punto fisso finisce con una voce diversa da zero (i, j) se possiamo passare da i a j in un numero dispari di passaggi.

In particolare, la diagonale del punto fisso ha voci diverse da zero solo quando un vertice può raggiungere se stesso in un numero dispari di passaggi: se c'è un ciclo dispari. Quindi la traccia del punto fisso è 0 se e solo se il grafico è bipartito.

Un'altra soluzione da 25 byte di questo modulo è Tr[#O@n//.x_:>#.#.x]===0&, nel caso in cui ciò offra a chiunque idee su come spingere il conteggio dei byte ancora più in basso.

Sforzi precedenti

Ho provato una serie di approcci a questa risposta prima di accontentarmi di questa.

26 byte: esponenziali della matrice

N@Tr[#.MatrixExp[#.#]]==0&

Si basa anche su poteri dispari della matrice di adiacenza. Dal momento che x * exp (x 2 ) è x + x 3 + x 5 /2! + x 7/4 ! + ..., quando x è una matrice A, questo ha un termine positivo per ogni potenza dispari di A, quindi avrà anche traccia zero se A ha un ciclo dispari. Questa soluzione è molto lenta per matrici di grandi dimensioni.

29 byte: grande potenza dispari

Tr[#.##&@@#~Table~Tr[2#!]]<1&

Per una matrice n per n A, trova A 2n + 1 e quindi esegue il controllo diagonale. Qui, #~Table~Tr[2#!]genera 2n copie della matrice di input n per n e #.##& @@ {a,b,c,d}decomprime a a.a.b.c.d, moltiplicando insieme 2n + 1 copie della matrice di conseguenza.

53 byte: matrice laplaciana

(e=Eigenvalues)[(d=DiagonalMatrix[Tr/@#])+#]==e[d-#]&

Utilizza un risultato oscuro nella teoria dei grafi spettrali ( Proposizione 1.3.10 in questo pdf ).


Penso che puoi eliminare un paio di byte dal tuo metodo più efficiente con Tr[#.Nest[#.#&,#,Tr[#!]]]<1&. (Questa è una risposta incredibile che continua a migliorare ogni volta che la guardo!)
Non un albero il

1
Questo ha meno byte rispetto al semi-integrato (necessita di due funzioni)BipartiteGraphQ@AdjacencyGraph@#&
Kelly Lowder,

2
@KellyLowder: per matrici di grandi dimensioni MatrixExprestituisce risultati in termini di Rootoggetti non valutati , che non vengono automaticamente semplificati quando aggiunti. Le N@forze Rootdevono essere calcolate numericamente in modo da poter valutare la veridicità.
Michael Seifert,

1
@Notatree Il tuo approccio in effetti si riduce di pochi byte, ma costano; per matrici 18x18, è 1000 volte più lenta e da lì peggiora. Penso che se apporto quel cambiamento, perdo il diritto di chiamare il metodo efficiente "efficiente".
Misha Lavrov,

1
@KellyLowder Potresti accorciarlo BipartiteGraphQ@*AdjacencyGraph, ma è ancora più lungo.
Martin Ender,

3

JavaScript, 78 byte

m=>!m.some((l,i)=>m.some((_,s)=>(l=m.map(t=>t.some((c,o)=>c&&l[o])))[i]&&s%2))

Input array di array di 0/1, output true / false.


2

Pyth , 25 byte

xmyss.D.DRx0dQx1d.nM*FQss

Provalo online!

Ciò restituisce -1falsità e qualsiasi numero intero non negativo per verità.

Come funziona

xmyss.D.DRx0dQx1d.nM * FQss ~ Programma completo, riceve una matrice di adiacenza da STDIN.

                    * FQ ~ Riduci (piega) per prodotto cartesiano.
                 .nM ~ Appiattisci ciascuno.
 m ~ Mappa con una variabile d.
         RQ ~ Per ogni elemento nell'input,
       .D ~ Elimina gli elementi negli indici ...
          x0d ~ Tutti gli indici di 0 in d.
     .D ~ E da questo elenco, elimina gli elementi negli indici ...
              x1d ~ Tutti gli indici di 1 in d.
    s ~ Appiattire.
   s ~ Sum. Avrei potuto usare s se [] non fosse apparso.
  y ~ Doppio.
x ~ Nella mappatura sopra, ottieni il primo indice di ...
                       ss ~ Il numero totale di 1 nella matrice di input.

Funziona con commit d315e19 , l'attuale versione di Pyth di TiO.

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.