ฉันเพิ่งใช้อัลกอริทึมระยะทาง Damerau-Levenshtein จาก pseudocode บน Wikipedia ฉันไม่สามารถหาคำอธิบายใด ๆ ว่าวิธีการทำงานและชื่อตัวแปรใช้ pseudocode uninformative สมบูรณ์เช่นDA
, DB
, i1
และj1
ที่เหลือฉันเกาหัวของฉัน
นี่คือการใช้งานของฉันใน Python: https://gist.github.com/badocelot/5327337
การติดตั้ง Python ช่วยให้ฉันเดินผ่านโปรแกรมและค้นหาสิ่งที่เกิดขึ้นเปลี่ยนชื่อตัวแปรเป็นชื่อที่มีประโยชน์มากขึ้น ฉันคุ้นเคยกับแนวทางของ Wagner-Fischer มากพอที่จะคำนวณระยะทางของ Levenshtein ที่ฉันมีกรอบอ้างอิง
ด้วยความเสี่ยงที่จะมีความยาวมากเกินไปนี่เป็นวิธีที่ฉันเข้าใจ Damerau-Levenshtein:
ตัวแปรลึกลับ:
DA
(last_row
ในรหัสของฉัน) เป็นแผนที่ชนิดหนึ่งที่ถือแถวสุดท้ายที่แต่ละองค์ประกอบถูกเห็น ในรหัสของฉันมันเป็นพจนานุกรม Python ที่แท้จริงDB
(last_match_col
) เก็บคอลัมน์สุดท้ายที่ตัวอักษรb
ตรงกับตัวอักษรในa
แถวปัจจุบันi1
(last_matching_row
) คือหมายเลขแถวจากDA
สำหรับตัวอักษรปัจจุบันในb
j1
เป็นเพียงสำเนาของDB
/last_match_col
ก่อนที่จะอัปเดต ในรหัสของฉันฉันเพิ่งย้ายที่last_match_col
มีการปรับปรุงและกำจัดตัวแปรนี้
ค่าขนย้าย:
H[i1][j1] + (i-i1-1) + 1 + (j-j1-1)
กำลังคำนวณค่าใช้จ่ายในการแลกเปลี่ยนอักขระปัจจุบันb
ด้วยอักขระตัวสุดท้ายที่b
ทราบว่าอยู่ในa
(การจับคู่ครั้งสุดท้าย) การจัดการอักขระทั้งหมดในระหว่างการเพิ่มหรือการลบ
ส่วนประกอบของค่าใช้จ่าย:
H[i1][j1]
ย้อนกลับต้นทุนพื้นฐานไปยังจุดในการคำนวณก่อนการขนย้ายเนื่องจากการค้นหาการขนย้ายทำให้การทำงานก่อนหน้านี้ไม่ถูกต้อง(i-i1-1)
คือระยะห่างระหว่างแถวปัจจุบันและแถวสุดท้ายที่ตรงกับอักขระปัจจุบันซึ่งเป็นจำนวนการลบที่จะต้องใช้(j-j1-1)
คือระยะห่างระหว่างคอลัมน์ปัจจุบันและคอลัมน์สุดท้ายที่มีการจับคู่ซึ่งเป็นจำนวนการเพิ่ม+ 1
ค่าใช้จ่ายเพิ่มเติมเป็นเพียงค่าใช้จ่ายในการขนย้ายเท่านั้น
หากการวิเคราะห์นี้ไม่ถูกต้องฉันชอบที่จะรู้ว่าฉันผิดไปไหน ที่ผมกล่าวว่าฉันไม่สามารถหาใด ๆคำอธิบายรายละเอียดของวิธีการขั้นตอนวิธีการทำงานออนไลน์
รุ่นที่ปรับปรุงแล้ว?
มีคิดออกที่แม้ว่ามันหลงฉันว่าโดยการคำนวณค่าใช้จ่ายของทั้งเพิ่มและการลบระหว่างตัวอักษรขนย้ายดูเหมือนสมบูรณ์: หนึ่งบวกและลบหนึ่งจะเทียบเท่ากับการลงสนาม, ที่นี้ไม่ได้ตรวจสอบ
หากสิ่งที่ถูกต้องแก้ปัญหาควรเป็นเรื่องเล็กน้อย: ค่าใช้จ่ายของตัวอักษรระหว่างตัวอักษรที่ถูกย้ายควรจะสูงกว่าของการเพิ่มและการลบ: แปลงจำนวนมากเป็นการทดแทนที่เป็นไปได้และเพิ่มในส่วนเพิ่มเติมหรือการลบที่เหลือ
ดังนั้นราคาจะเป็น:
H[i1][j1] + max((i-i1-1), (j-j1-1)) + 1
นี่คือรหัสของฉันสำหรับรุ่นนี้: https://gist.github.com/badocelot/5327427
จากการทดสอบอย่างง่าย ๆ ดูเหมือนว่าถูกต้อง ตัวอย่างเช่น "abcdef" -> "abcfad" ให้ระยะทางแก้ไขเป็น 2 (เปลี่ยน "d" และ "f" เปลี่ยน "e" เป็น "a") ในขณะที่อัลกอริทึมดั้งเดิมให้ระยะห่าง 3 (ทั้งสามล่าสุด ตัวอักษรคือการแทนที่หรือ 1 การขนย้าย + 1 นอกจากนี้ + 1 การลบ 1)
ตอนนี้ฉันไม่สามารถเป็นคนแรกที่คิดเรื่องนี้ได้ ดังนั้นทำไมฉันไม่วิ่งข้ามมัน? ฉันแค่ค้นหาไม่นานพอหรือไม่? หรือมีข้อบกพร่องเล็ก ๆ น้อย ๆ ที่ป้องกันไม่ให้มันทำงานได้จริง