Để thử kiểm tra xem thuật toán cho một số vấn đề có chính xác hay không, điểm khởi đầu thông thường là thử chạy thuật toán bằng tay trên một số trường hợp thử nghiệm đơn giản - thử một vài trường hợp ví dụ, bao gồm một vài trường hợp "góc đơn giản" ". Đây là một heuristic tuyệt vời: đó là một cách tuyệt vời để nhanh chóng loại bỏ nhiều nỗ lực không chính xác đối với một thuật toán và để hiểu được lý do tại sao thuật toán không hoạt động.
Tuy nhiên, khi học thuật toán, một số sinh viên muốn dừng lại ở đó: nếu thuật toán của họ hoạt động chính xác trên một số ví dụ, bao gồm tất cả các trường hợp góc mà họ có thể nghĩ để thử, thì họ kết luận rằng thuật toán phải chính xác. Luôn có một sinh viên hỏi: "Tại sao tôi cần chứng minh thuật toán của mình đúng, nếu tôi có thể thử nó trong một vài trường hợp thử nghiệm?"
Vì vậy, làm thế nào để bạn đánh lừa "thử một loạt các trường hợp thử nghiệm" heuristic? Tôi đang tìm kiếm một số ví dụ tốt để cho thấy rằng heuristic này là không đủ. Nói cách khác, tôi đang tìm kiếm một hoặc nhiều ví dụ về thuật toán nhìn bề ngoài có vẻ đúng và nó đưa ra câu trả lời đúng cho tất cả các đầu vào nhỏ mà bất kỳ ai cũng có thể đưa ra, nhưng thực sự thuật toán không hoạt động. Có thể thuật toán chỉ hoạt động chính xác trên tất cả các đầu vào nhỏ và chỉ thất bại đối với các đầu vào lớn hoặc chỉ thất bại đối với các đầu vào có mẫu bất thường.
Cụ thể, tôi đang tìm kiếm:
Một thuật toán. Lỗ hổng phải ở cấp độ thuật toán. Tôi không tìm kiếm lỗi thực hiện. (Ví dụ, ở mức tối thiểu, ví dụ phải là bất khả tri về ngôn ngữ và lỗ hổng sẽ liên quan đến các mối quan tâm về thuật toán hơn là các vấn đề về kỹ thuật hoặc triển khai phần mềm.)
Một thuật toán mà ai đó có thể đưa ra một cách hợp lý. Mã giả nên nhìn ít nhất là chính xác (ví dụ, mã bị che khuất hoặc rõ ràng không rõ ràng không phải là một ví dụ tốt). Điểm thưởng nếu đó là một thuật toán mà một số học sinh thực sự nghĩ ra khi cố gắng giải bài tập về nhà hoặc bài kiểm tra.
Một thuật toán sẽ vượt qua một chiến lược kiểm tra thủ công hợp lý với xác suất cao. Một số người thử một vài trường hợp thử nghiệm nhỏ bằng tay sẽ không thể phát hiện ra lỗ hổng. Ví dụ: "mô phỏng QuickCheck bằng tay trên hàng tá trường hợp thử nghiệm nhỏ" sẽ không thể tiết lộ rằng thuật toán không chính xác.
Tốt hơn là, một thuật toán xác định. Tôi đã thấy nhiều sinh viên nghĩ rằng "thử một số trường hợp kiểm tra bằng tay" là một cách hợp lý để kiểm tra xem thuật toán xác định có đúng hay không, nhưng tôi nghi ngờ hầu hết các sinh viên sẽ không cho rằng thử một vài trường hợp kiểm tra là một cách tốt để xác minh xác suất thuật toán. Đối với các thuật toán xác suất, thường không có cách nào để biết liệu bất kỳ đầu ra cụ thể nào là chính xác hay không; và bạn không thể quay tay đủ các ví dụ để thực hiện bất kỳ kiểm tra thống kê hữu ích nào về phân phối đầu ra. Vì vậy, tôi muốn tập trung vào các thuật toán xác định, vì chúng trở nên rõ ràng hơn đối với những quan niệm sai lầm của sinh viên.
Tôi muốn dạy tầm quan trọng của việc chứng minh thuật toán của bạn chính xác và tôi hy vọng sẽ sử dụng một vài ví dụ như thế này để giúp thúc đẩy bằng chứng về tính chính xác. Tôi thích các ví dụ tương đối đơn giản và dễ tiếp cận với sinh viên đại học; các ví dụ yêu cầu máy móc hạng nặng hoặc một tấn nền toán học / thuật toán ít hữu ích hơn. Ngoài ra, tôi không muốn các thuật toán "không tự nhiên"; Mặc dù có thể dễ dàng xây dựng một số thuật toán nhân tạo kỳ lạ để đánh lừa heuristic, nếu nó trông rất không tự nhiên hoặc có một cửa hậu rõ ràng được xây dựng chỉ để đánh lừa heuristic này, nó có thể sẽ không thuyết phục được sinh viên. Bất kỳ ví dụ tốt?