ขั้นตอนวิธีของเฮิร์ชเบิร์ก

ขั้นตอนวิธีของเฮิร์ชเบิร์ก เป็นขั้นตอนวิธีสำหรับการเปรียบเทียบของสายอักขระ มีชื่อมาจากผู้คิดค้น แดน เฮิร์ชเบิร์ก (Dan Hirschberg) ซึ่งขั้นตอนวิธีนี้เป็นขั้นตอนวิธีการเขียนโปรแกรมแบบพลวัต (Dynamic programming algorithm) ที่ถูกออกแบบมาเพื่อแก้ปัญหาลำดับย่อยร่วมยาวสุด (Longest common subsequence) โดยขั้นตอนวิธีนี้จะแก้ปัญหาการเปรียบเทียบสายอักขระโดยใช้ปริภูมิเชิงเส้น (Linear space) เพื่อหาระยะทางที่ถูกแก้ไขของราเวนสตีน (Levenshtein edit distance) ของสายอักขระ 2 สายที่เปรียบเทียบกันรวมทั้งหาการเรียงตัวของสายอักขระทั้งสองด้วย

สำหรับสายอักขระ 2 สายคือ "s1", "s2" ซึ่งเป็นสายอักขระย่อยของสายอักขระที่ประกอบด้วยตัวอักษรเท่านั้น โดยสายอักขระย่อยไม่จำเป็นต้องติดกัน เช่น ee ese และ es เป็นสายอักขระย่อยของ “predecessor” และ “descendant” (ee สามารถเป็นสายอักขระย่อยได้ “predecessor”)

การเชื่อมต่อระหว่างลำดับย่อยร่วมยาวสุด (Longest common subsequence (lcs)) และระยะทางที่ถูกแก้ไข (edit distance) สามารถแสดงในรูปสมการได้ดังนี้ d("s1","s2")=|"s1"|+|"s2"|-2lcs("s1","s2") ซึ่ง d("s1","s2") คือระยะทางที่ถูกแก้ไขของราเวนสตีน (Levenshtein edit distance) ที่จะหาต้นทุนที่น้อยที่สุดในการแปลงสายอักขระหนึ่งไปเป็นอีกสายอักขระหนึ่ง โดยมีทั้งการแทรก การแทนที่ การลบ หรือ การกระทำที่ไม่มีผล เป็นต้น

ขั้นตอนวิธีของเฮิร์ชเบิร์กสามารถอธิบายการทำงานได้หลายวิธี เช่น ใช้ขั้นตอนวิธีแวงเกอร์ – ฟิชเชอร์ (Wanger – Fisher algorithm) ในการมาใช้สร้างขั้นตอนวิธีของเฮิร์ชเบิร์กแต่ในที่นี้เราจะอธิบายขั้นตอนวิธีของเฮิร์ชเบิร์ก โดยใช้การแบ่งแยกและเอาชนะ (divide and conquer) ของขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์ (Needleman – Wunsch algorithm) โดยปกติแล้วขั้นตอนวิธีของเฮิร์ชเบิร์กนิยมใช้ในทางการคำนวณชีววิทยาเพื่อเปรียบเทียบของเหมือนของการเรียงตัวของ DNA และ โปรตีน

ขั้นตอนวิธีของเฮิร์ชเบิร์กเป็นขั้นตอนวิธีที่ใช้ในการหาการจัดเรียงของลำดับสายอักขระที่ดีที่สุด สมมติว่าให้ "x" และ "y" เป็นสายอักขระซึ่ง "n" เป็นความยาวของสายอักขระ "x" และ "m" เป็นความยาวของสายอักขระ "y" เราสามารถใช้ขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์ (Needleman – Wunsch algorithm) หาการจัดเรียงที่ดีที่สุดได้โดยใช้เวลา O("nm") และใช้เนื้อที่ O("nm") แต่หากเราใช้ขั้นตอนวิธีของเฮิร์ชเบิร์กซึ่งดีกว่าขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์เราจะหาการจัดเรียงที่ดีที่สุดภายในเวลา O("nm") และใช้เนื้อที่เพียง O(min{"n","m"})

ระยะทางที่ถูกแก้ไข (Edit distance Edit("x","y")) คือ ต้นทุนที่น้อยที่สุดของการเปลี่ยนแปลงรูปจากสายอักขระหนึ่งเปลี่ยนเป็นอีกสายอักขระหนึ่ง ซึ่งโดยทั่วไปการเปลี่ยนแปลงสายอักขระจะมีดังนี้ การแทรก การแทนที่ การลบ และ การสลับตำแหน่ง เป็นต้น

โดยนิยามสัญลักษณ์ต่างๆดังนี้ Ins("a") คือ ต้นทุนในการแทรกสัญลักษณ์ "a" ลงสายอักขระ Sub("a","b") ต้นทุนครั้งของการแทนที่สัญลักษณ์ "a" ด้วยสัญลักษณ์ "b" ในสายอักขระ และ Del("a") ต้นทุนของการลบสัญลักษณ์ "a" ในสายอักขระซึ่งโดยทั่วไปแล้วต้นทุนของการเปลี่ยนแปลงต่างๆจะเป็นดังนี้ Ins("a") และ Del("a") ต้นทุนเท่ากับ 1 สำหรับทุกๆสัญลักษณ์ "a" ใดๆ รวมทั้ง Sub("a","a") เท่ากับ 0 และ Sub("a","b") เท่ากับ 1 ในกรณีที่สัญลักษณ์ "a" ไม่เท่ากับ "b"

ขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์ (Needleman – Wunsch algorithm) จะคำนวณ Edit(Prefix["x","i"],Prefix["y","j"]) สำหรับทุกๆ "i" และ "j" ที่ซึ่ง Prefix["x","i"] หมายถึง คำนำหน้า(prefix) ของสายอักขระ "x" ที่ความยาว "i" ขั้นตอนวิธีนี้ต้องใช้เวลา O("nm") และใช้เนื้อที่ O("nm") โดย "n" เท่ากับความยาวของสายอักขระ "x" และ "m" เท่ากับความยาวของสายอักขระ "y"

เพื่อที่จะเข้าใจขั้นตอนวิธีของเฮิร์ชเบิร์กมันสำคัญมากที่จะต้องเข้าใจระยะทางที่ถูกแก้ไขสามารถคำนวณโดยใช้วิธีการปริภูมิเชิงเส้น (Linear space)

เราจะนิยามโปรแกรมย่อยไปข้างหน้า(Forward subprogram) ซึ่งคำนวณค่าของ Edit(Prefix["x","i"],Prefix["y","j"]) สำหรับทุกๆ "i" และ "j" คล้ายขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์ และคืนค่า array{Edit("x",Prefix["y","j"])} อีกส่วนหนึ่งที่เราจะนิยามคือโปรแกรมย่อยถอยหลัง(Backward subprogram) ซึ่งคล้ายกับโปรแกรมย่อยไปข้างหน้าแต่จะทำโปรแกรมแบบพลวัติ (dynamic program) จะสลับทิศทางกัน โดยจะเริ่มจากซ้ายไปขวาและล่างขึ้นบนแทน ซึ่งโปรแกรมนี้จะคืนค่า array {Edit("x",Suffix["y","j"])} โดย Suffix["y","j"] คือ คำเสริมท้าย(suffix) ของสายอักขระ "y" ของความยาว "j"

โปรแกรมย่อยไปข้างหน้า (Forward subprogram) และโปรแกรมย่อยถอยหลัง (Backward subprogram) จะคำนวณค่าในเมทริกซ์(matrix) โดยใช้ค่าที่ถูกคำนวณไว้ก่อนหน้านี้ แต่จะบันทึกช่องว่างโดยการลบค่าที่ไม่จำเป็นต้องใช้อีกต่อไประหว่างการทำงานของโปรแกรมย่อย (subprogram) แต่น่าเสียดายที่บางครั้งค่าที่ถูกลบไปอาจจะต้องนำมาใช้ในการคำนวณทีหลัง ขั้นตอนวิธีของเฮิร์ชเบิร์กจะใช้เวลาในการทำงานเป็น 2 เท่าของขั้นตอนวิธีของนีดเดิ้ลแมน – วันช์ (Needleman-Wunsch algorithm) แต่ก็ยังถือว่าอยู่ในเวลา O("nm")

คำอธิบายระดับสูงของโปรแกรมย่อยไปข้างหน้า
คำอธิบายระดับสูงของโปรแกรมย่อยถอยหลัง

คำอธิบายระดับสูงของขั้นตอนวิธีเฮิร์ชเบิร์ก :

ประโยชน์สำคัญอันหนึ่งของขั้นตอนวิธีนี้ คือ การหาการลำดับเรียงตัวของสาย DNA และสายโปรตีน ซึ่งมันเป็นวิธีที่มีประสิทธิภาพในการคำนวณลำดับย่อยร่วมยาวสุด (Longest cummon subsequence) ระหว่างกลุ่มข้อมูล 2 กลุ่มที่แตกต่างกันผู้ศึกษาขั้นตอนวิธีการของเฮิร์ชเบิร์ก เป็นขั้นตอนวิธีที่มีประโยชน์มากในการที่จะนำไปประยุกต์ใช้งาน เนื่องจากในโลกปัจจุบันเรามีข้อมูลจำนวนมากที่เป็นสายอักขระ ดังนั้นการที่เรามีขั้นตอนวิธีการที่ใช้เปรียบเทียบสายอักขระได้อย่างมีประสิทธิภาพ จะทำให้เราสามารถแก้ไขปัญหาหลายๆปัญหาที่เกี่ยวข้องกับสายอักขระได้อย่างมีประสิทธิภาพด้วยเช่นกัน

เอกสารการเรียนเรื่องการจัดเรียง