Approccio euristico per un'implementazione DIFF flessibile


12

Ho creato un'implementazione DIFF per confrontare le revisioni dei documenti sul lavoro. Si basa su un algoritmo di differenza O (ND) e sulle sue variazioni .

Una cosa che è diventata importante è prendere l'elenco dei cambiamenti e interpretarli in un testo leggibile dall'uomo. Mentre l'attuale algoritmo è molto efficiente, è così tanto che è difficile espandersi.

Breve domanda

Stavo pensando di provare a usare A * e un'euristica che aggiunge penalità per i "turni". L'idea è quella di appianare inutili "aggiungi, elimina, aggiungi, elimina, aggiungi, elimina" in modo che sia più facile analizzare qualcosa che un essere umano può leggere. Fondamentalmente, trasforma il mio problema di percorso più breve in un problema di percorso più semplice .

E ovviamente non creare un output che sia sempre "Elimina tutto , Aggiungi tutto "

Sembra ragionevole?

Esiste una precedenza per l'utilizzo di un'euristica in un'implementazione DIFF? Cos'è l'euristico?

Il problema:

Se viene eliminata una frase lunga e un'altra frase lunga, ma condividono almeno una parola, pronuncia "con". Lasciare sola la parola comune (non aggiungendola o eliminandola) creerà il percorso più breve. Tuttavia, questo in realtà offusca il contesto del cambiamento in un essere umano che cerca di leggere una stampa dei cambiamenti.

Esempio con DIFF corrente:

  • Testo precedente: Pulito: lava e asciuga con aria di officina.
  • Nuovo testo: pulito: pulire con acetone e un panno privo di lanugine.
  • Modifica elenco note:
    • Cambia "Powerwash e asciuga" in "Pulisci con acetone"
    • Cambia "aria di negozio" in "acetone e un panno privo di lanugine"

Nota: viene utilizzato "Modifica" anziché "elimina" aria di negozio ", aggiungi" acetone ""

Come puoi vedere, la seconda nota perde TUTTO il contesto e senza guardare ancora i set di testo vecchi e nuovi completi non puoi capire cosa significhi.

Nota sulla punteggiatura:

Ho delimitato la punteggiatura come "parole" separate in modo da ottenere

  • Inserisci "("

invece di

  • Cambia "Ripara" in "(Ripara"

perché questo era odioso. Tuttavia, ciò significa che se c'è anche una virgola in entrambi i testi (al contrario della parola "con" nell'esempio precedente) accade la stessa cosa.

Possibile soluzione:

Penso che potrei invece utilizzare un algoritmo di ricerca di percorsi diversi che mi dia la flessibilità di aggiungere peso a diversi "percorsi" di cambiamento che potrebbero avere più senso per una persona. Forse, potrei persino fare in modo che viaggiare verso nodi contenenti punteggiatura abbia un peso ridotto (non sono sicuro di come ciò influirebbe su altre cose).

Quindi potrei ottenere l'esempio precedente per elencare quanto segue:

  • Modifica elenco note:
    • Cambia "Powerwash e asciuga con aria di officina" in "Pulisci con acetone e un panno privo di lanugine"

Vedere! Molto più chiaro!

So che subirò un colpo di performance, e potrei dover fare una revisione abbastanza importante del mio programma, ma è più importante avere il risultato finale che desidero.

Linea di fondo:

Ancora una volta, c'è qualche precedenza nell'uso di un'euristica in un'implementazione DIFF, e cos'è?

Altri pensieri? Un investimento ragionevole? Altre idee? Altri algoritmi?

Grazie in anticipo!

MODIFICARE:

Ho cercato di chiarire / consolidare la mia domanda e generalizzare la mia domanda per aggiungere un'euristica al mio algoritmo, piuttosto che usare A *. Fondamentalmente la stessa cosa in questo caso, ma penso ancora più preciso ora. Questo post è stato perspicace.

Risposte:


1

Potresti farlo in una versione simile a vimdiff:

Passaggio 1: identificazione delle frasi aggiunte, cancellate e modificate.

Passaggio 2: per ogni frase modificata, individuare la prima e l'ultima parola modificata e tagliare qualsiasi cosa non tra queste due parole.

Se hai bisogno di mantenere una struttura grammaticale più coerente, guarda gli interni di http://www.languagetool.org/ o di altri mostrati in questo post .

Informazioni sulla presentazione: puoi presentare entrambe le versioni di quella frase una sotto l'altra. Potresti voler mostrare il contesto per ogni modifica. Per ispirazione, guarda latexdiff che può stampare il testo aggiunto in blu in è il posto finale nella versione finale del testo e il testo cancellato nelle note (anche compatibile con \usepackage[para]{footmisc}).


Questo affronta solo i problemi di visualizzazione, non la questione principale della corrispondenza euristica.
Adam Zuckerman,

Hai letto il mio secondo paragrafo?
user2987828

L'ho fatto. Potresti approfondire ciò che stai cercando di spiegare? La mia prima (e seconda) lettura mi ha portato a pensare che stavi ancora descrivendo come visualizzare le informazioni, non elaborarle.
Adam Zuckerman,

Sono attualmente in grado di utilizzare HTML per formattare le aggiunte e le rimozioni, il visualizzatore di modifiche di stackexchange è ciò che mi ha ispirato. Questo non è il mio problema.
ptpaterson,

1
Devo capire meglio come potrei usare un diverso metodo di ricerca del grafico per trovare le differenze. Quello originale che ho effettivamente crea un grafico con pesi uguali di tutti i bordi ed esegue una prima ricerca di profondità per trovare tutti i movimenti di aggiunta / rimozione / mantenimento fino alla fine. Sto considerando di aggiungere pesi diversi ai bordi e di aggiungere un'euristica.
ptpaterson,
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.