ความแตกต่างในการเขียนโปรแกรมแบบไดนามิก: ตัวอย่างที่จำเป็น!


19

ฉันทำงานเกี่ยวกับการเขียนโปรแกรมแบบไดนามิกมาระยะหนึ่งแล้ว วิธีบัญญัติของการประเมินการเรียกใช้การเขียนโปรแกรมแบบไดนามิกคือการสร้างตารางของค่าที่จำเป็นทั้งหมดและกรอกข้อมูลทีละแถว ดูตัวอย่างจากCormen, Leiserson และ al: "Introduction to Algorithms"สำหรับการแนะนำ

ฉันมุ่งเน้นที่รูปแบบการคำนวณบนโต๊ะในสองมิติ (การกรอกข้อมูลแบบแถวต่อแถว) และตรวจสอบโครงสร้างของการพึ่งพาเซลล์นั่นคือเซลล์ใดที่ต้องทำก่อนที่จะคำนวณอื่นได้ เราแสดงด้วยชุดของดัชนีของเซลล์ที่เซลล์ของฉันขึ้นอยู่กับ โปรดทราบว่าΓจะต้องไม่มีรอบΓ(i)iΓ

ฉันสรุปจากฟังก์ชันจริงที่คำนวณและมีสมาธิกับโครงสร้างแบบเรียกซ้ำ อย่างเป็นทางการผมพิจารณา recurrrence ที่จะเขียนโปรแกรมแบบไดนามิกถ้ามันมีรูปแบบd

d(i)=f(i,Γ~d(i))

กับ , ~ Γ d ( ฉัน ) = { ( J , d ( ) ) | เจΓ d ( ฉัน ) }และบางคน (คำนวณ) ฟังก์ชั่นที่ไม่ได้ ใช้วันที่อื่นที่ไม่ใช่ผ่าน~ Γ di[0m]×[0n]Γ~d(i)={(j,d(j))jΓd(i)}fdΓ~d

เมื่อการ จำกัด ความละเอียดของไปยังพื้นที่ขรุขระ (ไปทางซ้าย, ซ้าย - บน, บน - ขวา, ... ของเซลล์ปัจจุบัน) หนึ่งสังเกตว่ามีสามกรณี (ถึงสมมาตรและการหมุน) ที่ถูกต้อง การเรียกโปรแกรมแบบไดนามิกที่แจ้งวิธีเติมตาราง:Γd

สามกรณีของการพึ่งพาเซลล์การเขียนโปรแกรมแบบไดนามิก

พื้นที่สีแดงหมายถึง (overapproximations ของ) Γกรณีที่หนึ่งและสองยอมรับชุดย่อยกรณีที่สามคือกรณีที่เลวร้ายที่สุด (สูงถึงการแปลงดัชนี) โปรดทราบว่าไม่จำเป็นต้องใช้อย่างเคร่งครัดว่าทั้งพื้นที่สีแดงถูกปกคลุมไปด้วยΓ ; เซลล์บางส่วนในทุกส่วนสีแดงของตารางเพียงพอที่จะทาสีแดง พื้นที่สีขาวจำเป็นต้องมีการอธิบายเพื่อไม่ให้มีเซลล์ที่ต้องการΓΓ

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

ฉันไม่มีตัวอย่าง (ธรรมชาติ) สำหรับกรณีที่สามแม้ว่า ดังนั้นคำถามของฉันคืออะไรคือตัวอย่างของกรณีที่การเรียกซ้ำ / ปัญหาการเขียนโปรแกรมแบบไดนามิกสามกรณี


2
กรณีที่ 3 รายการย่อย 1 และ 2
JeffE

ไม่มันไม่ได้แม้จะมีรูปลักษณ์ ยกตัวอย่างเช่นตัวอย่างเช่นกรณีที่ 1 ไม่สามารถมีเซลล์ที่จำเป็นต้องใช้ในพื้นที่ด้านบนซ้ายในขณะที่ตัวอย่างเช่นกรณีที่ 3 มีจะมีเซลล์ที่จำเป็นในพื้นที่ด้านบนซ้าย ฉันแก้ไขคำอธิบายเพื่อชี้แจง
ราฟาเอล

คำตอบ:


15

มีตัวอย่างอื่น ๆ ของอัลกอริทึมการเขียนโปรแกรมแบบไดนามิกที่ไม่เหมาะกับรูปแบบของคุณเลย

  • ปัญหาลำดับที่เพิ่มขึ้นที่ยาวที่สุดนั้นต้องการเพียงตารางหนึ่งมิติ

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

  • (1+ϵ)


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

9
โอเค แต่ฉันคิดว่าคุณไม่มีประเด็น
JeffE

เนื่องจากมี upvotes มากมายฉันคิดว่าฉันควรทำให้ชัดเจน: โพสต์นี้ไม่ตอบคำถามและในความเป็นจริงก็ไม่ได้พยายาม
Raphael

2
@ ราฟาเอลถูกต้อง "คำตอบ" ของฉันไม่ใช่คำตอบ แต่เป็นการวิจารณ์คำถาม แต่มันยาวเกินไปสำหรับความคิดเห็น
JeffE

3

A(m,n)A(m,n1)A(m1,k)k

สิ่งนี้ไม่เหมาะกับความต้องการเนื่องจากจำนวนคอลัมน์ไม่มีที่สิ้นสุดและการคำนวณมักจะทำจากบนลงล่างด้วยการท่องจำ แต่ฉันคิดว่ามันคุ้มค่าที่จะพูดถึง


1
A(m1,A(m,n1))

1
ไม่แน่ใจว่าทำไมคำตอบนี้จึงถูกลดระดับลงเนื่องจากเป็นคำตอบที่ดี ฟังก์ชั่น Ackermann ให้ยืมตัวเองดีมากสำหรับการเขียนโปรแกรมแบบไดนามิก โดยทั่วไปฟังก์ชันใด ๆ ที่กำหนดซ้ำซึ่งคำนวณซ้ำ ๆ สำหรับอาร์กิวเมนต์เดียวกันจะให้ยืมตัวเองกับการเขียนโปรแกรมแบบไดนามิก หากต้องการดูสิ่งนี้จะต้องใช้งานและเปรียบเทียบเวลาการทำงาน สิ่งที่ใช้เวลาหลายปีในการคำนวณด้วยฟังก์ชั่น Ackermann สามัญอาจใช้เวลาไม่กี่วินาทีกับการตั้งโปรแกรมแบบไดนามิก
Jules

@Jules: ปัญหาสำหรับรูปแบบตารางแบบบัญญัติคือคุณไม่ทราบว่ามีการผูก (ดั้งเดิมแบบเรียกซ้ำ) บนขนาดตาราง a นิรนัย แน่นอนว่าคุณสามารถทำการจำได้ แต่ไม่ได้ทำในวิธีปกติ ดังนั้นใช่มันอาจเป็นไปได้สำหรับ DP แต่มันไม่พอดีกับระดับของปัญหาที่คำถามของฉันเกี่ยวข้อง
Raphael

1
ฉันไม่คิดว่ามันเป็นข้อกำหนดสำหรับ DP ที่คุณมีความสำคัญกับขนาดของตารางใช่หรือไม่ ในความเป็นจริงตามที่ JeffE กล่าวถึงแคชไม่จำเป็นต้องเป็นตารางเลย มันสามารถเป็นโครงสร้างข้อมูลเชื่อมโยงใด ๆ DP เป็นแนวคิดที่ง่ายมาก ๆ : คุณต้องการคำนวณฟังก์ชั่นที่กำหนดซ้ำ แต่ฟังก์ชั่นนี้จะถูกเรียกซ้ำ ๆ บนอาร์กิวเมนต์เดียวกัน DP คือการเพิ่มประสิทธิภาพที่คุณแนะนำแคชเพื่อให้แน่ใจว่าคุณคำนวณแต่ละกรณีเพียงครั้งเดียว มีฟังก์ชั่นมากมายที่ไม่เหมาะกับเคสของคุณแม้ว่ามันจะเป็นฟังก์ชั่นของจำนวนเต็มสองจำนวนที่มีขอบเขต
Jules

2

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

ดังนั้นกฎจึงเป็นดังนี้:

diagMatrix


1
เขียนแบบนี้มันไม่เหมาะกับกรณีใด ๆ อย่างไรก็ตามถ้าคุณหมุนตามเข็มนาฬิกา 45 องศาคุณจะได้รับกรณีที่ 2 (และคุณสมบัติทั้งหมดโดยนัย) นี่เป็นความจริงสำหรับตัวอย่างอื่น ๆ ที่ทำงานจากแนวทแยงมุมไปยังมุมอีกด้วย แต่ขอบคุณที่พูดถึงมัน!
Raphael

@ ราฟาเอลไม่ชัดเจนในทันทีว่าสิ่งเหล่านี้เทียบเท่าคุณอาจต้องการพูดถึงในคำถามของคุณ
Joe

0

ฉันรู้ว่ามันเป็นตัวอย่างที่งี่เง่า แต่ฉันคิดว่าเป็นปัญหาซ้ำ ๆ อย่างง่ายเช่น

ค้นหาผลรวมของตัวเลขในเมทริกซ์จตุรัส

อาจมีสิทธิ์ แบบดั้งเดิม "สำหรับแต่ละแถวสำหรับแต่ละคอลัมน์" ดูเหมือนว่ากรณีของคุณ 3


-1

นี่ไม่ใช่พื้นที่การค้นหาที่คุณกำลังมองหา แต่ฉันมีความคิดที่ดีในหัวของฉันซึ่งอาจช่วยได้

ปัญหา:

n×nMxM

ตอบ

วิธีนี้สามารถแก้ไขได้ด้วยวิธีแบบเรียกซ้ำต่อไปนี้:

k=1+n2xmk,kx<mk,kmi,jkinkjn1/4x>mk,k1/434n2x(34)3n2


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