ฉันเพิ่งใช้อัลกอริทึมระยะทาง 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สำหรับตัวอักษรปัจจุบันในbj1เป็นเพียงสำเนาของ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)
ตอนนี้ฉันไม่สามารถเป็นคนแรกที่คิดเรื่องนี้ได้ ดังนั้นทำไมฉันไม่วิ่งข้ามมัน? ฉันแค่ค้นหาไม่นานพอหรือไม่? หรือมีข้อบกพร่องเล็ก ๆ น้อย ๆ ที่ป้องกันไม่ให้มันทำงานได้จริง