Praktik yang baik untuk menulis algoritma

22

Ini tentang seberapa efektif kita dapat mengekspresikan suatu algoritma. Saya membutuhkan ini untuk pengajaran sarjana saya.

Saya mengerti tidak ada yang namanya cara standar untuk menulis kode semu. Penulis yang berbeda mengikuti konvensi yang berbeda.

Akan sangat membantu jika orang-orang di sini menunjukkan, cara mereka mengikuti dan berpikir yang terbaik.

Apakah ada buku yang membahas hal ini dengan sangat baik?

pengguna3162
sumber
9
"Terbaik" sangat subyektif, saya pikir Anda harus memodifikasi judul dan di tempat meminta "terbaik", tanyakan apa yang dilakukan orang dalam praktik. Mungkin sesuatu seperti "bagaimana menyajikan algoritma" atau "praktik yang baik untuk menyajikan algoritma". Anda mungkin juga ingin lebih spesifik karena menyajikan algoritma: 1. kepada siswa di kelas sarjana 2. di buku teks 3. di makalah konferensi adalah tugas yang sangat berbeda.
Kaveh
1
Anda mungkin juga ingin memeriksa bagian yang relevan dari Penulisan Matematika oleh Knuth, Larrabee, dan Roberts.
Kaveh

Jawaban:

26

Menulis pseudocode seperti menulis kode: Ini tidak terlalu penting standar mana yang Anda ikuti, selama Anda (dan orang-orang yang menulis dengan Anda) benar-benar mengikuti beberapa standar.

Tetapi sebagai catatan, inilah standar istimewa yang saya gunakan dalam catatan kuliah, makalah penelitian, dan buku saya yang akan datang.

  • Gunakan sintaks imperatif standar untuk aliran kontrol dan akses memori - jika, sementara, untuk, kembali, array [indeks], fungsi (argumen). Tuliskan "else if".

    • Tetapi gunakan field(record) sebagai ganti record.fieldataurecord->field
  • Gunakan standar notasi matematika untuk matematika - Menulis bukan , sebuah mod b bukan , s t bukan , bukan , bukan , bukan , bukan , dll .xyx*yamodba%bsts <= t¬p!pxsqrt(x)πPIMAX_INT

    • Tetapi gunakan untuk penugasan, untuk menghindari masalah.xy==

    • Tetapi hindari notasi (dan kodesemu!) Sepenuhnya jika bahasa Inggris lebih jelas.

      • Secara simetris, hindari Bahasa Inggris jika notasi lebih jelas!
  • Minimalkan gula sintaksis - Tunjukkan struktur blok dengan indentasi yang konsisten (à la Python). Hapus kata kunci yang manis seperti "mulai / akhir" atau "do / od" atau "fi". Hapus nomor baris. Jangan tidak menekankan kata kunci seperti "untuk" atau "sementara" atau "jika" dengan menetapkan mereka dalam berbagai typefaceatau gaya . Pernah. Hanya saja, jangan.

    • Tetapi nama-nama algoritma konstanta dan konstanta dalam \ textsc {Small Caps}, nama variabel dalam huruf miring , dan string literal dalam sans serif.

    • Tetapi tambahkan sedikit ruang "bernapas" vertikal ( \\[0.5ex]) di antara potongan kode yang bermakna.

  • Jangan menentukan detail yang tidak penting. Jika tidak masalah urutan apa yang Anda kunjungi simpul, cukup katakan "untuk semua simpul".

Sebagai contoh, berikut adalah formulasi rekursif dari algoritma spanning tree minimum Borůvka . Saya sebelumnya telah mendefinisikan sebagai grafik yang diperoleh dari dengan mengontrak semua tepi di set , dan Ratakan sebagai subrutin yang menghilangkan loop dan tepi paralel.G/LGL

Algoritma Borovka

Saya menggunakan algorithmlingkungan LaTeX ringan saya sendiri untuk mengeset pseudocode. (Ini hanya tabbinglingkungan di dalam \fbox.) Berikut kode sumber saya untuk algoritma 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}
Jeffε
sumber
fj(v)jthv
@ SureshVenkat: Begitulah cara Anda biasanya melakukannya dalam bahasa fungsional, dan juga notasi dalam TAoCP. (Jelas, saya tidak tahu apakah itu sebabnya Jɛ ff E menggunakan notasi ini.)
Radu GRIGore
5
Alasan utama untuk berhati-hati dengan pseudo-code adalah mudahnya bingung tentang algoritme sehingga penting untuk menekankan beberapa hal. Contoh Jeff di atas untuk Boruvka menggambarkan hal ini. Dalam kode L diperlakukan sebagai satu set. Edge uv dapat menjadi insiden edge paling ringan untuk Anda dan juga v sehingga ditambahkan dua kali dalam loop tetapi tidak masalah jika Anda menganggap L sebagai set. Namun, ini tidak jelas dan seseorang yang mengimplementasikan ini dapat dengan mudah tersandung jika mereka menerapkan L sebagai daftar.
Chandra Chekuri
2
@ChandraChekuri: Ya, mengimplementasikan set secara tidak benar dapat menyebabkan masalah dalam algoritma yang memanipulasi set.
Jeffε
1
@ SureshVenkat: Oh, itu. Tidak, saya tidak tahan. Kata kunci yang berani membuat bayi Yesus menangis. Dijkstra harus kehilangan penghargaan Turing karena memperkenalkan konvensi tipografi yang dapat dijalankan.
Jeff
11

Saya cenderung menggunakan sesuatu yang menyerupai sintaksis Python. Python sudah cukup dekat dengan pseudocode sehingga dalam beberapa kasus pseudocode saya dapat berubah menjadi kode kerja aktual.

David Eppstein
sumber
Saya juga, tetapi di Ruby. Dengan github gists, Anda dapat dengan mudah berbagi cuplikan yang dapat dieksekusi untuk dimainkan. gist.github.com/chadbrewbaker/7202412
Chad Brewbaker
Namun Python tidak baik untuk mewakili aljabar linier. Oktaf lebih cocok menurut saya dalam kasus ini (lebih dekat dengan pseudocode).
Gaborous
3

Jika Anda ingin memiliki kode yang pasti (yaitu sedikit atau tidak ada matematika, dekat dengan pemrograman nyata) Anda mungkin ingin mempertimbangkan untuk memiliki kode yang benar-benar dikompilasi. Ini memiliki beberapa keunggulan:

  • Anda mendapatkan sorotan sintaksis di mana-mana.
  • Compiler memeriksa sintaks untuk Anda dan menerapkan konsistensi.
  • Anda dapat menguji unit implementasi Anda untuk meningkatkan kualitas kode.
  • Anda dapat menjalankan algoritme dan membandingkan runtime yang diukur dengan analisis (dengan demikian memotivasi teknik analisis lanjutan).

Seorang profesor di universitas saya melakukan ini dalam kursus algoritmanya. Bahasa pilihannya adalah Modula. Tetapi saya tidak berpikir pilihan bahasa tertentu yang penting. Tetaplah pada satu (per paradigma) yang paling sesuai dengan tingkat abstraksi Anda.

Raphael
sumber
"Hanya berpegang pada satu (per paradigma) yang paling sesuai dengan tingkat abstraksi Anda." Saya pikir ini adalah saran yang bagus untuk mencari alternatif pseudocode. Ada banyak bahasa, dan hampir selalu ada setidaknya satu yang menargetkan sintaksis sederhana untuk paradigma spesifik: Ada untuk desain bersamaan, Oktaf untuk aljabar linier, Python untuk prosedural, NetLogo untuk sistem multi-agen, Prolog untuk logika, KLIP untuk pemrograman berbasis aturan, dll.
gaborous
@ rumit Jika Anda dapat memiliki kode abstrak yang dapat dibaca - lakukan saja. Sayangnya, saya menduga bahwa ini akan membuat Anda menggunakan setidaknya tiga bahasa dalam badan kerja yang lebih besar; itu akan sangat disayangkan juga.
Raphael
tentu saja saya setuju untuk kode yang lebih besar tidak ada bahasa, tetapi untuk algoritma inti yang kecil, seringkali mungkin untuk menemukan bahasa yang sangat dekat dengan pseudocode.
Gaborous