어떤 문제에 대한 알고리즘이 올바른지 테스트하기 위해 일반적인 출발점은 여러 간단한 테스트 사례에서 직접 알고리즘을 실행하는 것입니다. 몇 가지 간단한 "코너 사례를 포함하여 몇 가지 예제 인스턴스에서 시도해보십시오. ". 이것은 휴리스틱입니다. 알고리즘에 대한 많은 잘못된 시도를 신속하게 제거하고 알고리즘이 작동하지 않는 이유를 이해하는 데 좋은 방법입니다.
그러나 알고리즘을 학습 할 때 일부 학생들은 여기서 그만두려고합니다. 시도 할 수있는 모든 경우를 포함하여 소수의 예제에서 알고리즘이 올바르게 작동하면 알고리즘이 정확해야한다는 결론을 내립니다. "여러 가지 테스트 사례에서 알고리즘을 시도 할 수 있다면 왜 알고리즘을 올바르게 증명해야합니까?"라고 묻는 학생이 항상 있습니다.
그렇다면 "다양한 테스트 사례를 시도하십시오"휴리스틱을 어떻게 속이겠습니까? 이 휴리스틱이 충분하지 않다는 것을 보여줄 좋은 예를 찾고 있습니다. 다시 말해서, 나는 그것이 겉으로는 정확할 것으로 보이는 알고리즘의 하나 이상의 예를 찾고 있으며, 누군가가 생각해 낼 수있는 모든 작은 입력에 대해 올바른 답을 출력하지만 알고리즘이 실제로 어디에 작동하지 않습니다. 알고리즘은 모든 작은 입력에서 올바르게 작동하고 큰 입력에서만 실패하거나 특이한 패턴의 입력에서만 실패 할 수 있습니다.
특히, 나는 찾고 있습니다 :
알고리즘. 결함은 알고리즘 수준이어야합니다. 구현 버그를 찾고 있지 않습니다. 예를 들어 최소한 예제는 언어에 구애받지 않아야하며 결함은 소프트웨어 엔지니어링 또는 구현 문제보다는 알고리즘 문제와 관련이 있어야합니다.
누군가가 그럴듯하게 생각 해낼 수있는 알고리즘. 의사 코드는 최소한 그럴듯하게 보일 것입니다 (예 : 난독 화되거나 명백하게 모호한 코드는 좋은 예가 아닙니다). 숙제 나 시험 문제를 해결하려고 할 때 일부 학생이 실제로 만든 알고리즘 인 경우 보너스 포인트.
확률이 높은 합리적인 수동 테스트 전략을 통과하는 알고리즘입니다. 손으로 몇 가지 작은 테스트 사례를 시도하는 사람은 결함을 발견하지 못할 것입니다. 예를 들어, "수십 개의 작은 테스트 사례에서 수작업으로 QuickCheck 시뮬레이션"은 알고리즘이 잘못되었음을 나타내지 않을 것입니다.
바람직하게는 결정적 알고리즘이다. 많은 학생들이 "수동으로 일부 테스트 사례를 시험해 보는 것"이 결정 론적 알고리즘이 올바른지 확인하는 합리적인 방법이라고 생각하지만 대부분의 학생들은 몇 가지 테스트 사례를 시도하는 것이 확률론을 검증하는 좋은 방법이라고 생각하지 않을 것입니다 알고리즘. 확률 알고리즘의 경우 특정 출력이 올바른지 여부를 알 수있는 방법이없는 경우가 많습니다. 출력 분포에 대한 유용한 통계 테스트를 수행하기에 충분한 예제를 수동으로 크랭크 할 수 없습니다. 따라서 결정 론적 알고리즘에 중점을두기를 원합니다. 학생들의 오해의 중심에 더 명확하게 도달하기 때문입니다.
알고리즘의 정확성을 증명하는 것이 중요하다는 것을 가르치고 싶습니다. 정확성 증명에 동기를 부여하기 위해 이와 같은 몇 가지 예를 사용하고 싶습니다. 학부생들이 비교적 간단하고 접근 할 수있는 사례를 선호합니다. 중장비 또는 많은 수학적 / 알고리즘 배경이 필요한 예는 그다지 유용하지 않습니다. 또한 "부 자연스러운"알고리즘을 원하지 않습니다. 휴리스틱을 속이는 이상한 인공 알고리즘을 구성하는 것이 쉽지만, 매우 부자연 스럽거나이 휴리스틱을 속이는 것으로 명확한 백도어가 있다면 학생들에게 설득력이 없을 것입니다. 좋은 예가 있습니까?