Щоб спробувати перевірити правильність алгоритму для якоїсь проблеми, звичайним початковим пунктом є спробувати запустити алгоритм вручну на декількох простих тестових випадках - спробуйте його на кількох прикладах проблемних випадків, включаючи кілька простих "кутових випадків" ". Це чудова евристика: це чудовий спосіб швидко вилучити багато неправильних спроб алгоритму та зрозуміти, чому алгоритм не працює.
Однак, вивчаючи алгоритми, деякі студенти спокушаються зупинитися на цьому: якщо їх алгоритм працює правильно на кількох прикладах, включаючи всі кутові випадки, які вони можуть спробувати спробувати, то вони роблять висновок, що алгоритм повинен бути правильним. Завжди є студент, який запитує: "Чому мені потрібно довести свій алгоритм правильним, якщо я можу просто спробувати його на кількох тестових випадках?"
Отже, як ви обдурите евристику "спробуйте купу тестових справ"? Я шукаю кілька хороших прикладів, щоб показати, що цього евристики недостатньо. Іншими словами, я шукаю один або кілька прикладів алгоритму, який поверхово виглядає так, що це може бути правильним, і який дає правильну відповідь на всі невеликі входи, які хтось, ймовірно, може придумати, але де алгоритм насправді не працює. Можливо, алгоритм просто працює правильно на всіх малих входах і виходить з ладу лише для великих входів, або лише не працює для входів з незвичайним малюнком.
Конкретно шукаю:
Алгоритм. Недолік повинен бути на алгоритмічному рівні. Я не шукаю помилок в реалізації. (Наприклад, при мінімальному рівні приклад повинен бути мовно-агностичним, і недолік повинен стосуватися алгоритмічних проблем, а не інженерії програмного забезпечення або впровадження.)
Алгоритм, який хтось може правдоподібно придумати. Псевдокод повинен виглядати принаймні правдоподібно правильним (наприклад, код, який затуманений або очевидно сумнівний, не є гарним прикладом). Бонусні бали, якщо це алгоритм, який насправді придумав студент, намагаючись вирішити домашнє завдання чи екзаменаційну задачу.
Алгоритм, який би пройшов розумну ручну тестову стратегію з високою ймовірністю. Хтось, хто намагається вручну спробувати кілька невеликих тестових випадків, навряд чи виявить недолік. Наприклад, "моделювати QuickCheck вручну з десятка невеликих тестових випадків" навряд чи виявить, що алгоритм невірний.
Переважно, детермінований алгоритм. Я бачив, як багато студентів думають, що "спробувати кілька тестових випадків вручну" - це розумний спосіб перевірити, чи правильний алгоритм детермінований, але я підозрюю, що більшість студентів не вважають, що спробування декількох тестових випадків - це хороший спосіб перевірити вірогідність алгоритми. Для імовірнісних алгоритмів часто немає способу визначити, чи правильний якийсь конкретний вихід; і ви не можете перекрутити достатньо прикладів, щоб зробити будь-який корисний статистичний тест на розподіл виводу. Тому я вважаю за краще зосередитись на детермінованих алгоритмах, оскільки вони стають більш чіткими до серця помилок учнів.
Я хотів би навчити важливості доведення вашого алгоритму правильним, і я сподіваюся використати кілька таких прикладів, щоб допомогти мотивувати докази правильності. Я вважаю за краще приклади, які відносно прості та доступні для студентів; приклади, що вимагають важкої техніки або тон математичного / алгоритмічного походження, є менш корисними. Крім того, я не хочу алгоритмів, які є "неприродними"; хоча це може бути легко побудувати якийсь дивний штучний алгоритм, щоб обдурити евристику, якщо він виглядає вкрай неприродно або має очевидний задній простір, побудований просто для того, щоб обдурити це евристику, це, мабуть, не буде переконливим для студентів. Якісь хороші приклади?