рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╡рд░реНрддрдиреА рдЬрд╛рдБрдЪ, рд╢реЛрд░ рдЪреИрдирд▓ рдореЙрдбрд▓

рд╢реБрдн рджрд┐рдиред рджреВрд╕рд░реЗ рджрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рдСрдкреНрдЯрд┐рдХрд▓ рдЯреЗрдХреНрд╕реНрдЯ рд░рд┐рдХрдЧреНрдирд┐рд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдмрд╛рдж рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдерд╛ред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╛рда рдореЗрдВ рд╡рд░реНрддрдиреА рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЙрдбрд▓ рдЦрд░рд╛рдм рдирд╣реАрдВ рдерд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдмреЗрд╢рдХ рдпрд╣ рдХрд╛рд░реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдлрд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рдкреЛрд╕реНрдЯ Noisy Channel рдореЙрдбрд▓ рдХреЛ рд╕рдорд░реНрдкрд┐рдд рд╣реЛрдЧреА, рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╡рд░реНрддрдиреА рдЬрд╛рдБрдЪ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╣рдо рдЧрдгрд┐рддреАрдп рдореЙрдбрд▓ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░реЗрдВрдЧреЗ, c # рдореЗрдВ рдХреБрдЫ рдХреЛрдб рд▓рд┐рдЦреЗрдВрдЧреЗ , рдкреАрдЯрд░ рдиреЙрд░рд╡рд┐рдЧ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдореЙрдбрд▓ рдХреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░реЗрдВрдЧреЗ , рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рд╛ред



рдЧрдгрд┐рддреАрдп рдореЙрдбрд▓ - 1


рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрдпрд╛рди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдЗрд╕рд▓рд┐рдП рдЖрдк рдХреБрдЫ рд╢рдмреНрджреЛрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдо рдЕрдХреНрд╖рд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдЬреНрдЮрд╛рдд, рдПрди рдЕрдХреНрд╖рд░ рд╕реЗ рдорд┐рд▓рдХрд░ рд╢рдмреНрдж x рдХрд╛рдЧрдЬ рдкрд░ рдирд┐рдХрд▓рддрд╛ рд╣реИред рд╡реИрд╕реЗ, рдЖрдк рдмрд┐рд▓реНрдХреБрд▓ рд╢реЛрд░ рдЪреИрдирд▓ рд╣реИрдВ , рд╢реЛрд░ рдХреЗ рд╕рд╛рде рд╕реВрдЪрдирд╛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреИрдирд▓ рд╣реИ, рдЬрд┐рд╕рдиреЗ рд╕рд╣реА рд╢рдмреНрдж w (рд╕рд╣реА рд╢рдмреНрджреЛрдВ рдХреЗ рдмреНрд░рд╣реНрдорд╛рдВрдб рд╕реЗ) рдХреЛ рдЧрд▓рдд x (рд╕рднреА рд▓рд┐рдЦрд┐рдд рд╢рдмреНрджреЛрдВ рдХрд╛ рд╕реЗрдЯ) рдореЗрдВ рд╡рд┐рдХреГрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИред



рд╣рдо рдЙрд╕ рд╢рдмреНрдж рдХреЛ рдвреВрдВрдврдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЖрдк рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдорддрд▓рдм рд╣реИ рдЬрдм x рд╢рдмреНрдж рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рдЧрдгрд┐рддреАрдп рд░реВрдк рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд╡рд┐рдЪрд╛рд░ рдореЗрдВ рдореЙрдбрд▓ рднреЛрд▓реЗ рдмреЗрдпрд╕ рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░ рдХреЗ рдореЙрдбрд▓ рдХреЗ рд╕рдорд╛рди рд╣реИ , рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдФрд░ рднреА рд╕рд░рд▓ рд╣реИ:




рдЕрдЧрд▓рд╛, рдмрд╛рдпреЗрд╕рд┐рдпрди рдкреНрд░рдореЗрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдХрд╛рд░рдг рдФрд░ рдкреНрд░рднрд╛рд╡ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдХреБрд▓ рд╕рдВрднрд╛рд╡рдирд╛ x рдХреЛ рднрд╛рдЬрдХ рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм argmax, рдпрд╣ w рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:





рд╕рдВрднрд╛рд╡реНрдпрддрд╛ рдорд╛рди P рдХреА рдЧрдгрдирд╛ (x | w)


рдпрд╣рд╛рдБ рджрдореЗрд░рд╛рдК-рд▓реЗрд╡рдиреНрд╕рд╣рд╛рдЗрдЯ рджреВрд░реА рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрддреА рд╣реИ - рдпрд╣ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рджреЛ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдПрдХ рдЙрдкрд╛рдп рд╣реИ, рд╕реНрд░реЛрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд▓рдХреНрд╖реНрдп рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрдбрд╝реЛрд╕реА рд╡рд░реНрдгреЛрдВ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ, рд╣рдЯрд╛рдиреЗ, рдмрджрд▓рдиреЗ рдФрд░ рдкреБрдирд░реНрд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рд▓реЗрд╡реЗрдВрд╢реЗрдЯрд┐рди рджреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗ, рдЬреЛ рдЗрд╕ рдорд╛рдпрдиреЗ рдореЗрдВ рдЕрд▓рдЧ рд╣реИ рдХрд┐ рдпрд╣ рдкрдбрд╝реЛрд╕реА рдкрд╛рддреНрд░реЛрдВ рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЗрди рджреЛрдиреЛрдВ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рдпрд╣рд╛рдБ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рдирд╣реАрдВ рджреЛрд╣рд░рд╛рдпрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рддреБрд░рдВрдд рдХреЛрдб рджреЗ рджреВрдВрдЧрд╛:

рд▓реЗрд╡реЗрдВрд╕рд╣рд┐рди рджреВрд░реА
public static int LevenshteinDistance(string s, string t) { int[,] d = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i < s.Length + 1; i++) { d[i, 0] = i; } for (int j = 1; j < t.Length + 1; j++) { d[0, j] = j; } for (int i = 1; i <= s.Length; i++) { for (int j = 1; j <= t.Length; j++) { d[i, j] = (new int[] { d[i - 1, j] + 1, // del d[i, j - 1] + 1, // ins d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub }).Min(); } } return d[s.Length, t.Length]; } 



рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд╢рдмреНрдж рдХреЛ рджреВрд╕рд░реЗ рдореЗрдВ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХрд┐рддрдиреЗ рдбрд┐рд▓реАрдЯ, рдЗрдВрд╕рд░реНрдЯ рдФрд░ рд░рд┐рдкреНрд▓реЗрд╕ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрди рдСрдкрд░реЗрд╢рдВрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рднреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ, рдЖрдЗрдП рдЗрд╕реЗ рдмреИрдХрдЯреНрд░реЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╣рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐, рджреВрд░рд┐рдпреЛрдВ рдХреЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп d , рд╕рдВрдЪрд╛рд▓рди b рдХреЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рднреА рд▓рд┐рдЦрд╛ рдЬрд╛рдПред Ca рдФрд░ abc рд╢рдмреНрджреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

рдШрдмреА (0 - рд╕реНрд░реЛрдд рд╕реЗ рд╣рдЯрд╛рдПрдВ, рдмрд╛рдПрдВ; 1 - рд▓рдХреНрд╖реНрдп рд╕реЗ рд╕реНрд░реЛрдд рддрдХ рдбрд╛рд▓реЗрдВ; 2 - рд▓рдХреНрд╖реНрдп рд╕реЗ рдЪрд░рд┐рддреНрд░ рдХреЗ рд╕рд╛рде рд╕реНрд░реЛрдд рдореЗрдВ рдЪрд░рд┐рддреНрд░ рдХреЛ рдмрджрд▓реЗрдВ)


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ, рджреВрд░реА рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рд╕реЗрд▓ (i, j) рдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:

 d[i, j] = (new int[] { d[i - 1, j] + 1, // del - 0 d[i, j - 1] + 1, // ins - 1 d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub - 2 }).Min(); 


рдпрд╣ рдСрдкрд░реЗрд╢рди рдХреЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд╕реЗрд▓ (i, j) рдореЗрдВ рд╕реЗрд▓ рдХреЗ i (рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП 0, рд╡рд┐рд▓реЛрдкрди рдХреЗ рд▓рд┐рдП 0, рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП 2 рдФрд░ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд▓рд┐рдП) рдХреНрд░рдорд╢рдГ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рдХреЛрдб рдХрд╛ рдпрд╣ рдЯреБрдХрдбрд╝рд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 IList<int> vals = new List<int>() { d[i - 1, j] + 1, // del d[i, j - 1] + 1, // ins d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub }; d[i, j] = vals.Min(); int idx = vals.IndexOf(d[i, j]); b[i, j] = idx; 


рдПрдХ рдмрд╛рд░ рджреЛрдиреЛрдВ рдореИрдЪреНрдпреЛрд░ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдмреИрдХрдЯреНрд░реЗрд╕ (рдКрдкрд░ рдХреЗ рдЪрд┐рддреНрд░реЛрдВ рдореЗрдВ рддреАрд░) рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдСрдкрд░реЗрд╢рди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рдирд┐рдЪрд▓реЗ рджрд╛рдПрдВ рд╕реЗрд▓ рд╕реЗ рд░рд╛рд╕реНрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рджреВрд░реА рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдХрдо рд╕реЗ рдХрдо рд▓рд╛рдЧрдд рдХрд╛ рд░рд╛рд╕реНрддрд╛ рд╣реИред рд╣рдо рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
  1. рд╡рд░реНрддрдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рдЪрд▓реЗ рд╕рд╣реА рд╕реЗрд▓ рдХреЛ рдирд┐рд░реВрдкрд┐рдд рдХрд░реЗрдВ
  2. рдирд┐рдореНрди рдореЗрдВ рд╕реЗ рдПрдХ рдХрд░реЗрдВ
    • рдпрджрд┐ рд╡рд┐рд▓реЛрдкрди, рддреЛ рд╣рдЯрд╛рдП рдЧрдП рдЪрд░рд┐рддреНрд░ рдХреЛ рд▓рд┐рдЦреЗрдВ, рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдКрдкрд░ рд▓реЗ рдЬрд╛рдПрдВ (рд▓рд╛рд▓ рддреАрд░)
    • рдпрджрд┐ рд╕рдореНрдорд┐рд▓рд┐рдд рд╣реИ, рддреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдЪрд░рд┐рддреНрд░ рд▓рд┐рдЦреЗрдВ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдмрд╛рдИрдВ рдУрд░ рд▓реЗ рдЬрд╛рдПрдВ (рд▓рд╛рд▓ рддреАрд░)
    • рдпрджрд┐ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди, рд╕рд╛рде рд╣реА рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рд╡рд░реНрдг рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рд╡рд░реНрдг рд▓рд┐рдЦреЗрдВ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдмрд╛рдИрдВ рдФрд░ рдКрдкрд░ (рд▓рд╛рд▓ рд░рдВрдЧ) рдкрд░ рд▓реЗ рдЬрд╛рдПрдВ
    • рдпрджрд┐ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди, рд▓реЗрдХрд┐рди рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рд╡рд░реНрдг рдмрд░рд╛рдмрд░ рд╣реИрдВ, рддреЛ рдХреЗрд╡рд▓ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдмрд╛рдИрдВ рдФрд░ рдКрдкрд░ (рдиреАрд▓реЗ рддреАрд░) рдкрд░ рд▓реЗ рдЬрд╛рдПрдВ

  3. рдпрджрд┐ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЧрдП рдСрдкрд░реЗрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реЗрд╡реЗрдВрд╕рд╛рдЗрдЯрд┐рди рджреВрд░реА рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдПрдХ рдмрд┐рдВрджреБ рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВ;


рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдорд┐рд▓рддреЗ рд╣реИрдВ рдЬреЛ рд▓реЗрд╡реЗрдиреНрд╕рд╣рд╛рдЗрдЯрд┐рди рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдмреИрдХрдЯреНрд░реЗрд╕:

рд▓реЗрд╡реЗрдиреНрд╕реНрдЯрд╛рдЗрди рджреВрд░реА рдХреЗ рд╕рд╛рде рдкреАрдЫреЗ
 //del - 0, ins - 1, sub - 2 public static Tuple<int, IList<Tuple<int, string>>> LevenshteinDistanceWithBacktrace(string s, string t) { int[,] d = new int[s.Length + 1, t.Length + 1]; int[,] b = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i < s.Length + 1; i++) { d[i, 0] = i; } for (int j = 1; j < t.Length + 1; j++) { d[0, j] = j; b[0, j] = 1; } for (int i = 1; i <= s.Length; i++) { for (int j = 1; j <= t.Length; j++) { IList<int> vals = new List<int>() { d[i - 1, j] + 1, // del d[i, j - 1] + 1, // ins d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub }; d[i, j] = vals.Min(); int idx = vals.IndexOf(d[i, j]); b[i, j] = idx; } } List<Tuple<int, string>> bt = new List<Tuple<int, string>>(); int x = s.Length; int y = t.Length; while (bt.Count != d[s.Length, t.Length]) { switch (b[x, y]) { case 0: x--; bt.Add(new Tuple<int, string>(0, s[x].ToString())); break; case 1: y--; bt.Add(new Tuple<int, string>(1, t[y].ToString())); break; case 2: x--; y--; if (s[x] != t[y]) { bt.Add(new Tuple<int, string>(2, s[x] + "" + t[y])); } break; } } bt.Reverse(); return new Tuple<int, IList<Tuple<int, string>>>(d[s.Length, t.Length], bt); } 



рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЯрдкрд▓ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд╣рд▓реЗ рддрддреНрд╡ рдореЗрдВ рд▓реЗрд╡реЗрдВрд╕рд╣рд╛рдЗрдЯ рдХреА рджреВрд░реА рджрд░реНрдЬ рдХреА рдЧрдИ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ, рдЬреЛрдбрд╝реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА <рдСрдкрд░реЗрд╢рди рдЖрдИрдбреА, рд▓рд╛рдЗрди>, рд▓рд╛рдЗрди рдореЗрдВ рдбрд┐рд▓реАрдЯ рдФрд░ рдЗрдВрд╕рд░реНрдЯ рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдг рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рджреЛ рдЕрдХреНрд╖рд░ (рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╡рд░реНрдг рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рдЕрд░реНрде рд╣реИ) )ред

рдкреБрдирд╢реНрдЪ: рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдзреНрдпрд╛рди рджреЗрдЧрд╛ рдХрд┐ рдирд┐рдЪрд▓реЗ рджрд╛рдПрдВ рд╕реЗрд▓ рд╕реЗ рдЕрдХреНрд╕рд░ рдХрдо рд╕реЗ рдХрдо рд▓рд╛рдЧрдд рдХреЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реЛрддреЗ рд╣реИрдВ, рдпрд╣ рдЪрдпрди рдмрдврд╝рд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рднреА рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗред

рдЧрдгрд┐рддреАрдп рдореЙрдбрд▓ - реи


рдЕрдм рд╣рдо рд╕реВрддреНрд░реЛрдВ рдХреЗ рднрд╛рд╖рд╛ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдкрд░рд┐рдгрд╛рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред рджреЛ рд╢рдмреНрджреЛрдВ x рдФрд░ w рдХреЗ рд▓рд┐рдП, рд╣рдо рдкрд╣рд▓реЗ рд╢рдмреНрдж рдХреЛ рджреВрд╕рд░реЗ рддрдХ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЪрд╛рд▓рди рдХреА рд╕реВрдЪреА рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдХреНрд╖рд░ f рд╕реЗ рд╕рдВрдЪрд╛рд▓рди рдХреА рд╕реВрдЪреА рдХреЛ рдирд┐рд░реВрдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╢рдмреНрдж x рд▓рд┐рдЦрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ w рдХреЗ рд░реВрдк рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдХреЗ рдЙрддреНрдкрд╛рджрди рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧреА, рдмрд╢рд░реНрддреЗ рдХрд┐ рд╣рдордиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ x рд▓рд┐рдЦрд╛, рдФрд░ рдЧрд░реНрднрд┐рдд w :



рдпрд╣рд╛рдБ рд╕рд░рд▓реАрдХрд░рдг рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рднреЛрд▓реЗ рдмрд╛рд╕реЗрд╕рд┐рдпрди рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░ рдореЗрдВ рдереЗ, рдЙрдирдХреЗ рд╕рдорд╛рди рд╣реИрдВ:




рдЕрдм, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рд╡реЗ рдЪрд╛рд╣реЗ рдЬреЛ рднреА рд╢рдмреНрдж рдмрдирд╛рдП рдЧрдП рд╣реЛрдВ), рдпрд╣ рдЙрдирдХреА рдЧрд▓рдд рд╡рд░реНрддрдиреА рдХреЗ рд╕рд╛рде рд╢рдмреНрджреЛрдВ рдХреЗ рдХрд┐рд╕реА рднреА рдЖрдзрд╛рд░ рдХреЛ рд╣рд╛рде рдореЗрдВ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рд╣рдо рдЕрдВрддрд┐рдо рд╕реВрддреНрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд╢реВрдиреНрдп рдХреЗ рдХрд░реАрдм рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд▓реЙрдЧ рд╕реНрдкреЗрд╕ рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ:



рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╣реИ? рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЧреНрд░рдВрдереЛрдВ рдХрд╛ рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рд╕реЗрдЯ рд╣реИ, рддреЛ рд╣рдо рднрд╛рд╖рд╛ рдореЗрдВ рд╢рдмреНрджреЛрдВ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ; рдЙрдирдХреЗ рдЧрд▓рдд рд╡рд░реНрддрдиреА рдХреЗ рд╕рд╛рде рд╣рд╛рде рдкрд░ рд╢рдмреНрджреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рд╣реЛрдиреЗ рд╕реЗ, рд╣рдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпреЗ рджреЛ рдЖрдзрд╛рд░ рдореЙрдбрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВред

рддреНрд░реБрдЯрд┐ рд╕рдВрднрд╛рд╡рдирд╛ рдзреБрдВрдзрд▓рд╛


рдЬрдм рд╣рдо argmax рдХреЗ рд╕рд╛рде рд╕рднреА рд╢рдмреНрдж рдЖрдзрд╛рд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрднреА рднреА рд╢реВрдиреНрдп рд╕рдВрднрд╛рд╡рдирд╛ рд╡рд╛рд▓реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдЖрдПрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЬрдм рд╢рдмреНрдж x рдХреЛ рд╢рдмреНрдж w рдкрд░ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдкрд╛рджрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдСрдкрд░реЗрд╢рди рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рддреНрд░реБрдЯрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рдереЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, additive рдЪреМрд░рд╕рд╛рдИ рдпрд╛ рд▓рд╛рдкреНрд▓рд╛рд╕ рдзрдмреНрдмрд╛ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдЧрд╛ (рдпрд╣ рднреЛрд▓реЗ рдмреЗрдпрд╕ рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░ рдореЗрдВ рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)ред рдореБрдЭреЗ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реВрддреНрд░ рдпрд╛рдж рджрд┐рд▓рд╛рдПрдВред рдпрджрд┐ рдХреБрдЫ рд╕реБрдзрд╛рд░ рдСрдкрд░реЗрд╢рди рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ n рдмрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдореАрдЯрд░ рд╣реИ , рдФрд░ рд╕реБрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рдЯреА рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрд┐рддрдиреА рдмрд╛рд░ " рдмреА рдмрд╛рдп" рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд┐рддрдиреЗ рдЕрджреНрд╡рд┐рддреАрдп рдЬреЛрдбрд╝реЗ "" * "), рддрдм рдзреБрдВрдзрд▓реА рд╕рдВрднрд╛рд╡рдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ, рдЬрд╣рд╛рдВ k рдзрдмреНрдмрд╛ рдЧреБрдгрд╛рдВрдХ рд╣реИ:



рдлрд┐рд░ рдПрдХ рдСрдкрд░реЗрд╢рди рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдЬреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЖрдзрд╛рд░ рдореЗрдВ рдХрднреА рдирд╣реАрдВ рдЖрдИ рд╣реИ ( n = 0 ) рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧреА:



рдЧрддрд┐


рдПрдХ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рдкреНрд░рд╢реНрди рдЙрдарддрд╛ рд╣реИ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЧрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рд╢рдмреНрджреЛрдВ рдХреЗ рдкреВрд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рдирд╛ рд╣реИ, рдФрд░ рдпрд╣ рдПрдХ рд╕реЗрдВрдЪреБрд░реА рдХреЗ рд╕рд╛рде Levenshtein рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕реИрдХрдбрд╝реЛрдВ рдХреЙрд▓ рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╕рднреА рд╢рдмреНрджреЛрдВ рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдпреЛрдЧ, рдпрджрд┐ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛ рддреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкреВрд░реНрд╡-рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рд▓рдШреБрдЧрдгрдХ рд╣реИрдВ)ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рддрдереНрдп рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИ:



рдареАрдХ рд╣реИ, рддреЛ рдЖрдк рд╡рд┐рднрд┐рдиреНрди рдПрд▓реНрдЧреЛрд░рд┐рдердо рдЪрд╛рд▓ рдХреЗ рд╕рд╛рде рдЖ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдкрд╖реНрдЯ рдФрд░ рдмрд╣реБрдд рд╕рд░рд▓ рддрд░реАрдХреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЕрдЧрд░ рдореБрдЭреЗ рдХреЗрд╡рд▓ рдореМрдЬреВрджрд╛ рд╢рдмреНрдж рд╕реЗ рдЯреА рдПрдбрд┐рдЯрд┐рдВрдЧ рдСрдкрд░реЗрд╢рдВрд╕ рд╕реЗ рдЕрдзрд┐рдХ рд╢рдмреНрджреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЙрдирдХреА рд▓рдВрдмрд╛рдИ рд╡рд░реНрддрдорд╛рди рд╕реЗ рдЕрд▓рдЧ рд╣реЛрддреА рд╣реИ, рдЯреА рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВред рдХреНрд▓рд╛рд╕ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рдПрдХ рд╣реИрд╢ рдЯреЗрдмрд▓ рдмрдирд╛рддрд╛ рд╣реВрдБ рдЬрд┐рд╕рдореЗрдВ рдХреБрдВрдЬрд┐рдпрд╛рдБ рд╢рдмреНрджреЛрдВ рдХреА рд▓рдВрдмрд╛рдИ рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рдорд╛рди рдЗрд╕ рд▓рдВрдмрд╛рдИ рдХреЗ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕реЗрдЯ рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд╕реЗ рд╕рд░реНрдЪ рд╕реНрдкреЗрд╕ рдХреЛ рдХрд╛рдлреА рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдХреЛрдб


рдореБрдЭреЗ рдЬреЛ рд╢реЛрд░рдЧреБрд▓ рдорд┐рд▓рд╛ рд╣реИ, рдореИрдВ рдЙрд╕реЗ NoisyChannel рдХреНрд▓рд╛рд╕ рдХрд╛ рдХреЛрдб рджреВрдВрдЧрд╛:

NoisyChannel
 public class NoisyChannel { #region vars private string[] _words = null; private double[] _wLogPriors = null; private IDictionary<int, IList<int>> _wordLengthDictionary = null; //length of word - word indices private IDictionary<int, IDictionary<string, double>> _mistakeLogProbs = null; private double _lf = 1d; private IDictionary<int, int> _mNorms = null; #endregion #region ctor public NoisyChannel(string[] words, long[] wordFrequency, IDictionary<int, IDictionary<string, int>> mistakeFrequency, int mistakeProbSmoothing = 1) { _words = words; _wLogPriors = new double[_words.Length]; _wordLengthDictionary = new SortedDictionary<int, IList<int>>(); double wNorm = wordFrequency.Sum(); for (int i = 0; i < _words.Length; i++) { _wLogPriors[i] = Math.Log((wordFrequency[i] + 0d)/wNorm); int wl = _words[i].Length; if (!_wordLengthDictionary.ContainsKey(wl)) { _wordLengthDictionary.Add(wl, new List<int>()); } _wordLengthDictionary[wl].Add(i); } _lf = mistakeProbSmoothing; _mistakeLogProbs = new Dictionary<int, IDictionary<string, double>>(); _mNorms = new Dictionary<int, int>(); foreach (int mType in mistakeFrequency.Keys) { int mNorm = mistakeFrequency[mType].Sum(m => m.Value); _mNorms.Add(mType, mNorm); int mUnique = mistakeFrequency[mType].Count; _mistakeLogProbs.Add(mType, new Dictionary<string, double>()); foreach (string m in mistakeFrequency[mType].Keys) { _mistakeLogProbs[mType].Add(m, Math.Log((mistakeFrequency[mType][m] + _lf)/ (mNorm + _lf*mUnique)) ); } } } #endregion #region correction public IDictionary<string, double> GetCandidates(string s, int maxEditDistance = 2) { IDictionary<string, double> candidates = new Dictionary<string, double>(); IList<int> dists = new List<int>(); for (int i = s.Length - maxEditDistance; i <= s.Length + maxEditDistance; i++) { if (i >= 0) { dists.Add(i); } } foreach (int dist in dists) { foreach (int tIdx in _wordLengthDictionary[dist]) { string t = _words[tIdx]; Tuple<int, IList<Tuple<int, string>>> d = LevenshteinDistanceWithBacktrace(s, t); if (d.Item1 > maxEditDistance) { continue; } double p = _wLogPriors[tIdx]; foreach (Tuple<int, string> m in d.Item2) { if (!_mistakeLogProbs[m.Item1].ContainsKey(m.Item2)) { p += _lf/(_mNorms[m.Item1] + _lf*_mistakeLogProbs[m.Item1].Count); } else { p += _mistakeLogProbs[m.Item1][m.Item2]; } } candidates.Add(_words[tIdx], p); } } candidates = candidates.OrderByDescending(c => c.Value).ToDictionary(c => c.Key, c => c.Value); return candidates; } #endregion #region static helper //del - 0, ins - 1, sub - 2 public static Tuple<int, IList<Tuple<int, string>>> LevenshteinDistanceWithBacktrace(string s, string t) { int[,] d = new int[s.Length + 1, t.Length + 1]; int[,] b = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i < s.Length + 1; i++) { d[i, 0] = i; } for (int j = 1; j < t.Length + 1; j++) { d[0, j] = j; b[0, j] = 1; } for (int i = 1; i <= s.Length; i++) { for (int j = 1; j <= t.Length; j++) { IList<int> vals = new List<int>() { d[i - 1, j] + 1, // del d[i, j - 1] + 1, // ins d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub }; d[i, j] = vals.Min(); int idx = vals.IndexOf(d[i, j]); b[i, j] = idx; } } List<Tuple<int, string>> bt = new List<Tuple<int, string>>(); int x = s.Length; int y = t.Length; while (bt.Count != d[s.Length, t.Length]) { switch (b[x, y]) { case 0: x--; bt.Add(new Tuple<int, string>(0, s[x].ToString())); break; case 1: y--; bt.Add(new Tuple<int, string>(1, t[y].ToString())); break; case 2: x--; y--; if (s[x] != t[y]) { bt.Add(new Tuple<int, string>(2, s[x] + "" + t[y])); } break; } } bt.Reverse(); return new Tuple<int, IList<Tuple<int, string>>>(d[s.Length, t.Length], bt); } public static int LevenshteinDistance(string s, string t) { int[,] d = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i < s.Length + 1; i++) { d[i, 0] = i; } for (int j = 1; j < t.Length + 1; j++) { d[0, j] = j; } for (int i = 1; i <= s.Length; i++) { for (int j = 1; j <= t.Length; j++) { d[i, j] = (new int[] { d[i - 1, j] + 1, // del d[i, j - 1] + 1, // ins d[i - 1, j - 1] + (s[i - 1] == t[j - 1] ? 0 : 1) // sub }).Min(); } } return d[s.Length, t.Length]; } #endregion } 



рд╡рд░реНрдЧ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд╛рдирдХреЛрдВ рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рдкрд░реАрдХреНрд╖рдг


рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреАрдЯрд░ рдиреЙрд░рд╡рд┐рдЧ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ , рдЬрд┐рд╕рдореЗрдВ рдЖрд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде 333333 рд╢рдмреНрдж рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЧрд▓рдд рд╡рд░реНрддрдиреА рд╡рд╛рд▓реЗ 7481 рд╢рдмреНрдж рднреА рд╣реИрдВред рдирд┐рдореНрди рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ NoisyChannel рд╡рд░реНрдЧ рдХреЛ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рдЖрдзрд╛рд░ рдкрдврд╝рдирд╛
 string[] words = null; long[] wordFrequency = null; #region read priors if (!File.Exists("../../../Data/words.bin") || !File.Exists("../../../Data/wordFrequency.bin")) { IDictionary<string, long> wf = new Dictionary<string, long>(); Console.Write("Reading data:"); using (StreamReader sr = new StreamReader("../../../Data/count_1w.txt")) { string line = sr.ReadLine(); while (line != null) { string[] parts = line.Split('\t'); wf.Add(parts[0].Trim(), Convert.ToInt64(parts[1])); line = sr.ReadLine(); Console.Write("."); } sr.Close(); } Console.WriteLine("Done!"); words = wf.Keys.ToArray(); wordFrequency = wf.Values.ToArray(); using (FileStream fs = File.Create("../../../Data/words.bin")) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, words); fs.Flush(); fs.Close(); } using (FileStream fs = File.Create("../../../Data/wordFrequency.bin")) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, wordFrequency); fs.Flush(); fs.Close(); } } else { using (FileStream fs = File.OpenRead("../../../Data/words.bin")) { BinaryFormatter bf = new BinaryFormatter(); words = bf.Deserialize(fs) as string[]; fs.Close(); } using (FileStream fs = File.OpenRead("../../../Data/wordFrequency.bin")) { BinaryFormatter bf = new BinaryFormatter(); wordFrequency = bf.Deserialize(fs) as long[]; fs.Close(); } } #endregion //del - 0, ins - 1, sub - 2 IDictionary<int, IDictionary<string, int>> mistakeFrequency = new Dictionary<int, IDictionary<string, int>>(); #region read mistakes IDictionary<string, IList<string>> misspelledWords = new SortedDictionary<string, IList<string>>(); using (StreamReader sr = new StreamReader("../../../Data/spell-errors.txt")) { string line = sr.ReadLine(); while (line != null) { string[] parts = line.Split(':'); string wt = parts[0].Trim(); misspelledWords.Add(wt, parts[1].Split(',').Select(w => w.Trim()).ToList()); line = sr.ReadLine(); } sr.Close(); } mistakeFrequency.Add(0, new Dictionary<string, int>()); mistakeFrequency.Add(1, new Dictionary<string, int>()); mistakeFrequency.Add(2, new Dictionary<string, int>()); foreach (string s in misspelledWords.Keys) { foreach (string t in misspelledWords[s]) { var d = NoisyChannel.LevenshteinDistanceWithBacktrace(s, t); foreach (Tuple<int, string> ml in d.Item2) { if (!mistakeFrequency[ml.Item1].ContainsKey(ml.Item2)) { mistakeFrequency[ml.Item1].Add(ml.Item2, 0); } mistakeFrequency[ml.Item1][ml.Item2]++; } } } #endregion 



рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдореЙрдбрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддрд╛ рд╣реИ рдФрд░ " рд╣реЗ ;; o " рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╢рдмреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИред (рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣реИрд▓реЛ , рд╕реЗрдореАрдХреЛрд▓рди рдПрд▓ рдХреЗ рджрд╛рдИрдВ рдУрд░ рд╣реИ рдФрд░ рдкреНрд░рд┐рдВрдЯрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп рдЧрд▓рддреА рдХрд░рдирд╛ рдЖрд╕рд╛рди рдерд╛ред рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╣реИрд▓реЛ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдиреА рд╕реВрдЪреА рдореЗрдВ рд╢рдмреНрдж рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ ;) рдУ ) 2 рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рдХреА рджреВрд░реА рдкрд░, рд╕рдордп рджрд░реНрдЬ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рд╕рд╛рде:

 NoisyChannel nc = new NoisyChannel(words, wordFrequency, mistakeFrequency, 1); Stopwatch timer = new Stopwatch(); timer.Start(); IDictionary<string, double> c = nc.GetCandidates("he;;o", 2); timer.Stop(); TimeSpan ts = timer.Elapsed; Console.WriteLine(ts.ToString()); 


рдореЗрд░реЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреА рдЧрдгрдирд╛ рдФрд╕рддрди 1 рд╕реЗрдХрдВрдб рд╕реЗ рдереЛрдбрд╝рд╛ рдХрдо рд╕рдордп рд▓реЗрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреБрдХреВрд▓рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЙрдкрд░реЛрдХреНрдд рд╡рд┐рдзрд┐рдпреЛрдВ рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдЙрдирдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреА рд╣реИред рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдФрд░ рдЙрдирдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:



рд╕рдВрджрд░реНрдн




рдХреЛрдб рд╡рд╛рд▓реЗ рдЖрд░реНрдХрд╛рдЗрд╡ рдХреЛ рдпрд╣рд╛рдВ рд╕реЗ рдорд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

Source: https://habr.com/ru/post/In202908/


All Articles