Strategi pemrograman apa yang dapat saya ambil untuk memodifikasi parameter algoritma dengan mudah?

17

Mengembangkan algoritma ilmiah adalah proses yang sangat berulang sering melibatkan perubahan banyak parameter yang saya ingin bervariasi baik sebagai bagian dari desain eksperimen saya atau sebagai bagian dari mengutak-atik kinerja algoritma. Strategi apa yang dapat saya ambil untuk menyusun parameter ini sehingga saya dapat dengan mudah mengubahnya di antara iterasi dan sehingga saya dapat dengan mudah menambahkan yang baru?

Scottie T
sumber

Jawaban:

14

Sulit bagi pengguna untuk menentukan setiap aspek dari suatu algoritma. Jika algoritma memungkinkan komponen bersarang, maka tidak ada jumlah opsi yang terbatas akan cukup. Oleh karena itu, sangat penting bahwa opsi tidak harus "menggembung" ke tingkat atas, seperti dalam kasus argumen eksplisit atau parameter templat. Ini kadang-kadang disebut "masalah konfigurasi" dalam rekayasa perangkat lunak. Saya percaya PETSc memiliki sistem unik yang kuat untuk manajemen konfigurasi. Ini mirip dengan pola Service Locator dalam esai Martin Fowler tentang inversi kontrol .

Sistem konfigurasi PETSc bekerja melalui kombinasi konfigurasi yang ditentukan pengguna yang dikelola oleh objek solver (dengan get and set queries) dan Options Database. Setiap komponen simulasi dapat mendeklarasikan opsi konfigurasi, nilai default, dan tempat untuk meletakkan hasilnya. Objek bersarang memiliki awalan yang dapat dikomposisikan, sehingga setiap objek yang membutuhkan konfigurasi dapat ditangani secara independen. Opsi itu sendiri dapat dibaca dari baris perintah, lingkungan, file konfigurasi, atau dari kode. Saat opsi dideklarasikan, string bantuan dan halaman manual ditentukan, sehingga -helpopsi tersebut dapat dimengerti dan sehingga GUI yang tertaut dengan benar dapat ditulis.

Pengguna memanggil SetFromOptionsmetode untuk membuat objek mengkonfigurasi sendiri berdasarkan opsi baris perintah. Memanggil fungsi ini adalah opsional, dan tidak dapat dipanggil jika pengguna (orang yang menulis kode yang memanggil PETSc) mengekspos opsi melalui beberapa antarmuka lainnya. Kami sangat menyarankan agar pengguna mengekspos basis data opsi karena memberikan pengguna akhir (orang yang menjalankan aplikasi) banyak daya, tetapi tidak diperlukan.

Konfigurasi tipikal, dipanggil via

PetscObjectOptionsBegin(object); /* object has prefix and descriptive string */
PetscOptionsReal("-ts_atol",                                      /* options database key */
                 "Absolute tolerance for local truncation error", /* long description */
                 "TSSetTolerances",                               /* function and man page on topic */
                  ts->atol,                                       /* current/default value *?
                  &ts->atol,                                      /* place to store value */
                  &option_set);                                   /* TRUE if the option was set */
PetscOptionsList("-ts_type","Time stepping method","TSSetType",TSList,
                 defaultType,typeName,sizeof typeName,&option_set);
TSAdaptSetFromOptions(ts->adapt);                                 /* configures adaptive controller method */
/* ... many others */
/* ... the following is only called from implicit implementations */
SNESSetFromOptions(ts->snes);                                     /* configure nonlinear solver. */
PetscOptionsEnd();

Catatan:

  • PetscOptionsList()menyajikan pengguna dengan pilihan dari daftar dinamis. Ada arsitektur plugin yang implementasi baru dapat digunakan untuk mengekspos diri mereka sebagai kelas pertama untuk penelepon. (Implementasi ini dapat ditempatkan di perpustakaan bersama dan digunakan sebagai kelas satu tanpa mengkompilasi ulang program.)
  • SNESSetFromOptions() mengkonfigurasi pemecah linear, prekondisi, dan komponen lainnya yang memerlukan konfigurasi secara rekursif.
Jed Brown
sumber
11

Saya telah menghadapi masalah ini beberapa kali ketika mengembangkan kode simulasi saya sendiri dari awal: parameter mana yang harus dimasukkan dalam file input, yang harus diambil dari baris perintah, dll. Setelah beberapa percobaan, yang berikut ternyata menjadi efisien. (Ini tidak setinggi PETSc.)

Alih-alih menulis 'program' simulasi eksperimental, saya lebih cenderung menulis paket Python yang berisi semua fungsi & kelas yang diperlukan untuk menjalankan simulasi. File input tradisional kemudian diganti dengan skrip Python kecil dengan 5 hingga 10 baris kode. Beberapa baris biasanya terkait dengan memuat file data dan menentukan output. Lainnya adalah instruksi untuk perhitungan yang sebenarnya. Nilai default yang bagus untuk argumen opsional dalam paket Python membuatnya mungkin bagi pemula untuk menggunakan perpustakaan untuk simulasi sederhana, sementara pengguna tingkat lanjut masih memiliki akses ke semua bel dan peluit.

Beberapa contoh:

Toon Verstraelen
sumber
Ini bagus, tapi saya pikir ini ortogonal untuk masalah konfigurasi. Jika Anda perlu menentukan algoritma hierarkis atau bersarang, maka Anda memiliki opsi untuk ditentukan untuk banyak objek dalam. Kode yang memanggil mereka yang seharusnya tidak benar-benar tahu tentang keberadaan mereka karena jumlah level dan jenis sarang dapat berubah. Ini adalah masalah dari semua pilihan "menggelegak". Dengan kode Python tingkat tinggi, Anda dapat membuatnya "mudah" untuk menentukan opsi-opsi itu, tetapi Anda masih harus menentukannya dalam kode. Saya pikir itu umumnya bukan hal yang baik.
Jed Brown
xmonad menggunakan metode ini untuk mengkonfigurasi window manager mereka untuk X.
rcollyer
2

Sebagai poin pertama, saya akan melakukan algoritma DAN perangkat lunak sealami mungkin. Saya telah belajar ini dengan cara yang sulit.

Katakanlah Anda mulai dengan test case sederhana. Anda dapat melakukan ini lebih cepat. Tetapi kemudian, jika Anda membuat perangkat lunak terlalu spesifik (terlalu sedikit parameter) untuk kasus awal ini, Anda akan kehilangan lebih banyak waktu mengadaptasinya setiap kali Anda menambahkan tingkat kebebasan baru. Apa yang saya lakukan sekarang menghabiskan lebih banyak waktu di awal membuat hal itu cukup umum, dan meningkatkan variasi parameter ketika saya bergerak maju.

Ini melibatkan lebih banyak pengujian dari awal karena Anda akan memiliki lebih banyak parameter dari titik awal, tetapi akan berarti bahwa Anda dapat memainkan banyak dengan algoritma pada nol atau biaya yang sangat rendah.

Contoh: algoritma melibatkan menghitung integral permukaan produk titik dari dua fungsi vektor. Jangan berasumsi dari awal ukuran, geometri dan diskritisasi permukaan jika di masa depan Anda mungkin ingin mengubahnya. Buat fungsi titik-produk, buat permukaan sealami mungkin, hitung integral dengan cara formal yang bagus. Anda dapat menguji setiap fungsi yang Anda buat secara terpisah.

Pada awalnya, Anda bisa dan mulai mengintegrasikan lebih dari geometri sederhana dan mendeklarasikan parameter may pada awalnya sebagai konstanta. Seiring berjalannya waktu, jika Anda ingin mengubah geometri, Anda dapat melakukannya dengan mudah. Seandainya Anda membuat asumsi di awal, Anda harus mengubah seluruh kode setiap waktu.

jbcolmenares
sumber