Não sei como desenhar paralelo entre o algoritmo Wagner-Fischer e o dtw algo. Nos dois casos, queremos encontrar a distância de cada combinação de índice (i, j).
Em Wagner-Fischer, iniciamos a distância pelo número de inserções que teríamos que fazer de uma sequência vazia para outra.
let wagnerFischer (s: string) (t: string) =
let m, n = s.Length, t.Length
let d = Array2D.create (m + 1) (n + 1) 0
for i = 0 to m do d.[i, 0] <- i
for j = 0 to n do d.[0, j] <- j
for j = 1 to n do
for i = 1 to m do
d.[i, j] <- List.min [
d.[i-1, j ] + 1;
d.[i , j-1] + 1;
d.[i-1, j-1] + if s.[i-1] = t.[j-1] then 0 else 1; ]
printfn "edit matrix \n %A" d
d.[m,n]
no DWT, iniciamos o limite em + infinito, porque não queremos "pular" nenhum número da sequência, sempre queremos combinar com outro item.
O que não vejo é o que muda entre o DWT e o WF algo que impede o uso para atualizar a distância de maneira homogênea. No DWT, adicionamos sistematicamente o custo, enquanto no WF algo, temos essa função não homegênea em diferentes casos
Eu entendo os dois algo, mas não faço a conexão entre essas diferenças na atualização da função de custo. Alguma idéia para entender a diferença intuitivamente?
let sequencebacktrack (s: 'a seq) (t:'a seq) (cost:'a->'a->double) (boundary:int->double) =
let m, n = s |> Seq.length, t |> Seq.length
let d = Array2D.create (m + 1) (n + 1) 0.
for i = 0 to m do d.[i, 0] <- boundary(i)
for j = 0 to n do d.[0, j] <- boundary(j)
t |> Seq.iteri( fun j tj ->
s |> Seq.iteri( fun i si ->
d.[1+i, 1+j] <- cost tj si + List.min [d.[1+i-1, 1+j ];
d.[1+i , 1+j-1];
d.[1+i-1, 1+j-1]; ] ))
printfn "edit matrix \n %A" d
d.[m,n]
//does not work
let wagnerFischer2 (s: string) (t: string) =
sequencebacktrack s t (fun a b -> if a = b then 0. else 1.) (id >> double)
let b = wagnerFischer2 "ll" "la"