Bazı problemler için bir algoritmanın doğru olup olmadığını test etmek için, normal başlangıç noktası algoritmayı bir dizi basit test durumunda elle çalıştırmayı denemek - birkaç basit "köşe durumu" da dahil olmak üzere birkaç örnek problem örneğinde deneyiniz. ". Bu harika bir buluşsal yöntemdir: Bir algoritmada birçok yanlış girişimi hızlı bir şekilde ayıklamak ve algoritmanın neden işe yaramadığını anlamak için harika bir yoldur.
Bununla birlikte, algoritmaları öğrenirken, bazı öğrenciler orada durma eğilimindedir: eğer algoritmaları denemeyi düşünebilecekleri tüm köşe vakaları da dahil olmak üzere birkaç örnek üzerinde doğru çalışıyorsa, algoritmanın doğru olması gerektiği sonucuna varırlar. Her zaman şunu soran bir öğrenci vardır: "Birkaç test vakasında deneyebilirsem neden algoritmamı doğrulamam gerekiyor?"
Öyleyse, "bir avuç test vakasını dene" buluşsalını nasıl kandırıyorsun? Bu buluşsal yöntemin yeterli olmadığını göstermek için bazı güzel örnekler arıyorum. Başka bir deyişle, yüzeysel olarak doğru gibi görünen ve algoritmanın gerçekte nerede olacağı, ancak algoritmanın gerçekte olduğu küçük girişlerin hepsine doğru cevabı veren bir algoritma örneği arıyorum. çalışmıyor Belki de algoritma tüm küçük girişlerde doğru bir şekilde çalışıyor ve sadece büyük girişler için başarısız oluyor veya sadece alışılmadık bir düzende girişler için başarısız oluyor.
Özellikle, ben arıyorum:
Bir algoritma. Kusur algoritmik seviyede olmalıdır. Uygulama hataları aramıyorum. (Örneğin, en azından, örnek dilin agnostik olması ve kusur, yazılım mühendisliği veya uygulama konularından ziyade algoritmik endişelerle ilgili olmalıdır.)
Birisinin makul bir şekilde bulabileceği bir algoritma. Sahte kod en azından makul bir şekilde doğru görünmelidir (ör. Gizlenmiş veya açıkça şüpheli olan kod iyi bir örnek değildir). Bonus, bir öğrencinin bir ev ödevi veya sınav problemini çözmeye çalışırken gerçekten ortaya çıkardığı bir algoritma ise puan.
Yüksek olasılıkla makul bir manuel test stratejisini geçebilecek bir algoritma. Birkaç küçük test vakasını elle deneyen birinin bu hatayı keşfetmesi mümkün olmamalıdır. Örneğin, "QuickCheck'i bir düzine küçük test durumunda el ile simüle edin", algoritmanın yanlış olduğunu ortaya koyması olası değildir.
Tercihen, deterministik bir algoritma. Bir çok öğrencinin “bazı test vakalarını el ile dene” nin, deterministik bir algoritmanın doğru olup olmadığını kontrol etmenin makul bir yolu olduğunu düşündüğümü gördüm, ancak çoğu öğrencinin birkaç test senaryosunu denemenin olasılıkları doğrulamak için iyi bir yol olduğunu varsaymayacağını düşünüyorum. algoritmaları. Olasılıklı algoritmalar için, herhangi bir özel çıkışın doğru olup olmadığını söylemenin bir yolu yoktur; ve çıktı dağılımı üzerinde faydalı bir istatistiksel test yapmak için yeterli örneği elle veremezsiniz. Bu yüzden, öğrenci yanılgılarının kalbine daha net bir biçimde yaklaşırken deterministik algoritmalara odaklanmayı tercih ederim.
Algoritmanızın doğru olduğunu kanıtlamanın önemini öğretmek istiyorum ve doğruluk kanıtlarını motive etmek için buna benzer birkaç örnek kullanmayı umuyorum. Lisans öğrencileri için nispeten basit ve erişilebilir örnekleri tercih ediyorum; ağır makine veya bir ton matematiksel / algoritmik arka plan gerektiren örnekler daha az yararlıdır. Ayrıca, "doğal olmayan" algoritmalar istemiyorum; Sezgisel kandırmak için bazı garip yapay algoritmalar oluşturmak kolay olsa da, eğer oldukça doğal görünmüyorsa veya sadece bu sezgisel kandırmak için yapılmış açık bir arka kapı varsa, muhtemelen öğrencileri ikna etmeyecektir. İyi örnekler var mı?