Làm thế nào để biết ký hiệu phân tích độ phức tạp thời gian sẽ sử dụng?


90

Trong hầu hết các lớp giải thuật giới thiệu, ký hiệu như (Big O) và ΘOΘ được giới thiệu, và một sinh viên thường sẽ học cách sử dụng một trong những để tìm sự phức tạp thời gian.

Tuy nhiên, có ký hiệu khác, chẳng hạn như , Ωω . Có kịch bản cụ thể nào mà một ký hiệu sẽ thích hợp hơn một ký hiệu khác không?oΩω


2
nó không được ưa thích nhiều như được áp dụng ...
vzn

Câu trả lời:


76

Bạn đang đề cập đến ký hiệu Landau . Chúng không phải là biểu tượng khác nhau cho cùng một thứ nhưng có ý nghĩa hoàn toàn khác nhau. Cái nào là "thích hợp" phụ thuộc hoàn toàn vào câu lệnh mong muốn.

có nghĩa là f phát triển nhanh nhất là g , không có triệu chứng và lên đến một yếu tố không đổi; nghĩ về nó như một . f o ( g ) là dạng chặt chẽ hơn, tức là < .fO(g)fgfo(g)<

có ý nghĩa đối xứng: f tăng trưởng ít nhất càng nhanh càng g . ω là anh em họ khắt khe hơn của nó. Bạn có thể thấy rằng f Ohm ( g ) tương đương với g O ( f ) .fΩ(g)fgωfΩ(g)gO(f)

có nghĩa là f phát triển về càng nhanh càng g ; chính thức f O ( g ) Ohm ( g ) . f g (đẳng thức tiệm cận) là dạng mạnh hơn của nó. Chúng ta thường có nghĩa là Θ khi chúng tôi sử dụng OfΘ(g)fgfO(g)Ω(g)fgΘO .

Lưu ý cách và anh chị em của nó là các lớp chức năngO(g) . Điều quan trọng là phải rất ý thức về điều này và các định nghĩa chính xác của họ - có thể khác nhau tùy thuộc vào người đang nói chuyện - khi thực hiện "arithologists" với họ.

Khi chứng minh mọi thứ, hãy cẩn thận để làm việc với định nghĩa chính xác của bạn. Có nhiều định nghĩa cho các biểu tượng Landau xung quanh (tất cả đều có cùng trực giác cơ bản), một số định nghĩa tương đương trên một số bộ trên các chức năng nhưng không phải trên các bộ khác.

Cách đọc được đề nghị:

Nếu bạn quan tâm đến việc sử dụng ký hiệu Landau một cách nghiêm ngặt và hợp lý, bạn có thể quan tâm đến công việc gần đây của Rutanen et al. [1]. Chúng xây dựng các tiêu chí cần và đủ cho ký hiệu tiệm cận khi chúng ta sử dụng chúng trong thuật toán, cho thấy định nghĩa chung không đáp ứng chúng và cung cấp một định nghĩa khả thi (trên thực tế).


  1. Một định nghĩa chung về ký hiệu O để phân tích thuật toán của K. Rutanen et al. (2015)

5
Tôi chỉ muốn chỉ ra rằng mặc dù hoạt động như Ω hoạt động như , có sự khác biệt; nó không phải là khó để tìm thấy chức năng gff O ( g )f Ohm ( g ) . OΩgffO(g)fΩ(g)
Zach Langley

1
+1 cho việc đề cập đến các lớp chức năng. Stuff như Ω ( 2 n ) xuất hiện ở khắp mọi nơi trong các giấy tờ, sổ sách, mà có thể gây nhầm lẫn cho người dân phải đối mặt với những ký hiệu cho lần đầu tiên. o(1)Ω(2n)
Janoma

7
@ZachLangley Những gì bạn nói là rất đúng. Không có tổng số thứ tự ở đây. Nó có lẽ là nguy hiểm để đưa lên ở tất cả, nhưng tôi nghĩ rằng nó phục vụ mục đích xây dựng trực giác.
Raphael

42

Big O: giới hạn trên

Cung điện lớn O O ( O ) đến nay là một phổ biến nhất. Khi bạn phân tích độ phức tạp của một thuật toán, hầu hết thời gian, điều quan trọng là có một số giới hạn trên về thời gian chạy nhanh như thế nào khi kích thước của đầu vào tăng lên. Về cơ bản, chúng tôi muốn biết rằng việc chạy thuật toán sẽ không mất nhiều thời gian. Chúng ta không thể biểu thị điều này theo đơn vị thời gian thực tế (giây), bởi vì điều đó phụ thuộc vào việc triển khai chính xác (cách viết chương trình, trình biên dịch tốt như thế nào, tốc độ của bộ xử lý của máy, tốc độ). Vì vậy, chúng tôi đánh giá những gì không phụ thuộc vào các chi tiết như vậy, đó là mất bao lâu để chạy thuật toán khi chúng tôi cung cấp cho đầu vào lớn hơn. Và chúng tôi chủ yếu quan tâm khi chúng tôi có thể chắc chắn rằng chương trình đã được thực hiện, vì vậy chúng tôi thường muốn biết rằng nó sẽ mất nhiều thời gian như vậy hoặc ít hơn.

Để nói rằng một thuật toán có thời gian chạy là cho kích thước đầu vào n có nghĩa là tồn tại một số K không đổi để thuật toán hoàn thành tối đa KO(f(n))nK các bước, tức là thời gian chạy của thuật toán tăng nhanh nhất là f (lên đến một hệ số tỷ lệ). Ghi nhận T ( n ) thời gian chạy của thuật toán cho kích thước đầu vào n , O ( n ) chính thức có nghĩa là T ( n ) f ( n ) lên đến một số yếu tố rộng.Kf(n)fT(n)nO(n)T(n)f(n)

Chặn dưới

Đôi khi, thật hữu ích khi có nhiều thông tin hơn giới hạn trên. là converse của O : nó biểu thị rằng một hàm phát triển ít nhất nhanh như hàm khác. T ( n ) = Ω ( g ( n ) ) có nghĩa là T ( N ) K ' g ( n ) đối với một số không đổi K ' , hoặc đặt nó không chính thức, T ( n ) g ( n ) lên đến một số nhân rộng hệ số.ΩOT(n)=Ω(g(n))T(N)Kg(n)KT(n)g(n)

Khi thời gian chạy của thuật toán có thể được xác định chính xác, kết hợp OΩ : nó biểu thị rằng tốc độ tăng trưởng của một hàm đã biết, cho đến một hệ số tỷ lệ. T ( n ) = Θ ( h ( n ) ) có nghĩa là K h ( n ) T ( n ) K ' h ( n ) đối với một số hằng số KK ' . Nói một cách không chính thức, T (ΘOΩT(n)=Θ(h(n))Kh(n)T(n)Kh(n)KK lên đến một số yếu tố rộng.T(n)h(n)

Cân nhắc thêm

Các “nhỏ” ω được sử dụng ít thường trong phân tích phức tạp. Ít o mạnh hơn O lớn ; Trong đó O chỉ ra sự tăng trưởng không nhanh hơn, o chỉ ra rằng sự tăng trưởng đó hoàn toàn chậm hơn. Ngược lại, ω cho thấy tốc độ tăng trưởng nhanh hơn đúng.oωoOOoω

Tôi đã hơi không chính thức trong các cuộc thảo luận ở trên. Wikipedia có định nghĩa formall và một cách tiếp cận toán học hơn.

Hãy nhớ rằng việc sử dụng dấu bằng trong và tương tự là một cách viết sai. Nói đúng ra, O ( f ( n ) ) là một tập hợp các hàm của biến n và chúng ta nên viết T O ( f ) .T(n)=O(f(n))O(f(n))nTO(f)

Ví dụ: một số thuật toán sắp xếp

Vì điều này khá khô khan, hãy để tôi đưa ra một ví dụ. Hầu hết các thuật toán sắp xếp có thời gian chạy trường hợp xấu nhất bậc hai, tức là đối với đầu vào có kích thước , thời gian chạy của thuật toán là O ( n 2 ) . Ví dụ, sắp xếp lựa chọn có thời gian chạy O ( n 2 ) , vì việc chọn phần tử thứ k yêu cầu so sánh n - k , với tổng số so sánh n ( n - 1 ) / 2 . Trong thực tế, số lượng so sánh luôn luôn chính xác n ( n -nO(n2)O(n2)knkn(n1)/2 , phát triển thành n 2 . Vì vậy, chúng ta có thể chính xác hơn về độ phức tạp thời gian của sắp xếp lựa chọn: đó là Θ ( n 2 ) .n(n1)/2n2Θ(n2)

Bây giờ hãy sắp xếp hợp nhất . Hợp nhất sắp xếp cũng là bậc hai ( ). Điều này đúng, nhưng không chính xác lắm. Hợp nhất sắp xếp trong thực tế có thời gian chạy O ( nO(n2) trong trường hợp xấu nhất. Giống như sắp xếp lựa chọn, luồng công việc của sắp xếp hợp nhất về cơ bản không phụ thuộc vào hình dạng của đầu vào và thời gian chạy của nó luôn là nO(nlg(n)) lên đến một yếu tố chất nhân không đổi, tức là nó là Θ ( nnlg(n) .Θ(nlg(n))

Tiếp theo, hãy xem xét quicksort . Quicksort phức tạp hơn. Nó chắc chắn là . Hơn nữa, trường hợp xấu nhất của quicksort là bậc hai: các trường hợp xấu nhấtΘ ( n 2 ) . Tuy nhiên, trường hợp tốt nhất của quicksort (khi đầu vào đã được sắp xếp) là tuyến tính: tốt nhất chúng ta có thể nói cho một ràng buộc thấp hơn để quicksort nói chung là Ω ( n ) . Tôi sẽ không lặp lại chứng tại đây, nhưng trung bình độ phức tạp của quicksort (tỷ lệ trung bình thực hiện trên tất cả các hoán vị có thể của đầu vào) là Θ ( nO(n2)Θ(n2)Ω(n) .Θ(nlg(n))

Có kết quả chung về sự phức tạp của các thuật toán sắp xếp trong các cài đặt chung. Giả sử rằng một thuật toán sắp xếp chỉ có thể so sánh hai yếu tố tại một thời điểm, với kết quả có hoặc không ( hoặc x > y ). Sau đó, rõ ràng là thời gian chạy của thuật toán sắp xếp luôn luôn là Ω ( n ) (trong đó n là số phần tử cần sắp xếp), bởi vì thuật toán phải so sánh mọi phần tử ít nhất một lần để biết nó sẽ phù hợp ở đâu. Giới hạn dưới này có thể được đáp ứng, ví dụ, nếu đầu vào đã được sắp xếp và thuật toán chỉ so sánh từng phần tử với phần tử tiếp theo và giữ chúng theo thứ tự (đó là n - 1xyx>yΩ(n)nn1so sánh). Điều ít rõ ràng hơn là thời gian chạy tối đa nhất thiết phải là . Có thể thuật toán đôi khi sẽ tạo ra các phép so sánh ít hơn, nhưng phải có một số K không đổisao cho với bất kỳ kích thước đầu vào n nào , có ít nhất một đầu vào mà thuật toán tạo ra nhiều hơn so sánh so với K n l g ( n ) . Ý tưởng của bằng chứng là xây dựng cây quyết định của thuật toán, tức là tuân theo các quyết định mà thuật toán lấy từ kết quả của mỗi so sánh. Vì mỗi so sánh trả về kết quả có hoặc không, cây quyết định là cây nhị phân. Có n !Ω(nlg(n))KnKnlg(n)n!hoán vị có thể có của đầu vào và thuật toán cần phân biệt giữa tất cả chúng, vì vậy kích thước của cây quyết định là . Kể từ khi cây là một cây nhị phân, phải mất độ sâu Θ ( l g ( n ! ) ) = Θ ( nn! để phù hợp với tất cả các nút. Độ sâu là số lượng tối đa các quyết định rằng các thuật toán mất, vì vậy chạy các thuật toán liên quan đến ít nhất này nhiều so sánh: thời gian chạy tối đa là Ω ( nΘ(lg(n!))=Θ(nlg(n)) .Ω(nlg(n))

¹ Hoặc tiêu thụ tài nguyên khác như không gian bộ nhớ. Trong câu trả lời này, tôi chỉ xem xét thời gian chạy.


1
"Tuy nhiên, trường hợp tốt nhất của quicksort (khi đầu vào đã được sắp xếp) là tuyến tính" đây là trường hợp xấu nhất !!
dùng5507

@ user5507: Trên thực tế, nó phụ thuộc vào chiến lược xoay vòng. Nếu phần tử đầu tiên (hoặc cuối cùng) được chọn làm trục, thì bạn đã đúng; nhưng nếu bạn chọn phần tử ở giữa hoặc trung vị của đầu tiên, giữa, cuối cùng, thì đầu vào được sắp xếp là trường hợp tốt nhất.
chirlu

"Ít o và little được sử dụng ít thường xuyên hơn trong phân tích độ phức tạp." Điều này không đúng trong phân tích độ phức tạp không gian. Trong phân tích độ phức tạp thời gian, bạn thường sử dụng o và ω khi bạn đang đếm các thao tác cụ thể (so sánh, tìm kiếm đĩa, bỏ lỡ bộ đệm, những gì có bạn). Nhưng vì bạn luôn có thể chờ đợi và mua một máy tính nhanh hơn, "thời gian treo tường" luôn luôn "lên đến một yếu tố không đổi", vì vậy big-O phổ biến hơn nhiều. Trong phân tích không gian, thường có giới hạn dưới cứng vì lý thuyết thông tin, do đó, rất phổ biến để xem kích thước được báo cáo là "f (n) + o (f (n)) bit" trong đó f (n) là giới hạn dưới.
Bút danh

Trong khi tôi nghĩ về nó: Nếu f (n) là lý thuyết thấp hơn ràng buộc vào kích thước của một số cấu trúc dữ liệu, thì một cấu trúc sử dụng f (n) + O (1) (chi phí không đổi) được gọi là "ẩn", một sử dụng f (n) + O (f (n)) (chi phí tương đối không đổi) được gọi là "compact" và một công cụ sử dụng f (n) + o (f (n)) (chi phí tương đối cuối cùng trở nên không đáng kể) được gọi là "cô đọng" ". Điều khoản tốt để biết nếu bạn cần phải làm việc trong không gian đó.
Bút danh

17

Điển hình là được sử dụng để nêu trên bên vọt (ước tính từ trên cao), trong khi Ω được sử dụng để ghi-cận dưới (ước tính từ bên dưới), và Θ được sử dụng khi chúng phù hợp, trong trường hợp này bạn có thể sử dụng Θ ở vị trí của họ (thường) để nêu kết quả.OΩΘΘ


3
Thông thường thì sao? Chúng có thể được sử dụng cho cái gì khác?
Svick

1
@svick, vâng, vd: không phải là một câu lệnh giới hạn trên. Theo một câu lệnh giới hạn trên, tôi có nghĩa là một cái gì đó như f = O ( g ) thể hiện giới hạn trên của f . P=DTime(nO(1))f=O(g)f
Kaveh

4
Thật ra, Kaveh, đó một tuyên bố ràng buộc trên. Bản dịch tiếng Anh propoer của " " là "P là tập hợp các vấn đề có thể được giải quyết bằng cách sử dụng AT MOST một số phép toán đa thức". Nếu bạn không có nghĩa là "nhiều nhất", bạn nên viết P = D T i m eP=DTime(nO(1)) . (Tất cả các tuyên bố đều đúng, tất nhiên.)P=DTime(nΘ(1))
JeffE

@JeffE, tôi nghĩ về nó như một sự bình đẳng giữa các bộ hàm, nhưng bạn nói đúng, người ta cũng có thể nghĩ về nó như một giới hạn trên theo nghĩa chung hơn.
Kaveh

@JeffE Trên thực tế, , kể từ D T I M E ( Θ ( n log n ) ) P nhưng D T I M E ( Θ ( nPCƯỜI MỞ MIỆNGTTôiME(viết sai rồiΘ(1))CƯỜI MỞ MIỆNGTTôiME(Θ(viết sai rồiđăng nhậpviết sai rồi))P . CƯỜI MỞ MIỆNGTTôiME(Θ(viết sai rồiđăng nhậpviết sai rồi))CƯỜI MỞ MIỆNGTTôiME(viết sai rồiΘ(1))= =
David Richerby
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.