Chúng ta nên dạy định nghĩa nào về tốc độ tăng trưởng tiệm cận?


35

Khi chúng ta tuân theo các sách giáo khoa hoặc truyền thống tiêu chuẩn, hầu hết chúng ta đều dạy định nghĩa sau đây về ký hiệu big-Oh trong một vài bài giảng đầu tiên của một lớp thuật toán: Có lẽ chúng tôi thậm chí còn đưa ra toàn bộ danh sách với tất cả các bộ lượng hóa của nó:

f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n)).
  1. f=o(g) iff (c>0)(n00)(nn0)(f(n)cg(n))
  2. f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n))
  3. f=Θ(g) iff (c>0)(d>0)(n00)(nn0)(dg(n)f(n)cg(n))
  4. f=Ω(g) iff (d>0)(n00)(nn0)(f(n)dg(n))
  5. f=ω(g) iff (d>0)(n00)(nn0)(f(n)dg(n)) .

Tuy nhiên, vì các định nghĩa này không dễ thực hiện khi chứng minh ngay cả những điều đơn giản như , hầu hết chúng ta nhanh chóng chuyển sang giới thiệu "mánh khóe giới hạn":5nlog4n+nlogn=o(n10/9)

  1. f=o(g) nếu tồn tại và là ,0limnf(n)/g(n)0
  2. lim n f ( n ) / g ( n ) + f=O(g) nếu tồn tại và không ,limnf(n)/g(n)+
  3. lim n f ( n ) / g ( n ) 0 + f=Θ(g) if tồn tại và không phải là hay ,limnf(n)/g(n)0+
  4. f=Ω(g) nếu limnf(n)/g(n) tồn tại và không phải là 0 ,
  5. f=ω(g) nếu limnf(n)/g(n) tồn tại và là + .

Câu hỏi của tôi là:

Nó có phải là một mất mát lớn khi dạy một lớp thuật toán đại học để có các điều kiện giới hạn như các định nghĩa của o , O , Θ , Ωω ? Đó là những gì tất cả chúng ta cuối cùng đều sử dụng và dường như khá rõ ràng với tôi rằng việc bỏ qua các định nghĩa định lượng giúp cuộc sống của mọi người trở nên dễ dàng hơn.

Tôi sẽ quan tâm để biết liệu bạn có gặp phải trường hợp tự nhiên thuyết phục nào trong đó tiêu chuẩn nghĩa thực sự là bắt buộc hay không, và nếu không, liệu bạn có lập luận thuyết phục để giữ chuẩn -định nghĩa trước không. c , n 0c,n0c,n0


1
Thẻ phải thực sự là "giảng dạy" nhưng tôi không thể tìm thấy bất kỳ thẻ liên quan nào và tôi không được phép tạo thẻ mới.
slimton

1
Điều này về cơ bản hấp thụ các bộ định lượng vào định nghĩa giới hạn epsilon-delta. Mối quan tâm duy nhất của tôi là nhiều sinh viên CS chưa phân tích và vì vậy sự hiểu biết về giới hạn của họ chủ yếu là cơ học. Tuy nhiên, để cho phép họ nhanh chóng tính toán, đó là một việc không có trí tuệ.
Per Vognsen

6
Lưu ý rằng hai định nghĩa của bạn về O () không tương đương (cùng một cảnh báo áp dụng cho () và ()). Xét trường hợp f (n) = 2n cho chẵn n và f (n) = 1 cho n lẻ. Là f (n) = O (n)? Tôi thích sử dụng limsup thay vì lim để tôi có thể nói f (n) = (n) trong trường hợp này (mặc dù cả hai định nghĩa của bạn đều không cho phép điều này). Nhưng đây có thể là sở thích cá nhân của tôi (và thậm chí là một thực hành không chuẩn), và tôi chưa bao giờ dạy một lớp.
Tsuyoshi Ito

2
@Tsuyoshi: Tôi nghĩ rằng điểm của "mẹo giới hạn" là nó là điều kiện đủ nhưng không cần thiết cho . (Đối với nó cũng cần thiết.) Ví dụ về hàm dao động không có giới hạn. o ( )O()o()
András Salamon

1
Bạn không nên thay thế ký hiệu by trong mỗi định nghĩa và thuộc tính? Tôi thấy việc sử dụng rất đáng lo ngại khi là một sinh viên. ===
Jeremy

Câu trả lời:


13

Tôi thích dạy định nghĩa ban đầu với định lượng.

IMO, con người thường gặp khó khăn trong việc hiểu các công thức và định nghĩa với hơn hai lần thay thế lượng tử trực tiếp. Giới thiệu định lượng mới có thể làm rõ nghĩa của định nghĩa. Ở đây, hai bộ định lượng cuối cùng chỉ có nghĩa là "cho tất cả n đủ lớn", giới thiệu loại định lượng này có thể giúp ích.

Những hình ảnh tôi vẽ để giải thích các khái niệm này phù hợp hơn với các phiên bản định lượng.

Tôi nghĩ rằng đơn giản hóa giới hạn là hữu ích cho sinh viên kỹ thuật, những người chỉ quan tâm đến việc tính toán tốc độ tăng trưởng, nhưng sẽ không hữu ích cho sinh viên khoa học máy tính. Trong thực tế, sử dụng đơn giản hóa này có thể gây hại nhiều hơn lợi.

Ý tưởng này tương tự như đề xuất rằng chúng tôi sử dụng các quy tắc để tính toán các dẫn xuất (của đa thức, lũy thừa, ..., quy tắc chuỗi, ...) thay cho định nghĩa epsilon-delta của nó, mà IMHO không phải là một ý tưởng hay.


Khái niệm thống trị cuối cùng cũng hữu ích: iff . Bây giờ iff có st . \ es m n > m f ( n ) < g ( n ) f O ( g ) c > 0 f ( x ) c g ( x )f(x)g(x)\esitsmn>mf(n)<g(n)fO(g)c>0f(x)cg(x)
Kaveh

9

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 ) ≤ cg ( n ).
  • f ( n ) = O ( g ( n )) khi và chỉ khi với một số c > 0, với n đủ lớn , f ( n ) ≤ cg ( 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 ) dg ( n ).
  • f ( n ) = ω ( g ( n )) khi và chỉ khi với mọi d > 0, với vô số n , f ( n ) dg ( 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 !


Tôi cũng sử dụng các định nghĩa limsup, nhưng đối với những sinh viên chưa từng thấy limsup (hầu hết tất cả trong số họ) tôi phải mở rộng thành các bộ lượng hóa rõ ràng.
Jeffε

@JeffE: Tôi đồng ý rằng hầu hết các sinh viên chưa thấy limsup, vì vậy nếu chúng ta sử dụng các định nghĩa limsup, chúng ta phải sử dụng các bộ lượng hóa thay vì trong lớp.
Tsuyoshi Ito

2
Vấn đề với các phiên bản định lượng là chúng khó nhớ và hình dung. Tôi thích vì nó có thể được mô tả là "điểm giới hạn cao nhất". Một lời giải thích có thể là: "Nó giống như , ngoại trừ chỉ hoạt động khi chuỗi hội tụ. Ví dụ, nếu chuỗi không hội tụ vì thuật toán dao động giữa rất nhanh đối với và chậm đối với khác , thì chúng ta lấy điểm giới hạn cao nhất. " limsuplimlimnn
Apfelmus Heinrich

Trên thực tế, có bất kỳ ví dụ tự nhiên nào cho các thuật toán trong đó thời gian chạy không dao động?
Apfelmus Heinrich

2
@Heinrich: Tôi đã đề cập đến thời gian chạy của một thuật toán để tìm một kết hợp hoàn hảo của đồ thị trên n đỉnh, nhưng nó có được tính là một ví dụ tự nhiên không? Tôi đã thêm một ví dụ khác trong đó thời gian chạy không dao động nhưng f (n) / g (n) dao động. Ví dụ nói về độ phức tạp không gian, nhưng độ phức tạp thời gian của cùng một ví dụ có cùng thuộc tính.
Tsuyoshi Ito

8

Sử dụng các giới hạn là một chút khó hiểu vì (1) một khái niệm phức tạp hơn (2) nó không nắm bắt được f = O (g) độc đáo (như chúng ta có thể thấy trong cuộc thảo luận ở trên). Tôi thường nói về các chức năng từ các số Tự nhiên (hoàn toàn tích cực) đến các số Tự nhiên (đủ cho thời gian chạy), bỏ qua các công cụ nhỏ, và sau đó định nghĩa ngắn gọn và phù hợp cho sinh viên năm thứ nhất:

Dfn: f = O (g) nếu với một số C cho tất cả n ta có f (n) <= C * g (n)


1
Đầu tiên tôi không thích định nghĩa này bởi vì nói rõ tất cả các n che khuất thực tế quan trọng là ký hiệu O () chỉ quan tâm đến hành vi của các hàm đối với n lớn. Tuy nhiên, bất kể chúng ta chọn định nghĩa nào, tôi đoán rằng chúng ta nên giải thích thực tế này cùng với định nghĩa. Suy nghĩ theo cách đó, nêu định nghĩa đơn giản này có vẻ khá tốt.
Tsuyoshi Ito

Trong khi điều này nắm bắt được bản chất, tôi không thích rằng nếu với tất cả , cho tất cả lên đến và thì ngược lại, sau đó nhưng định nghĩa này không nắm bắt được mối quan hệ này. Vì vậy, người ta phải thêm một số handwaving về các chức năng được hành xử tốt trong một số ý nghĩa. f(n)=nng(n)=0nN0g(n)=f(n)+1f=O(g)
András Salamon

2
Điểm nói về các hàm có phạm vi là các số Tự nhiên (không bao gồm 0) chính xác là không rơi vào các vấn đề với g (n) = 0.
Noam

1
@Warren Victor Shoup trong cuốn sách về Lý thuyết số tính toán sử dụng ký hiệu thay vì trong phân tích thời gian chạy, mà tôi thấy gọn gàng. len(a)loga
Srivatsan Narayaan

1
@Warren (tiếp theo) Đây là cách anh giải thích: "Khi diễn tả thời gian chạy của thuật toán theo đầu vào , chúng tôi thường thích viết hơn là . Một lý do là thẩm mỹ: viết nhấn mạnh thực tế rằng thời gian chạy là một hàm của độ dài bit của . Một lý do khác là về mặt kỹ thuật: đối với các ước tính big- liên quan đến các hàm trên một miền tùy ý, các bất đẳng thức thích hợp sẽ được giữ trong toàn miền và vì lý do này, sẽ rất bất tiện khi sử dụng các hàm, như , biến mất hoặc không được sử dụng trên một số đầu vào. " alen(a)logalen(a)aOlog
Srivatsan Narayaan

5

Khi tôi tham gia các khóa học cơ bản, chúng tôi đã được trao cho điều theo định nghĩa và các công cụ khác như định lý.c,n0

Tôi nghĩ rằng cái đầu tiên là tự nhiên hơn đối với nhiều người nghĩ rời rạc hơn là liên tục, đó là hầu hết các nhà khoa học máy tính (theo kinh nghiệm của tôi). Nó cũng phù hợp với cách chúng ta thường nói về những điều đó tốt hơn: "Có một hàm đa thức bậc 3 là giới hạn trên của này cho đến một yếu tố không đổi."f

Chỉnh sửa : Bạn có thể tiến gần hơn đến cách nói này nếu bạn sử dụng định nghĩa này: (Lưu ý rằng kết nối định nghĩa này với định nghĩa thường được đưa ra)fO(g):⇔c,d>0n0:f(n)cg(n)+dd=f(n0)

Các công cụ giới hạn là khá hữu ích để tính toán các lớp phức tạp, đó là bằng bút và giấy.

Trong mọi trường hợp, tôi nghĩ rằng nó rất hữu ích cho sinh viên để biết rằng có rất nhiều định nghĩa tương đương (hy vọng). Họ sẽ có thể nhận ra điều đó và chọn ra những khác biệt trong trường hợp định nghĩa không tương đương.


4

Đã nghiên cứu những khái niệm này chỉ một vài năm trước đây, chúng không phải là những khái niệm khó nắm bắt nhất đối với lớp học của tôi (trái ngược với các khái niệm như cảm ứng, hoặc tích cực). Theo tôi, giới hạn và giới hạn chỉ "trực quan" hơn đối với những người quen thuộc với tính toán. Nhưng những sinh viên có nền tảng toán học như vậy dù sao cũng sẽ có nền tảng lý thuyết tập hợp, để họ có thể xử lý các vòng loại rời rạc.

Ngoài ra, quan trọng hơn, hãy nhớ rằng cuối cùng các sinh viên của bạn sẽ tiếp tục (hy vọng) đọc các sách giáo khoa lý thuyết cs khác, và thậm chí có thể nghiên cứu một ngày nào đó. Như vậy, tốt hơn là họ nên thoải mái với ký hiệu chuẩn trong lĩnh vực này, ngay cả khi ban đầu nó không được hình thành một cách lý tưởng. Không có hại khi cung cấp cho họ các định nghĩa thay thế, một khi họ đã đồng hóa các định nghĩa chuẩn.


3

Để có một vấn đề thú vị về vấn đề này, hãy xem lá thư được viết độc đáo của Don Knuth "Tính toán qua ký hiệu O" . Ông ủng hộ quan điểm ngược lại rằng tính toán nên được dạy thông qua các ký hiệu 'A', 'O' và 'o'.

Lưu ý: Anh ta sử dụng ký hiệu "A" làm bước sơ bộ trong việc xác định ký hiệu "O" tiêu chuẩn. Một đại lượng là của (tức là ), nếu . Cụ thể, có ý nghĩa khi nói là .A y x = A ( y ) | x | y 100 Một ( 200 )xAyx=A(y)|x|y100A(200)


1
  1. Định nghĩa của Tsuyoshi Ito không hoàn toàn đúng. Đối với ít omega và big-omega, các định nghĩa nên sử dụng liminf, không phải limsup. Định nghĩa của big-theta cần cả giới hạn dưới của liminf và giới hạn trên của limsup.

  2. Một định nghĩa của f (n) = O (g (n)) là tồn tại một hàm khác f '(n)> = f (n) sao cho lim f' (n) / g (n) <vô cùng.

  3. Tại sao người mới được phép đăng câu trả lời nhưng không đưa ra nhận xét?


1
Đối với mục 1, tôi có nghĩa là limsup trong mọi trường hợp và lý do được giải thích trong đoạn thứ hai của câu trả lời của tôi.
Tsuyoshi Ito

Thật không may, đó là một cơ chế chặn thư rác.
Suresh Venkat

Aso, bạn có thể sử dụng latex trong câu trả lời của bạn.
Suresh Venkat

1

Đầu tiên , tôi cố gắng phát triển ở học sinh một số trực giác , trước khi hiển thị các phương trình.

  • "Hợp nhất-sắp xếp so với chèn-sắp xếp" là điểm khởi đầu tốt.

Sau đó, sau đó ... tôi cố gắng thể hiện cả hai cách. Các sinh viên, phụ thuộc nhiều hơn vào trực giác thích trong khi những người phụ thuộc nhiều hơn vào toán học, phương trình, đại số, v.v., họ thích các định nghĩa " ".lim n

f=O(g) iff (c>0)(n00)(nn0)(f(n)cg(n)).
limn

Một khía cạnh khác là, nó phụ thuộc rất nhiều vào chương trình nghiên cứu cụ thể. IMHO tùy thuộc vào các đối tượng trước, một trong những định nghĩa sẽ phù hợp hơn - trong khi IMHO vẫn nên trình bày cả hai và chấp nhận cả hai loại giải pháp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.