Menguji algoritma (deterministik) dengan banyak atau sulit untuk membuktikan jawaban benar yang benar

11

Saya ingin Pendahuluan ini bahwa ini pertanyaan serupa, tapi pertanyaan saya tidak melibatkan keacakan, hanya rewel determinisme, sehingga jawaban dari "menggunakan benih yang dikenal" tidak benar-benar berlaku. Demikian juga, ini pertanyaan serupa, tapi sekali lagi, saya tidak mengharapkan algoritma yang pernah gagal - Saya tidak tahu jalan mana yang akan benar.

Pertanyaan ini muncul saat menguji algoritma grafik. tetapi tidak terbatas pada mereka. Beberapa algoritma seperti A * dapat memiliki beberapa jawaban yang benar. Bergantung pada implementasi tepat Anda, Anda mungkin mendapatkan salah satu dari beberapa jawaban, yang masing-masing sama-sama benar. Ini bisa membuat mereka sulit untuk diuji, karena Anda tidak tahu yang mana yang akan dimuntahkan sebelumnya, dan itu sangat memakan waktu untuk menghitung jawaban dengan tangan.

Dalam kasus spesifik saya, saya mengatasinya dengan memodifikasi Floyd-Warshall untuk memuntahkan setiap jalur terpendek yang mungkin , dan menghabiskan waktu untuk menguji itu. Itu memiliki manfaat menjadi fitur yang baik dengan sendirinya. Kemudian saya bisa menguji fungsi-fungsi lain dalam hal jalur yang benar yang diketahui dari FW (jika jalur yang dikembalikan adalah salah satu jalur yang dikembalikan oleh FW untuk pasangan awal / akhir, itu benar). Tentu saja, ini hanya berfungsi untuk grafik padat karena cara kerja FW, tapi tetap bagus.

Namun, itu mungkin tidak selalu layak untuk semua algoritma dengan karakteristik ini. Sejauh ini, jawaban terbaik yang saya dapatkan adalah menguji karakteristik jawaban yang benar, bukan jawaban yang benar itu sendiri. Untuk kembali ke algoritme jalur terpendek, Anda dapat memeriksa biaya jalur yang dikembalikan terhadap biaya yang diketahui dan memastikan jalur tersebut valid.

Ini berfungsi, tetapi dapat menjalankan risiko tidak memverifikasi semuanya dengan benar, semakin banyak kriteria untuk kebenaran ada, terutama jika verifikasi itu sendiri kompleks (misalnya saat ada algoritma yang benar , memverifikasi pohon rentang minimum adalah masalah yang sulit diketahui; mungkin lebih sulit daripada membangun MST itu sendiri), dalam hal ini Anda sekarang harus menguji secara luas kode pengujian Anda. Lebih buruk: mungkin Anda harus membangun MST untuk menguji algoritma verifikasi MST sehingga Anda sekarang memiliki skenario yang hebat di mana tes MST Anda bergantung pada algoritma verifikasi MST Anda bekerja, dan tes algoritma verifikasi MST Anda bergantung pada kerja kode generasi MST Anda.

Akhirnya, ada "cara murah", yang melibatkan mengamati output, memverifikasinya dengan tangan, lalu menyandikan tes untuk menguji output yang baru saja Anda verifikasi, tapi itu bukan ide bagus karena Anda mungkin harus merevisi tes setiap kali Anda ubah implementasi sedikit (yang seharusnya dihindari pengujian otomatis).

Jelas jawabannya tergantung pada algoritma yang tepat yang Anda uji sampai taraf tertentu, tetapi saya bertanya-tanya apakah ada "praktik terbaik" untuk memverifikasi algoritma yang memiliki beberapa keluaran pasti, deterministik "benar", tetapi keluaran tepat yang benar itu sulit untuk dilakukan. tahu sebelumnya, dan mungkin sulit untuk memverifikasi setelah fakta.

LinearZoetrope
sumber
3
Jika bahasa memungkinkan, Anda dapat membuktikan kebenaran alih-alih mengujinya
miniBill
Ada banyak teks, tetapi tidak ada pertanyaan. Jadi, apa yang sebenarnya Anda tanyakan?
BЈовић
@ BЈовић "Bagaimana saya harus menguji implementasi algoritma dengan banyak dan / atau sulit untuk memverifikasi output yang benar?" Saya tidak yakin bagaimana membuatnya lebih jelas, maaf. Saya akui bahwa itu bisa dianggap agak luas tergantung pada perspektif Anda, tapi saya rasa itu tidak terdefinisi.
LinearZoetrope
Saya masih tidak mengerti. Algoritme Anda tidak bergantung pada keacakan, namun masih dapat menghasilkan output yang berbeda. Itu sama sekali tidak masuk akal. Setiap algoritma, untuk input yang ditetapkan, harus memiliki output yang sama. Dan itulah yang dilakukan dan diuji dalam unit test. Bahkan algoritma dalam makalah yang Anda tautkan.
BЈовић
@ BЈовић Tentu saja deterministik, tetapi juga sangat sensitif terhadap, misalnya urutan grafik mengembalikan penerus node. Ini dapat menyebabkan sedikit efek kupu-kupu. Apakah Anda menekan titik A pada tumpukan sebelum titik B akan menghasilkan output yang berbeda jika keduanya mengarah ke jalur terpendek. Menggunakan fungsi perpustakaan seperti jenis yang tidak stabil atau min-heaps hanya memperburuk masalah.
LinearZoetrope

Jawaban:

5

Saya tidak yakin Anda mencoba menguji properti yang benar, dan ini menyebabkan ambiguitas Anda.

Algoritma grafik tidak bertujuan untuk menemukan beberapa jalur terpendek (ini adalah efek samping), tetapi untuk meminimalkan atau memaksimalkan beberapa fungsi biaya yang didefinisikan pada himpunan tepi dan simpul. Dengan demikian, Anda dapat memeriksa kebenaran solusi dengan menguji nilai akhir dari fungsional ini dan menyatakan bahwa node pertama dan terakhir adalah yang benar-benar diperlukan.

Jika Anda dapat melakukan pra-perhitungan nilai fungsi biaya akhir untuk setiap jalur yang mungkin (biasanya tidak realistis), maka Anda hanya perlu memeriksa bahwa biaya solusi yang disediakan oleh implementasi yang diuji adalah sama dengan biaya minimum di antara rangkaian ini (perbandingan mutlak ). Jika Anda "baru" memiliki algoritma dan / atau implementasi standar emas, maka Anda harus membandingkan biaya outputnya dengan salah satu algoritma yang sedang diuji (perbandingan relatif)

Misalnya, pengaturan tes naif adalah:

  1. Hitung semua jalur yang mungkin antara Va dan Vb dalam grafik uji dengan algoritma serakah.
  2. Hitung fungsi biaya (misalnya, panjang jika semua bobot tepi Anda sama dengan 1) untuk masing-masing jalur ini dan temukan nilai minimum.
  3. Terapkan algoritma yang sedang diuji.
  4. Buat pernyataan dalam pengujian unit Anda bahwa nilai biaya algoritma yang diuji sama dengan minimum solusi serakah.

Jika Anda ingin tahu lebih banyak tentang pengoptimalan berbasis grafik, Anda dapat melihat publikasi Yuri Boykov di sini , meskipun dalam konteks lain (masalah Penglihatan Komputer).

sansuiso
sumber
Saya terbalik, tetapi saya akan menunggu sedikit untuk menerima. Ini adalah "ujian untuk karakteristik jawaban yang benar" yang saya sebutkan dalam pertanyaan. Masalahnya selalu ada dalam memastikan Anda memverifikasi hal yang benar. Misalnya, pada satu titik saya sedang memeriksa biaya yang dikembalikan dan memastikan jalur itu valid. Tentu saja jalannya valid! Itu hanya simpul awal! Jadi saya harus mengubah tes untuk memastikan jalan itu sendiri benar-benar mengembalikan, biaya yang benar. Kesalahan konyol, tentu saja, tetapi semakin banyak interaksi seperti ini yang Anda miliki, semakin besar kemungkinan mereka.
LinearZoetrope
@Jsor menurut pandangan saya, ini adalah manfaat peningkatan pengujian yang berkelanjutan: Anda tidak bisa mengetahui semua sifat kebenaran solusi pada awalnya, kemudian suatu hari mengalami beberapa kegagalan, meningkatkan pengujian Anda dan sebagainya.
sansuiso
Jawaban ini merekomendasikan pengujian untuk karakteristik jawaban yang benar, tetapi yang penting adalah memilih karakteristik mana yang membuat tes yang baik. Dalam contoh ini, memverifikasi bahwa jawabannya adalah jalur dari A ke B dan bahwa fungsi biaya sama dengan nilai minimum memberi Anda dua kriteria yang semua memuaskan jawaban akan memenuhi, sedangkan tidak ada jawaban yang salah akan memenuhi kedua kriteria. Jika jawaban ini belum diberikan, saya akan merekomendasikan hal serupa. Memang seringkali tidak mudah untuk mengetahui karakteristik mana yang akan diuji.
David K
0

Saya pikir jawaban langsung untuk pertanyaan Anda adalah memilih test case yang lebih baik. Saya ingin tahu tentang kasus uji yang Anda gunakan. Grafik yang Anda gunakan dapat berupa grafik DAPAT di mana relatif mudah bagi manusia untuk menentukan respons yang diharapkan. Cobalah untuk mencari tahu "tepi" kasus yang Anda ingin memastikan algoritma Anda menangani dan membuat grafik kalengan untuk masing-masing kasus tepi tertentu yang mudah bagi manusia untuk menghitung. Misalnya, dalam kasus algoritme Djikstra, Anda mungkin dapat membuat beberapa grafik 5x5 atau 7x7 yang mencakup semua kasing tepi Anda, meskipun sistem Anda yang sebenarnya mungkin 500x500.

Kemudian sebagai pemeriksaan kewarasan terakhir Anda dapat membuat satu atau dua test case grafik yang lebih realistis. Tetapi bagaimanapun juga, saya pikir sansuiso telah menemukannya di mana ditunjukkan bahwa Anda perlu memastikan Anda menguji properti yang benar.

Celup
sumber