Tất cả các câu trả lời khác là chính xác, tôi chỉ muốn sửa đổi như sau. Tôi muốn xem, nếu việc giảm các lần thực hiện của vòng lặp k bên trong là đủ để giảm độ phức tạp thực tế bên dưới O(n⁴).
Vì vậy tôi đã viết như sau:
for (int n = 1; n < 363; ++n) {
int sum = 0;
for(int i = 1; i < n; ++i) {
for(int j = 1; j < i * i; ++j) {
if(j % i == 0) {
for(int k = 0; k < j; ++k) {
sum++;
}
}
}
}
long cubic = (long) Math.pow(n, 3);
long hypCubic = (long) Math.pow(n, 4);
double relative = (double) (sum / (double) hypCubic);
System.out.println("n = " + n + ": iterations = " + sum +
", n³ = " + cubic + ", n⁴ = " + hypCubic + ", rel = " + relative);
}
Sau khi thực hiện điều này, nó trở nên rõ ràng, rằng sự phức tạp là trên thực tế n⁴
. Các dòng đầu ra cuối cùng trông như thế này:
n = 356: iterations = 1989000035, n³ = 45118016, n⁴ = 16062013696, rel = 0.12383254507467704
n = 357: iterations = 2011495675, n³ = 45499293, n⁴ = 16243247601, rel = 0.12383580700180696
n = 358: iterations = 2034181597, n³ = 45882712, n⁴ = 16426010896, rel = 0.12383905075183874
n = 359: iterations = 2057058871, n³ = 46268279, n⁴ = 16610312161, rel = 0.12384227647628734
n = 360: iterations = 2080128570, n³ = 46656000, n⁴ = 16796160000, rel = 0.12384548432498857
n = 361: iterations = 2103391770, n³ = 47045881, n⁴ = 16983563041, rel = 0.12384867444612208
n = 362: iterations = 2126849550, n³ = 47437928, n⁴ = 17172529936, rel = 0.1238518469862343
Điều này cho thấy, sự khác biệt tương đối thực tế giữa thực tế n⁴
và độ phức tạp của đoạn mã này là một yếu tố tiệm cận đối với một giá trị xung quanh 0.124...
(thực tế là 0,125). Mặc dù nó không cung cấp cho chúng tôi giá trị chính xác, chúng tôi có thể suy luận như sau:
Thời gian phức tạp là n⁴/8 ~ f(n)
nơi f
chức năng / phương pháp của bạn.
- Trang wikipedia về ký hiệu Big O nêu trong các bảng của 'Gia đình Bachmann dòng Landau' rằng
~
định nghĩa giới hạn của hai mặt toán hạng là bằng nhau. Hoặc là:
f bằng g tiệm cận
(Tôi đã chọn 363 là giới hạn trên bị loại trừ, vì n = 362
là giá trị cuối cùng mà chúng tôi nhận được kết quả hợp lý. Sau đó, chúng tôi vượt quá không gian dài và giá trị tương đối trở thành âm.)
Người dùng kaya3 đã tìm ra những điều sau đây:
Hằng số tiệm cận là chính xác 1/8 = 0,125; đây là công thức chính xác thông qua Wolfram Alpha .
for (j = i; j < i *i; j += i)
sau đó bạn không cần kiểm tra mô đun (vìj
được đảm bảo chia hết choi
).