การบันทึกโดยไม่มีอาร์เรย์


14

ในบทนำสู่อัลกอริทึมของ Cormen และคณะส่วนที่ 15.3 องค์ประกอบของการเขียนโปรแกรมแบบไดนามิกจะอธิบายการบันทึกความจำดังนี้

อัลกอริทึมแบบเรียกซ้ำที่บันทึกช่วยเก็บรักษารายการในตารางสำหรับการแก้ปัญหาสำหรับแต่ละปัญหาย่อย แต่ละรายการในตารางเริ่มต้นมีค่าพิเศษเพื่อระบุว่ารายการยังไม่ได้กรอกเมื่อพบปัญหาย่อยเป็นครั้งแรกในขณะที่อัลกอริทึมแบบเรียกซ้ำเกิดขึ้นการแก้ปัญหาของมันจะถูกคำนวณและจัดเก็บในตาราง ในแต่ละครั้งที่เราพบปัญหาย่อยนี้เราเพียงค้นหาค่าที่เก็บไว้ในตารางและส่งคืน

และเพิ่มเป็นเชิงอรรถ:

วิธีการนี้อนุมานว่าเรารู้ชุดของพารามิเตอร์ย่อยที่เป็นไปได้ทั้งหมดและเราได้สร้างความสัมพันธ์ระหว่างตำแหน่งของตารางและปัญหาย่อย อีกวิธีที่ทั่วไปกว่าคือการบันทึกโดยใช้การแฮชด้วยพารามิเตอร์ย่อยเป็นคีย์

มีปัญหา DP ที่มีความรู้ที่ต้องการ (หรือทำให้ง่ายขึ้น) ในการจัดเก็บค่าที่บันทึกในพจนานุกรมแทนที่จะเป็นในอาร์เรย์ (หลายมิติ) หรือไม่?


ข้อมูลประกอบ: หากนี่เป็นการใช้งานใด ๆ เหตุผลสำหรับคำถามนี้คือฉันพยายามกระตุ้นความคิดของแผนภูมิการค้นหาแบบไบนารี (สมดุลตนเอง) แก่ผู้ที่เพิ่งเห็นการเขียนโปรแกรมแบบไดนามิก


ในซอฟต์แวร์จริงที่ฉันทำงานด้วยการจดบันทึกสามารถใช้ประโยชน์จากความจริงที่ว่าฟังก์ชั่นที่ค่อนข้างแพง (เช่นexp , logหรือpow ) สามารถเรียกได้จากหลาย ๆ ตำแหน่งในรหัสและมักจะถูกเรียกหลายครั้งตามลำดับ ค่าเดียวกันจากที่ตั้งรหัสแต่ละแห่ง ในกรณีดังกล่าว "พจนานุกรม" อาจเป็นค่าเดียวที่เก็บไว้ในตัวแปรเฉพาะรหัสสถานที่
Mike Dunlavey

คำตอบ:


5

อาจมีตัวอย่างที่ดีกว่านี้ แต่นี่คือหนึ่งจากส่วนหัวของฉัน:

S,Td>d


3

ฉันต้องการให้ 2 ตัวอย่าง

ปัญหาเครื่องหลัง 0-1

ในกรณีที่มีปัญหา 0-1 เป้ (ที่Wคือความจุของเป้และNเป็นจำนวนรายการ) บางครั้งมันจะดีกว่าที่จะใช้ Dynamic Programming จากบนลงล่างพร้อมการบันทึกช่วยจำแทนการแจงนับจากล่างขึ้นบนอย่างเป็นระบบ ของอาร์เรย์ 2 มิติขนาดWxN ทั้งหมด (โดยเฉพาะอย่างยิ่งในกรณีที่ความจุของเป้Wมีขนาดใหญ่ แต่ความสำคัญของชุดของการรวมกันที่อนุญาตของน้ำหนักของสินค้ามีขนาดเล็กกว่าWมาก)

ในกรณีนี้เพื่อความประหยัดของหน่วยความจำผู้ใช้อาจเลือกที่จะใช้พจนานุกรมสำหรับบันทึกช่วยจำแทนอาร์เรย์ 2 มิติ

ขั้นตอนวิธีการแยกวิเคราะห์ Earley

อัลกอริธึมการแยกวิเคราะห์ Earleyสามารถใช้สำหรับการวิเคราะห์คำสั่งซึ่งเป็นของไวยากรณ์ที่ไม่มีบริบท ตรงข้ามกับอัลกอริธึม CYK (ซึ่งอิงตามวิธี DP จากล่างขึ้นบนและใช้ตาราง 2D สำหรับการบันทึก) - ตัวแยกวิเคราะห์ Earley ใช้วิธีการจากบนลงล่างร่วมกับแผนภูมิการแยกเพื่อการบันทึก

การแยกวิเคราะห์แผนภูมิมีการแยกวิเคราะห์ทางไวยากรณ์บางส่วน (เช่น: จากการผลิตX → ABและหลังจากประสบความสำเร็จในการจับคู่ส่วนAของการผลิตนี้เราเก็บการผลิตที่จับคู่บางส่วนไว้ในแผนภูมิการแยก: X → A • Bที่จุดจุด ไปยังส่วนที่ตรงกันแล้ว)

จำนวนคอลัมน์ภายในแผนภูมิการแยกเท่ากับจำนวนโทเค็น อย่างไรก็ตามในกรณีทั่วไปอาจเป็นเรื่องยากมากในการประเมินจำนวนของการผลิตไวยากรณ์แยกวิเคราะห์บางส่วนต่อคอลัมน์ (ขึ้นอยู่กับไวยากรณ์และลำดับของโทเค็นเฉพาะ)

ดังนั้นจึงสะดวกกว่าที่จะใช้แผนภูมิการแยกวิเคราะห์ตามโครงสร้างข้อมูลพจนานุกรม

ในโดเมนการประมวลผลภาษาธรรมชาติโดยปกติแล้วผู้ตรวจการ Earley เป็นตัวเลือกที่สะดวกกว่าเพราะไม่ต้องการรูปแบบปกติของ Chomskyสำหรับไวยากรณ์ (และ CYK มีข้อกำหนดดังกล่าว)


0

จากประสบการณ์ของฉันจากการเขียนโปรแกรมการแข่งขันการใช้ตารางแฮช (Python dictหรือคล้ายกัน) มักจะสะดวกกว่าการใช้อาเรย์เพราะประเภทข้อมูลใด ๆ ที่แฮชสามารถใช้เป็นกุญแจเช่นสตริงชุด ( frozensetใน Python) หรือทูเปิล(string, int)เป็นต้น หากใช้อาเรย์คุณจะต้องแปลคีย์ทั้งหมดเป็นจำนวนเต็ม (เริ่มต้นที่ 0) ซึ่งทำงานพิเศษและในฐานะซอร์สโค้ดของคุณอาจเป็นไปไม่ได้ถ้าคุณไม่ทราบพื้นที่ของคีย์ล่วงหน้า ดังนั้นพจนานุกรมค่อนข้างกว้างกว่าอาร์เรย์

แน่นอนถ้าคุณสามารถหลีกเลี่ยงการใช้อาร์เรย์มันอาจเร็วกว่าเพราะหลีกเลี่ยงการคำนวณแฮชซ้ำ ๆ (ในทางกลับกันมันต้องเริ่มต้นอาร์เรย์ทั้งหมดก่อนซึ่งใช้เวลาและหน่วยความจำ) แต่อาจใช้เวลานานกว่าในการเขียนรหัส เพราะคุณต้องทำงานพิเศษในการแปลคีย์ทั้งหมดเป็นจำนวนเต็ม

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