เป็นไปได้ที่การปรับปรุง Damerau-Levenshtein


9

ฉันเพิ่งใช้อัลกอริทึมระยะทาง 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)

ตอนนี้ฉันไม่สามารถเป็นคนแรกที่คิดเรื่องนี้ได้ ดังนั้นทำไมฉันไม่วิ่งข้ามมัน? ฉันแค่ค้นหาไม่นานพอหรือไม่? หรือมีข้อบกพร่องเล็ก ๆ น้อย ๆ ที่ป้องกันไม่ให้มันทำงานได้จริง


ฉันตัดสินใจที่จะเขียนโพสต์บล็อกอธิบายรายละเอียดเกี่ยวกับ DL: scarcitycomputing.blogspot.com/2013/04/…
James Jensen

คำตอบ:


3

ฉันต้องค้นหาระยะทาง Damerau-Levenshtein บนวิกิพีเดียดังนั้นโปรดยกโทษให้ฉันหากนี่ผิด แต่ดูเหมือนว่าจะอนุญาตให้ส่งตัวอักษรที่อยู่ติดกันเท่านั้น ดังนั้นตัวอย่างของคุณ "abcdef" -> "abcfad" ที่มีการแปลงของ d และ f ไม่ทำงาน ดูเหมือนว่าคุณได้แก้ไขนิยามของอัลกอริทึมแล้วและจะไม่คำนวณระยะทางของ Damerau-Levenshtein อีกต่อไป


อืมฉันเห็นสิ่งที่คุณหมายถึง DL อนุญาตสำหรับการเคลื่อนย้ายก่อนเพิ่มหรือหลังการลบ หากทั้งคู่เกิดขึ้นมันไม่ใช่การขนย้ายที่อยู่ติดกันดังนั้นค่าใช้จ่ายที่เพิ่มขึ้นและค่าใช้จ่ายในการขนย้ายจะไม่ถูกเลือกเป็นค่าใหม่ ดูเหมือนว่าจะจัดการทั้งคู่เพราะหลีกเลี่ยงผลข้างเคียงของการลดต้นทุน
James Jensen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.