Đôi khi tôi thấy (n) với biểu tượng strange lạ với một cái gì đó ở giữa nó, và đôi khi chỉ là O (n). Có phải chỉ là sự lười biếng khi gõ bởi vì không ai biết cách gõ biểu tượng này, hoặc nó có nghĩa gì khác?
Đôi khi tôi thấy (n) với biểu tượng strange lạ với một cái gì đó ở giữa nó, và đôi khi chỉ là O (n). Có phải chỉ là sự lười biếng khi gõ bởi vì không ai biết cách gõ biểu tượng này, hoặc nó có nghĩa gì khác?
Câu trả lời:
Nếu một thuật toán là (g (n)), điều đó có nghĩa là thời gian chạy của thuật toán khi n (kích thước đầu vào) lớn hơn tỷ lệ thuận với g (n).
Nếu một thuật toán là O (g (n)), nó có nghĩa là thời gian chạy của thuật toán như n được lớn hơn là nhiều nhất là tỷ lệ thuận với g (n).
Thông thường, ngay cả khi mọi người nói về O (g (n)) họ thực sự có nghĩa là Θ (g (n)) nhưng về mặt kỹ thuật, có một sự khác biệt.
O (n) đại diện cho giới hạn trên. (N) có nghĩa là ràng buộc chặt chẽ. (N) đại diện cho giới hạn dưới.
f (x) = Θ (g (x)) iff f (x) = O (g (x)) và f (x) = Ω (g (x))
Về cơ bản khi chúng ta nói một thuật toán là của O (n), thì nó cũng là O (n 2 ), O (n 1000000 ), O (2 n ), ... nhưng thuật toán (n) không phải là Θ (n 2 ) .
Trong thực tế, vì f (n) = Θ (g (n)) có nghĩa là cho các giá trị đủ lớn của n, f (n) có thể được ràng buộc trong phạm vi c 1 g (n) và c 2 g (n) cho một số giá trị của c 1 và c 2 , tức là tốc độ tăng trưởng của f là tiệm tương đương với g: g có thể được một ràng buộc thấp và và một trên ràng buộc của f. Điều này trực tiếp ngụ ý f có thể là giới hạn dưới và giới hạn trên của g là tốt. Hậu quả là,
f (x) = Θ (g (x)) iff g (x) = Θ (f (x))
Tương tự, để hiển thị f (n) = (g (n)), đủ để hiển thị g là giới hạn trên của f (tức là f (n) = O (g (n))) và f là giới hạn dưới của g (tức là f (n) = Ω (g (n)) là điều tương tự chính xác như g (n) = O (f (n))). Chính xác,
f (x) = Θ (g (x)) iff f (x) = O (g (x)) và g (x) = O (f (x))
Ngoài ra còn có các ω
ký hiệu little-oh và little-omega ( ) đại diện cho giới hạn trên và dưới lỏng lẻo của một chức năng.
Để tóm tắt:
f(x) = O(g(x))
(big-oh) có nghĩa là tốc độ tăng trưởng củaf(x)
tiệm cận nhỏ hơn hoặc bằng với tốc độ tăng trưởng củag(x)
.
f(x) = Ω(g(x))
(big-omega) có nghĩa là tốc độ tăng trưởng của khôngf(x)
có triệu chứng lớn hơn hoặc bằng tốc độ tăng trưởng củag(x)
f(x) = o(g(x))
(little-oh) có nghĩa là tốc độ tăng trưởng của khôngf(x)
có triệu chứng thấp hơn tốc độ tăng trưởng củag(x)
.
f(x) = ω(g(x))
(little-omega) có nghĩa là tốc độ tăng trưởng của khôngf(x)
có triệu chứng lớn hơn tốc độ tăng trưởng củag(x)
f(x) = Θ(g(x))
(theta) có nghĩa là tốc độ tăng trưởng củaf(x)
tiệm cận bằng với tốc độ tăng trưởng củag(x)
Để thảo luận chi tiết hơn, bạn có thể đọc định nghĩa trên Wikipedia hoặc tham khảo sách giáo khoa cổ điển như Giới thiệu về thuật toán của Cormen et al.
>= \Omega(...)
nghĩa là gì? Tôi hiểu nếu chúng ta nói nó là thành viên của \Omega(...)
, nhưng nếu nó lớn hơn nó? Nó có ý nghĩa gì?
Có một cách đơn giản (một mẹo, tôi đoán vậy) để nhớ ký hiệu nào có nghĩa là gì.
Tất cả các ký hiệu Big-O có thể được coi là có một thanh.
Khi nhìn vào một, thanh nằm ở dưới cùng, vì vậy nó là một giới hạn dưới (tiệm cận).
Khi nhìn vào một, thanh rõ ràng là ở giữa. Vì vậy, nó là một (không triệu chứng) ràng buộc chặt chẽ.
Khi viết tay O, bạn thường hoàn thành ở trên cùng và vẽ một hình vuông. Do đó O (n) là giới hạn trên của hàm. Công bằng mà nói, cái này không hoạt động với hầu hết các phông chữ, nhưng nó là sự biện minh ban đầu của các tên.
một là "O" lớn
một là Big Theta
http://en.wikipedia.org/wiki/Big_O_notation
Big O có nghĩa là thuật toán của bạn sẽ thực thi không quá các bước so với biểu thức đã cho (n ^ 2)
Omega lớn có nghĩa là thuật toán của bạn sẽ thực hiện không ít bước hơn trong biểu thức đã cho (n ^ 2)
Khi cả hai điều kiện đều đúng cho cùng một biểu thức, bạn có thể sử dụng ký hiệu theta lớn ....
Thay vì cung cấp một định nghĩa lý thuyết, đã được tóm tắt rất hay ở đây, tôi sẽ đưa ra một ví dụ đơn giản:
Giả sử thời gian chạy f(i)
là O(1)
. Dưới đây là một đoạn mã có thời gian chạy tiệm cận Θ(n)
. Nó luôn gọi hàm f(...)
n
lần. Cả giới hạn dưới và giới hạn trên là n.
for(int i=0; i<n; i++){
f(i);
}
Đoạn mã thứ hai dưới đây có thời gian chạy tiệm cận của O(n)
. Nó gọi hàm f(...)
nhiều n
lần. Giới hạn trên là n, nhưng giới hạn dưới có thể Ω(1)
hoặc Ω(log(n))
, tùy thuộc vào những gì xảy ra bên trong f2(i)
.
for(int i=0; i<n; i++){
if( f2(i) ) break;
f(i);
}
Θ(n)
sẽ tăng tuyến tính khi n tăng, ví dụ thời gian chạy T có thể được biểu thị là T (n) = a * n + b. Đối với các giá trị nhỏ của n (ví dụ n = 1 hoặc 2), đây có thể không phải là cách tốt nhất để mô tả hành vi - có lẽ bạn có một số mã khởi tạo mất nhiều thời gian hơn f (i).
Theta là một cách viết tắt để đề cập đến một tình huống đặc biệt trong đó chữ O và Omega lớn giống nhau.
Vì vậy, nếu một người tuyên bố The Theta is expression q
, thì họ cũng nhất thiết phải yêu cầu điều đó Big O is expression q
và Omega is expression q
.
Tương tự thô:
Nếu: Theta tuyên bố, "Con vật đó có 5 chân." sau đó nó nói rằng: Big O là đúng ("Con vật đó có ít hơn hoặc bằng 5 chân.") và Omega là đúng ("Con vật đó có nhiều hơn hoặc bằng 5 chân.")
Đây chỉ là một sự tương tự thô vì các biểu thức không nhất thiết là các số cụ thể, mà thay vào đó là các hàm có độ lớn khác nhau như log (n), n, n ^ 2, (v.v.).
Một biểu đồ có thể làm cho các câu trả lời trước dễ hiểu hơn:
Bằng tiếng Anh,
Ở bên trái, lưu ý rằng có một giới hạn trên và giới hạn dưới là cả hai cùng một thứ tự cường độ (tức là g (n) ). Bỏ qua các hằng số, và nếu giới hạn trên và giới hạn dưới có cùng độ lớn, người ta có thể nói f (n) = (g (n)) hoặc f (n) nằm trong theta lớn của g (n) .
Bắt đầu với bên phải, ví dụ đơn giản hơn, nó nói rằng g (n) giới hạn trên chỉ đơn giản là thứ tự cường độ và bỏ qua hằng số c (giống như tất cả các ký hiệu O lớn làm).
f(n)
thuộc về O(n)
nếu tồn tại tích cực k
nhưf(n)<=k*n
f(n)
thuộc về Θ(n)
nếu tồn tại tích cực k1
, k2
nhưk1*n<=f(n)<=k2*n
Hãy xem xét f(n) > 0
và g(n) > 0
cho tất cả n
. Bạn có thể cân nhắc điều này vì thuật toán thực nhanh nhất có ít nhất một thao tác và hoàn thành việc thực hiện sau khi bắt đầu. Điều này sẽ đơn giản hóa phép tính, bởi vì chúng ta có thể sử dụng giá trị ( f(n)
) thay vì giá trị tuyệt đối ( |f(n)|
).
f(n) = O(g(n))
Chung:
f(n)
0 ≤ lim ──────── < ∞
n➜∞ g(n)
Dành cho g(n) = n
:
f(n)
0 ≤ lim ──────── < ∞
n➜∞ n
Ví dụ:
Expression Value of the limit
------------------------------------------------
n = O(n) 1
1/2*n = O(n) 1/2
2*n = O(n) 2
n+log(n) = O(n) 1
n = O(n*log(n)) 0
n = O(n²) 0
n = O(nⁿ) 0
Counterexamples:
Expression Value of the limit
-------------------------------------------------
n ≠ O(log(n)) ∞
1/2*n ≠ O(sqrt(n)) ∞
2*n ≠ O(1) ∞
n+log(n) ≠ O(log(n)) ∞
f(n) = Θ(g(n))
Chung:
f(n)
0 < lim ──────── < ∞
n➜∞ g(n)
Dành cho g(n) = n
:
f(n)
0 < lim ──────── < ∞
n➜∞ n
Ví dụ:
Expression Value of the limit
------------------------------------------------
n = Θ(n) 1
1/2*n = Θ(n) 1/2
2*n = Θ(n) 2
n+log(n) = Θ(n) 1
Counterexamples:
Expression Value of the limit
-------------------------------------------------
n ≠ Θ(log(n)) ∞
1/2*n ≠ Θ(sqrt(n)) ∞
2*n ≠ Θ(1) ∞
n+log(n) ≠ Θ(log(n)) ∞
n ≠ Θ(n*log(n)) 0
n ≠ Θ(n²) 0
n ≠ Θ(nⁿ) 0
Kết luận: chúng tôi coi O lớn, lớn và lớn Ω là điều tương tự.
Tại sao? Tôi sẽ nói lý do dưới đây:
Đầu tiên, tôi sẽ làm rõ một tuyên bố sai, một số người nghĩ rằng chúng tôi chỉ quan tâm đến sự phức tạp thời gian tồi tệ nhất, vì vậy chúng tôi luôn sử dụng chữ O lớn thay vì lớn. Tôi sẽ nói người đàn ông này là nhảm nhí. Giới hạn trên và dưới được sử dụng để mô tả một chức năng, không được sử dụng để mô tả độ phức tạp thời gian. Hàm thời gian tồi tệ nhất có giới hạn trên và dưới của nó; chức năng thời gian tốt nhất cũng có giới hạn trên và dưới của nó.
Để giải thích rõ ràng mối quan hệ giữa O lớn và lớn θ, trước tiên tôi sẽ giải thích mối quan hệ giữa O lớn và o nhỏ. Từ định nghĩa, chúng ta có thể dễ dàng biết rằng o nhỏ là tập con của chữ O lớn. Ví dụ:
T (n) = n ^ 2 + n, chúng ta có thể nói T (n) = O (n ^ 2), T (n) = O (n ^ 3), T (n) = O (n ^ 4). Nhưng đối với o nhỏ, T (n) = o (n ^ 2) không đáp ứng định nghĩa của o nhỏ. Vậy chỉ T (n) = o (n ^ 3), T (n) = o (n ^ 4) là đúng cho o nhỏ. T dư thừa (n) = O (n ^ 2) là gì? Nó lớn!
Nói chung, chúng ta nói O lớn là O (n ^ 2), khó có thể nói T (n) = O (n ^ 3), T (n) = O (n ^ 4). Tại sao? Bởi vì chúng tôi coi O lớn là lớn θ trong tiềm thức.
Tương tự như vậy, chúng ta cũng coi lớn Ω là lớn θ trong tiềm thức.
Trong một từ, chữ O lớn, lớn θ và lớn Ω không giống nhau từ các định nghĩa, nhưng chúng là cùng một thứ trong miệng và não của chúng ta.