Trovare anagrammi interessanti


31

Supponiamo che e siano due stringhe della stessa lunghezza. Un anagramma di due stringhe è una mappatura biiettiva p: [1 \ ldots n] \ a [1 \ ldots n] tale che a_i = b_ {p (i)} per ogni i .b 1 b 2b na1a2anb1b2bna i = b p ( i )p:[1n][1n]ai=bp(i)i

Potrebbe esserci più di un anagramma per la stessa coppia di stringhe. Ad esempio, se a= `abcab` b=cabab abbiamo p1[1,2,3,4,5][4,5,1,2,3] e p2[1,2,3,4,5][2,5,1,4,3] , tra gli altri.

Diremo che il peso w(p) di un anagramma p è il numero di tagli che uno deve fare nella prima stringa per ottenere pezzi che possono essere riorganizzati per ottenere la seconda stringa. Formalmente, questo è il numero di valori di i[1n1] per cui p(i)+1p(i+1) . Cioè, è il numero di punti in cui p non non aumentano con esattamente 1.For esempio, w(p1)=1 e w(p2)=4 , perché p1 tagli 12345volta, nei pezzi 123e 45, e p2 tagli 12345quattro volte, in cinque pezzi.

Supponiamo che esista un anagramma per due stringhe a e b . Quindi almeno un anagramma deve avere meno peso. Diciamo che questo è il più leggero . (Potrebbero esserci più anagrammature più leggere; non mi interessa perché sono interessato solo ai pesi.)

Domanda

Voglio un algoritmo che, dati due stringhe per le quali esiste un anagramma, produce in modo efficiente il peso esatto dell'anagramma più leggero delle due stringhe. Va bene se l'algoritmo produce anche un anagramma più leggero, ma non è necessario.

È abbastanza semplice generare tutti gli anagramm e pesarli, ma potrebbero essercene molti, quindi preferirei un metodo che trova direttamente gli anagramm.


Motivazione

La ragione per cui questo problema è interessante è la seguente. È molto facile fare in modo che il computer cerchi nel dizionario e trovi anagrammi, coppie di parole che contengono esattamente le stesse lettere. Ma molti degli anagrammi prodotti non sono interessanti. Ad esempio, gli esempi più lunghi che si possono trovare nel secondo dizionario internazionale di Webster sono:


duodenocholecystostomy colecistoduodenostomia

Il problema dovrebbe essere chiaro: sono poco interessante perché ammettono un'anagrammi molto leggero che semplicemente scambi il cholecysto, duedenoe stomyle sezioni, per un peso di 2. D'altra parte, questo esempio molto più breve è molto più sorprendente e interessante:

costa
sezionale

Qui l'anagramma più leggero ha un peso di 8.

Ho un programma che utilizza questo metodo per individuare anagrammi interessanti, vale a dire quelli per i quali tutti gli anagrammi sono di peso elevato. Ma lo fa generando e pesando tutti i possibili anagrammi, che è lento.


Solo per curiosità, come trovi coppie di anagrammi? Effettui una ricerca di forza bruta all'interno di tutte le parole della stessa lunghezza? O(n2)
Pedro

4
No certo che no. Converti ogni parola in una forma canonica che ha le stesse lettere in ordine alfabetico. (Ad esempio, la forma canonica di cholecystoduodenostomyè ccddeehlmnooooossttuyy.) Due parole sono anagrammi se e solo se hanno la stessa forma canonica. Memorizzi le parole in una tabella hash, codificata dalle loro forme canoniche e ogni volta che trovi una collisione, hai un anagramma.
Mark Dominus,

Ora ho una grande quantità di informazioni più o meno correlate al riguardo sul mio blog: (α) (β) (γ) (δ)
Mark Dominus,

Risposte:


21

Questo problema è noto come "problema minimo della partizione di stringa comune". (Più precisamente, la risposta nel problema della partizione di stringa comune minima è uguale alla risposta nel problema più 1). Sfortunatamente, è NP-difficile, anche con la restrizione che ogni lettera appare al massimo due volte in ciascuna delle stringhe di input, come dimostrato da Goldstein, Kilman e Zheng [GKZ05]. Ciò significa che non esiste alcun algoritmo del tempo polinomiale a meno che P = NP. (Naturalmente, se ogni lettera si presenta al massimo una volta, il problema è banale perché c'è solo un anagramma.)

Sul lato positivo, gli stessi autori [GKZ05] danno un algoritmo di approssimazione del tempo polinomiale 1.1037 con la stessa restrizione. (Un " algoritmo di approssimazione 1.1037 " indica un algoritmo che potrebbe non produrre la risposta corretta A ma è garantito che fornisca un valore B tale che AB ≤ 1,1037 A. ) Forniscono anche un algoritmo di approssimazione lineare a tempo 4 sotto il limitazione più debole che ogni lettera si presenta al massimo tre volte in ciascuna delle stringhe di input.

[GKZ05] Avraham Goldstein, Petr Kolman e Jie Zheng. Problema minimo comune di partizione di stringa: durezza e approssimazioni. Electronic Journal of Combinatorics , 12, articolo R50, 2005. http://www.combinatorics.org/ojs/index.php/eljc/article/view/v12i1r50



9

Questo è un seguito alla risposta di Tsuyoshi Ito sopra , che riassume la parte più rilevante del documento GKZ05 che ha citato.

Il documento dimostra una riduzione al problema del MIS (Maximal Independent Set ). Costruisci un grafico cui vertici sono coppie tale che e . Collega i vertici e (dove ) con un bordo ogni volta che è impossibile che un anagramma possa mappare tutti e e e . Questo è facile da rilevare; tale mappatura è impossibile esattamente se si verifica una delle seguenti condizioni:( iG(i,j)ai=bjai+1=bj+1(i,j)(k,)ikiji+1j+1kk+1+1

  1. i=k ej
  2. i+1=k ej+1
  3. i+1<k e è disgiunto da{j,j+1}{,+1}

Supponiamo che il grafico risultante abbia un set indipendente massimo di dimensioni . Poi il peso minimo Anagrammare è esattamente , dove è la lunghezza delle corde e . (Il contrario vale anche: un anagramma di peso ridotto si traduce direttamente in un grande MIS per Per i dettagli, vedere pagg. 4–5 del documento.)Gsns1nabG

Ad esempio, considera le due stringhe yttriouse touristy. Il grafico corrispondente ha due vertici, uno per la oucoppia condivisa e uno per la ricoppia condivisa . Non vi è alcun margine tra i vertici, perché è possibile avere un anagramma che mappa sia oua ouche ria ri; oppure si può verificare che le tre condizioni soprattutto falliscano. Quindi il grafico ha ovviamente un MIS di dimensione e il peso minimo dell'anagramma è effettivamente 8-2-1 = 5, corrispondente all'anagramma ↔ . 's=2y|t|t|ri|ou|st|ou|ri|s|t|y

D'altra parte, considera deratere treader. Questa volta il grafico ha tre vertici:

  1. DErater + treaDEr
  2. dERater + treadER
  3. deratER + treadER

2 e 3 sono incompatibili e 1 e 3 sono incompatibili, ma 1 e 2 sono compatibili. Quindi il MIS unico ha dimensioni e contiene i vertici 1 e 2. Il corrispondente anagramma del peso 7-2-1 = 4 è ↔ .s=2der|a|t|e|rt|r|e|a|der


2
Grazie per il post di follow-up, ma questa non è una prova della completezza NP del tuo problema. Per dimostrare la completezza NP del tuo problema, devi ridurre alcuni problemi noti NP-completi al tuo problema, e questo è il Teorema 2.2 di [GKZ05]. Ciò che hai presentato qui (Lemma 1.1 di [GKZ05]) è una riduzione nella direzione opposta.
Tsuyoshi Ito,

Questa è una bella riformulazione. Un cambiamento banale che è una semplificazione minore concettualmente (almeno per me): invece di disegnare bordi tra coppie incompatibili e chiedere il massimo set indipendente, possiamo disegnare bordi tra coppie compatibili e chiedere la massima cricca. (Trovo più facile pensare a "qual è il numero massimo di coppie che possiamo tenere insieme".)
ShreevatsaR

2

Non copre l'esatto algoritmo che avevi in ​​mente (cosa che fa la risposta di Tsuyoshi Ito ), ma cercando di capire il problema di fondo di trovare anagrammi "interessanti" ...

Il mio primo pensiero è stato quello di utilizzare alcune variazioni su edit-distance, in cui i cambiamenti atomici sono ponderati in base alla loro "interesse" piuttosto che alle solite ponderazioni "difficoltà" o "confusione". Certo, sembra improbabile che tu possa codificare in modo efficiente le trasformazioni davvero interessanti in questo modo, dal momento che sono probabilmente non locali e quindi si imbattono nei problemi NP completi di MIS, ecc.

Quindi, secondo pensiero sarebbe quello di costruire un allineamento lettera-a-lettera tra le parole (allineamenti di traduzione automatica), e quindi di valutare gli allineamenti stessi per "interesse" (ad esempio, contando gli allineamenti che portano le lettere adiacenti a non- lettere adiacenti o quanti allineamenti attraversa ciascun allineamento, ecc., quindi combinarli tutti tramite un modello lineare o simile).

La terza idea è quella di abbandonare completamente la struttura dell'anagramma stesso e guardare invece la semantica delle parole. Spesso ciò che rende un anagramma "interessante" è l'incongruenza tra i significati delle parole coinvolte. Quindi prova qualcosa come calcolare la loro distanza in WordNet o simili.


0

Il problema può essere espresso in termini di gruppi di permutazione .

Ora un gruppo di permutazione contiene tutte le "mosse anagramma", sia primitive (scambiando due lettere) che composte di sequenze di mosse primitive. Sembra che tu sia interessato solo a un sottoinsieme delle possibili permutazioni. Proverò a definirli.

Innanzitutto, ricorda la notazione per permutazioni, vale a dire la cosiddetta notazione del ciclo :

  • () significa nessuna permutazione.
  • (1) significa che 1 viene scambiato con 1, che è anche nessuna permutazione.
  • (12) significa che 1 e 2 vengono scambiati.
  • (123) significa 1 sostituisce 2 che sostituisce 3 che sostituisce 1 (una rotazione).
  • e così uno

Questi semplici "cicli" sono composti per descrivere permutazioni più complesse.

Sembra che le mosse che ti interessano siano (per una parola di lunghezza ):n

  • scambi di coppie di singoli caratteri: questi sono gli scambi come(12)
  • swap di coppie di 2 caratteri consecutivi: sono queste permutazioni della forma , dove e ea > 0 b < a + 1 b + 1 n(a b)(a+1 b+1)a>0b<a+1b+1n
  • ...
  • scambi di coppie di n caratteri consecutivi: si tratta di permutazioni della forma dove , e .a > 0 a + i - 1 b b + i - 1 n(a b)(a+1 b+1)(a+i1 b+i1)a>0a+i1bb+i1n

Queste mosse costituiscono la base per il tuo algoritmo. Ciò che ti interessa è trovare la sequenza più piccola di queste mosse per passare da una parola alla successiva.

Non conosco alcun algoritmo per calcolare questo, a parte la ricerca della forza bruta, ma almeno ora c'è una descrizione più chiara (spero) di quali siano le mosse primitive. (E forse alcuni teorici di gruppo tra di noi possono puntare a un algoritmo appropriato.)


1
Grazie. Forse sono pessimista, ma mi sembra che questo approccio sarà difficile. Non penso che un approccio teorico di gruppo produrrà frutti se non scopriamo prima quale gruppo di permutazione è interessante e che varia a seconda delle stringhe di input. Penso che una rappresentazione efficiente di gruppi finiti sia un problema estremamente profondo e ricco. Ma mi piacerebbe sbagliarmi.
Mark Dominus,

1
"Quello che ti interessa è trovare la più piccola sequenza di queste mosse per passare da una parola all'altra." Non penso che sia corretto. Ad esempio, se n = 4, lo swap (1 2) ha un peso 2, ma lo swap (2 3) ha un peso 3. Il tuo modo di contare non distingue questi due.
Tsuyoshi Ito,

Ho risposto a tarda notte. Non ho capito bene la misura del peso. In effetti, non lo capisco adesso. Pensavo che volessi consentire mosse di blocchi di lettere, motivo per cui mi sono preso la briga di definire questi primitivi. La mia risposta potrebbe fornire ispirazione, quindi la lascerò, anche se è sbagliata.
Dave Clarke,

0

Per colecistoduodenostomia / duodenocholecystostome, noto che se assegnassi un numero a ciascun personaggio che descrive quanto è stato spostato come delta, avresti qualcosa come 7 7, quindi 8 -7, quindi 6 0. Questo non è giusto perché alcuni caratteri potrebbero essere stati ripetuti (il secondo c si è spostato solo in avanti 2, non indietro 7) ecc., Ma è ancora molto "codificabile in lunghezza" perché si vedono gli stessi delta in una riga.

Confronta con la costa / sezionale, dove vedi qualcosa come (+2) (+ 5) (+ 5) (- 3) (- 1) (+ 3) .... molto meno "codifica della lunghezza della corsa".

Forse la casualità dei delta potrebbe darti un "punteggio" su quanto sia interessante l'anagramma?

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.