แนวปฏิบัติที่ดีสำหรับการเขียนอัลกอริทึม


22

นี่คือเกี่ยวกับประสิทธิภาพที่เราสามารถแสดงอัลกอริทึมในมือ ฉันต้องการสิ่งนี้สำหรับการสอนระดับปริญญาตรี

ฉันเข้าใจว่าไม่มีสิ่งนั้นเป็นวิธีมาตรฐานในการเขียนโค้ดหลอก ผู้เขียนที่แตกต่างกันปฏิบัติตามอนุสัญญา

มันจะมีประโยชน์ถ้าคนที่นี่ชี้ให้เห็นวิธีที่พวกเขาติดตามและคิดว่าดีที่สุด

มีหนังสือเล่มไหนบ้างที่เกี่ยวข้องกับเรื่องนี้ในรายละเอียดที่ดี?


9
"ดีที่สุด" เป็นเรื่องส่วนตัวฉันคิดว่าคุณควรปรับเปลี่ยนชื่อเรื่องและแทนที่การถามว่า "ดีที่สุด" ถามในสิ่งที่ผู้คนทำในทางปฏิบัติ อาจเป็น "วิธีการนำเสนออัลกอริทึม" หรือ "แนวปฏิบัติที่ดีสำหรับการนำเสนออัลกอริทึม" คุณอาจต้องการที่เฉพาะเจาะจงมากขึ้นตั้งแต่นำเสนออัลกอริทึม: 1. สำหรับนักเรียนในชั้นเรียนระดับปริญญาตรี 2. ในตำราเรียน 3. ในกระดาษการประชุมเป็นงานที่แตกต่างกันมาก
Kaveh

1
คุณอาจต้องการตรวจสอบส่วนที่เกี่ยวข้องของการเขียนทางคณิตศาสตร์โดย Knuth, Larrabee และ Roberts
Kaveh

คำตอบ:


26

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

แต่สำหรับบันทึกนี่เป็นมาตรฐานที่ฉันใช้ในบันทึกการบรรยายงานวิจัยและหนังสือเล่มต่อไป

  • ใช้ไวยากรณ์ที่จำเป็นมาตรฐานสำหรับโฟลว์การควบคุมและการเข้าถึงหน่วยความจำ - ถ้า, ในขณะ, สำหรับ, ส่งคืน, อาร์เรย์ [ดัชนี], ฟังก์ชัน (อาร์กิวเมนต์) สะกด "อื่นถ้า"

    • แต่ใช้field(record)แทนrecord.fieldหรือrecord->field
  • xyx*ys ที¬ พีamodba%bsts <= t¬p!pเธxsqrt(x)πPIMAX_INT

    • แต่ใช้สำหรับการมอบหมายเพื่อหลีกเลี่ยงปัญหาxy==

    • แต่หลีกเลี่ยงสัญกรณ์ (และ pseudocode!) โดยสิ้นเชิงถ้าภาษาอังกฤษชัดเจน

      • สมมาตรหลีกเลี่ยงภาษาอังกฤษถ้าสัญกรณ์ชัดเจน!
  • ย่อน้ำตาลประโยคให้น้อยที่สุด - ระบุโครงสร้างบล็อกโดยการเยื้องที่สอดคล้องกัน (à la Python) งดคำหลักหวานเช่น "เริ่มต้น / สิ้นสุด" หรือ "ทำ / od" หรือ "fi" ละเว้นหมายเลขบรรทัด ไม่ได้เน้นคำหลักเช่น "สำหรับ" หรือ "ในขณะที่" หรือ "ถ้า" โดยการตั้งค่าไว้ในที่แตกต่างกันtypefaceหรือสไตล์ เคย ทำไม่ได้

    • แต่ชื่ออัลกอริทึมของเรียงพิมพ์และค่าคงที่ใน \ ตำราc {Small Caps}, ชื่อตัวแปรในตัวเอียงและสตริงตัวอักษรใน sans serif

    • แต่เพิ่มช่องว่าง "หายใจ" ในแนวดิ่ง ( \\[0.5ex]) จำนวนหนึ่งระหว่างชิ้นโค้ดที่มีความหมาย

  • อย่าระบุรายละเอียดที่ไม่สำคัญ ถ้ามันไม่สำคัญว่าคุณจะไปที่จุดยอดนิยมเพียงแค่พูดว่า "สำหรับทุกจุด"

ยกตัวอย่างเช่นที่นี่เป็นสูตร recursive ของขั้นต่ำขั้นตอนวิธีต้นไม้ทอด Boruvka ของ ก่อนหน้านี้ฉันได้กำหนดเป็นกราฟที่ได้รับจากโดยการหดตัวขอบทั้งหมดในชุดและแบนเป็นรูทีนย่อยที่ลบลูปและขอบขนานG LG/LGL

อัลกอริทึมของBorůvka

ฉันใช้algorithmสภาพแวดล้อม LaTeX ที่มีน้ำหนักเบาของฉันเพื่อพิมพ์รหัสเทียม (เป็นเพียงtabbingสภาพแวดล้อมภายใน\fbox) นี่คือซอร์สโค้ดของฉันสำหรับอัลกอริทึมของBorůvka:

\begin{algorithm}
	\textul{$\textsc{Borůvka}(G)$:}\+
\\	if $G$ has no edges\+
\\		return $\varnothing$\-
\\[0.5ex]
	$L \gets \varnothing$
\\	for each vertex $v$ of $G$\+
\\		add the lightest edge incident to $v$ to $L$\-
\\[0.5ex]
	return $L \cup \textsc{Borůvka}(\textsc{Flatten}(G / L))$
\end{algorithm}

น่าสนใจที่คุณใช้ฟิลด์ (บันทึก) แทนบันทึก [ฟิลด์] ฉันคิดว่านี่คือมุมมอง "คือพิกัดของ " ของโลก? j t h vfj(v)jthv
Suresh Venkat

@SureshVenkat: เป็นวิธีที่คุณมักจะทำในภาษาที่ใช้งานได้และยังมีเครื่องหมายใน TAoCP (เห็นได้ชัดว่าฉันไม่รู้ว่าเป็นเพราะเหตุใด Jff ff E ใช้สัญลักษณ์นี้)
Radu GRIGore

5
เหตุผลหลักที่ควรระวังรหัสหลอกคือมันง่ายที่จะสับสนเกี่ยวกับอัลกอริทึมดังนั้นจึงเป็นสิ่งสำคัญที่จะต้องเน้นบางสิ่ง ตัวอย่างของ Jeff ด้านบนสำหรับ Boruvka แสดงสิ่งนี้ ในรหัส L จะถูกถือว่าเป็นชุด ยูวี edge อาจเป็นเหตุการณ์ที่ขอบที่เบาที่สุดสำหรับ u รวมถึง v ดังนั้นมันจึงถูกเพิ่มเข้ามาสองครั้งในลูป แต่มันไม่สำคัญว่าถ้าคุณคิดว่า L เป็นเซต อย่างไรก็ตามนี่ไม่ชัดเจนและบางคนที่ใช้สิ่งนี้สามารถเพิ่มขึ้นได้อย่างง่ายดายหากพวกเขาใช้ L เป็นรายการ
จันทรา Chekuri

2
@ChandraChekuri: ใช่การใช้ชุดที่ไม่ถูกต้องอาจทำให้เกิดปัญหาในอัลกอริทึมที่จัดการกับชุด
Jeffε

1
@SureshVenkat: โอ้นั่น ไม่ฉันทนไม่ได้ คำหลักที่เป็นตัวหนาทำให้ลูกน้อยของพระเยซูร้องไห้ Dijkstra ควรเสียรางวัลทัวริงของเขาสำหรับการแนะนำการประชุมวิชาการพิมพ์ที่น่ารังเกียจ
Jeff

11

ฉันมักจะใช้สิ่งที่คล้ายกับ Python ไวยากรณ์ Python ใกล้เคียงกับ pseudocode อยู่แล้วในบางกรณี pseudocode ของฉันสามารถแรเงาเป็นโค้ดที่ใช้งานได้จริง


ฉันยัง แต่ในทับทิม ด้วย gist gist คุณสามารถแบ่งปันตัวอย่างไฟล์ที่เรียกใช้งานได้เพื่อให้เล่นกับมันได้อย่างง่ายดาย gist.github.com/chadbrewbaker/7202412
Chad Brewbaker

อย่างไรก็ตาม Python นั้นไม่ดีในการแสดงพีชคณิตเชิงเส้น อ็อกเทฟเป็นแบบที่ดีกว่าฉันคิดว่าในกรณีนี้ (ใกล้กับรหัสเทียม)
gaborous

3

หากคุณต้องการมีรหัสแน่นอน (เช่นคณิตศาสตร์น้อยไปไม่มีคณิตศาสตร์ใกล้กับการเขียนโปรแกรมจริง) คุณอาจต้องการพิจารณามีรหัสที่รวบรวมจริง นี่มีข้อดีหลายประการ:

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

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


"แค่ยึดติดกับหนึ่ง (ต่อกระบวนทัศน์) ที่เหมาะกับระดับความเป็นนามธรรมของคุณที่สุด" ฉันคิดว่านี่เป็นคำแนะนำที่ดีในการค้นหาทางเลือก pseudocode มีภาษามากมายและมีอย่างน้อยหนึ่งภาษาที่กำหนดเป้าหมายไวยากรณ์แบบง่ายสำหรับกระบวนทัศน์เฉพาะ: Ada สำหรับการออกแบบพร้อมกัน, Octave สำหรับพีชคณิตเชิงเส้น, Python สำหรับขั้นตอน, NetLogo สำหรับระบบหลายตัวแทน, Prolog สำหรับตรรกะ, CLIPS สำหรับ การเขียนโปรแกรมตามกฎ ฯลฯ
gaborous

@gaborous หากคุณสามารถอ่านได้รหัสนามธรรม - ไปสำหรับมัน น่าเสียดายที่ฉันสงสัยว่าสิ่งนี้จะทำให้คุณใช้ภาษาอย่างน้อยสามภาษาในการทำงานที่ใหญ่กว่าใด ๆ ที่จะโชคร้ายเช่นกัน
Raphael

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