Chỉnh sửa: Sửa đổi lớn trong phiên bản 3.
Vì tôi chưa bao giờ dạy một lớp, tôi không nghĩ rằng tôi có thể yêu cầu bất cứ điều gì một cách thuyết phục về những gì chúng ta nên dạy. Tuy nhiên, đây là những gì tôi nghĩ về nó.
Có những ví dụ tự nhiên trong đó giới hạn của trò lừa bịp như được viết không thể được áp dụng. Ví dụ: giả sử bạn triển khai một vectơ có độ dài biến đổi (như vectơ <T> trong C ++) bằng cách sử dụng một mảng có độ dài cố định với kích thước nhân đôi (nghĩa là mỗi khi bạn sắp vượt quá kích thước của mảng, bạn phân bổ lại mảng lớn gấp đôi so với bây giờ và sao chép tất cả các phần tử). Kích thước S ( n ) của mảng khi chúng ta lưu trữ n phần tử trong vectơ là công suất nhỏ nhất bằng 2 lớn hơn hoặc bằng n . Chúng tôi muốn nói rằng S ( n ) = O ( n ), nhưng sử dụng thủ thuật giới hạn vụng trộm như được viết như định nghĩa sẽ không cho phép chúng tôi làm như vậy vì S ( n) / n dao động dày đặc trong phạm vi [1,2). Điều tương tự áp dụng cho Ω () và Θ ().
Là một vấn đề hơi riêng biệt, khi chúng tôi sử dụng các ký hiệu này để mô tả độ phức tạp của thuật toán, tôi nghĩ rằng định nghĩa của bạn về () đôi khi không thuận tiện (mặc dù tôi đoán rằng định nghĩa đó là phổ biến). Sẽ thuận tiện hơn khi định nghĩa rằng f ( n ) = ( g ( n )) khi và chỉ khi limsup f ( n ) / g ( n )> 0. Điều này là do một số vấn đề không quan trọng đối với vô số giá trị của n ( chẳng hạn như bài toán gia công hoàn hảo trên đồ thị có số n đỉnh là số lẻ ). Điều tương tự áp dụng cho Θ () và ω ().
Do đó, cá nhân tôi thấy rằng các định nghĩa sau đây thuận tiện nhất để sử dụng để mô tả độ phức tạp của thuật toán: cho các hàm f , g : ℕ → > 0 ,
- f ( n ) = o ( g ( n )) khi và chỉ khi limsup f ( n ) / g ( n ) = 0. (Điều này tương đương với lim f ( n ) / g ( n ) = 0.)
- f ( n ) = O ( g ( n )) khi và chỉ khi limsup f ( n ) / g ( n ) <.
- f ( n ) = Θ ( g ( n )) khi và chỉ khi 0 <limsup f ( n ) / g ( n ) <.
- f ( n ) = Ω ( g ( n )) khi và chỉ khi limsup f ( n ) / g ( n )> 0. (Điều này tương đương với f ( n ) không phải là o ( g ( n )).)
- f ( n ) = ω ( g ( n )) khi và chỉ khi limsup f ( n ) / g ( n ) =. (Điều này tương đương với f ( n ) không phải là O ( g ( n )).)
hoặc tương đương,
- f ( n ) = o ( g ( n )) khi và chỉ khi với mọi c > 0, với n đủ lớn , f ( n ) ≤ c ⋅ g ( n ).
- f ( n ) = O ( g ( n )) khi và chỉ khi với một số c > 0, với n đủ lớn , f ( n ) ≤ c ⋅ g ( n ).
- f ( n ) = Θ ( g ( n )) khi và chỉ khi f ( n ) = O ( g ( n )) và f ( n ) = Ω ( g ( n )).
- f ( n ) = Ω ( g ( n )) khi và chỉ khi với một số d > 0, với vô số n , f ( n ) d ⋅ g ( n ).
- f ( n ) = ω ( g ( n )) khi và chỉ khi với mọi d > 0, với vô số n , f ( n ) d ⋅ g ( n ).
Nhưng tôi không biết đây có phải là một thực tế phổ biến hay không. Ngoài ra tôi không biết nếu nó phù hợp cho việc giảng dạy. Vấn đề là đôi khi chúng ta muốn định nghĩa () bằng liminf thay vào đó (như bạn đã làm trong định nghĩa đầu tiên). Ví dụ, khi chúng ta nói, xác suất lỗi của thuật toán ngẫu nhiên này là 2 ( n ) , chúng tôi không có nghĩa là xác suất lỗi nhỏ theo cấp số nhân chỉ trong vô số n !