Modifica la distanza dell'elenco con elementi unici


12

La distanza di modifica della distanza Levenshtein tra le liste è un problema ben studiato. Ma non riesco a trovare molto sui possibili miglioramenti se è noto che nessun elemento si verifica più di una volta in ogni elenco .

Supponiamo anche che gli elementi siano comparabili / ordinabili (ma le liste da confrontare non sono ordinate per cominciare).

O(min(m,n)s)O(min(s,m,n)s)s

Più formalmente,

con quale efficienza possiamo calcolare la distanza di modifica tra due stringhe date con la promessa che non hanno lettere ripetute?s,tΣ

Σ è un alfabeto molto grande.


Qual è la tua domanda ora; come velocizzare la modifica in coppia, o come velocizzare il calcolo di tutte le distanze in coppia di un elenco di stringhe?
Raffaello

2
Ho il sospetto che la domanda sia: come calcolare la distanza di modifica tra , dove sono stringhe su un grande alfabeto e siamo certi che nessuna lettera appare due volte in o in (l'OP rappresenta ciascuna stringa come un elenco di lettere, ovvero un elenco di elementi). Ma questo ha bisogno di conferma. s , t Σ Σ s ts,ts,tΣΣst
DW

Sì, in questo caso l'alfabeto grande è costituito da indici del database e le "stringhe", s e t, sono elenchi contenenti questi indici.
user362178,

Per coloro che si chiedono delle complessità: e sono le lunghezze delle stringhe di input e è la distanza di modifica effettiva, quindi è inclusa nella complessità. Il costo di ogni modifica è considerato 1 ma è probabilmente irrilevante per il calcolo di questa distanza (il numero di modifiche ). n s smnss
Albert Hendriks,

Risposte:


3

TL; DR: un tipo leggermente più restrittivo di distanza di modifica, in cui possiamo solo inserire ed eliminare singoli caratteri, può essere calcolato in tempo linearitmico quando entrambe (o anche solo una) delle stringhe hanno caratteri univoci. Ciò fornisce utili limiti superiore e inferiore sulla distanza di modifica di Levenshtein.

Inserisci / elimina la distanza di modifica e le sottosequenze comuni più lunghe

La distanza di modifica di Levenshtein consente inserimenti, eliminazioni e sostituzioni a carattere singolo, assegnando a ciascuno un costo di 1. Se ci limitiamo a soli inserimenti ed eliminazioni, otteniamo una misura di distanza simile che ora fa sì che le sostituzioni abbiano un costo di 2 (poiché qualsiasi sostituzione può essere imitato usando un inserimento e una cancellazione). Non conosco un nome standard per questo tipo più restrittivo di distanza di modifica, quindi lo chiamerò "inserisci / elimina distanza di modifica". Corrisponde strettamente al problema della sottosequenza comune più lunga (LCS) , in cui ci vengono date due stringhe, rispettivamente di lunghezza e , e vogliamo conoscere la lunghezza della sottosequenza più lunga che appare in entrambi. Se due stringhe hanno LCSn L n + m - 2 LmnL, quindi hanno inserire / eliminare la modifica della distanzan+m2L : il modo più semplice per vederlo è allineare le stringhe in modo che i caratteri nell'LCS appaiano uno sopra l'altro, mentre i caratteri non nell'LCS appaiono di fronte a uno -spazio personaggio. Sarà quindi evidente che possiamo modificare la prima stringa nella seconda effettuando un inserimento ovunque sia presente un -nella riga superiore e una cancellazione ovunque ci sia un -nella riga inferiore. Per esempio:

-C-IRC-LE
T-RI-CKLE

Qui l'LCS di CIRCLEe TRICKLE, ICLEha lunghezza 4 e la distanza di modifica è effettivamente .6+724=5

Sottosequenze crescenti più lunghe

Il motivo di questa deviazione è che esiste un modo molto efficiente per calcolare l'LCS (e quindi l'inserimento / eliminazione della distanza di modifica) quando almeno una delle sequenze contiene solo caratteri distinti: in questo caso, il problema LCS può essere trasformato in il problema di trovare una sottosequenza crescente più lunga , che può essere risolta nel tempo . Supponiamo di avere due stringhe e e che la stringa abbia caratteri distinti. Possiamo rinominare il primo carattere in a 1, il secondo in 2 e così via, tenendo traccia del numero assegnato a ciascun personaggio in una tabella. Quindi inA B A A B O ( n + m registro m ) A B n mO(nlogn)ABAAB, rinominiamo i suoi caratteri usando questa tabella (ad esempio, ogni ricorrenza di qualunque sia stato il primo carattere Aè cambiata in 1, ecc.). Infine, cerchiamo una sottosequenza crescente più lunga in B. Ciò corrisponde a un LCS tra Ae B, e da lì possiamo immediatamente calcolare l'inserimento / eliminazione della distanza di modifica. Il tempo totale necessario è solo se e hanno rispettivamente lunghezze e .O(n+mlogm)ABnm

Limiti sulla distanza di modifica di Levenshtein

La distanza di inserimento / cancellazione fornisce chiaramente un limite superiore sulla distanza di Levenshtein (poiché qualsiasi sequenza valida di operazioni di modifica sotto la distanza di inserimento / cancellazione è anche una sequenza valida di operazioni di modifica di Levenshtein). Dividere la distanza di modifica in insert / delete per 2 dà anche un limite inferiore, poiché nel caso peggiore qualsiasi operazione di modifica in Levenshtein può essere cambiata in 2 operazioni di modifica in insert / delete.

generalizzazioni

Già nel 1977, Hunt e Szymanski hanno escogitato un algoritmo che può essere visto come una generalizzazione dell'algoritmo di sottosezione in aumento più lungo. È efficiente quando il numero di coppie di posizioni di caratteri corrispondenti tra le due stringhe è piccolo. Se ci sono coppie di questo tipo, il loro algoritmo richiede tempo . (Si noti che se tutti i caratteri in una stringa sono distinti.) Questo algoritmo era la base del programma originale , che trattava intere righe di testo come singoli caratteri. in seguito è passato all'uso dell'algoritmo -time di Myers , doveO ( ( r + n ) log n ) r n O ( n d ) drO((r+n)logn)rndiffdiffO(nd)d è la distanza di modifica di inserimento / eliminazione, poiché si comporta meglio quando le differenze complessive sono piccole ma alcuni "caratteri" (righe di testo) appaiono frequentemente (come una riga contenente solo una parentesi graffa di apertura nel codice del programma C).

Hunt, J .; Szymanski, T. (1977), "Un algoritmo veloce per il calcolo delle sottosequenze comuni più lunghe", Communications of the ACM, 20 (5): 350–353, doi: 10.1145 / 359581.359603

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.