Cách tính độ phức tạp của một số giải thuật đơn giản.
QUY TẮC XÁC ĐỊNH ĐỘ PHỨC TẠP
• Độ phức tạp tính toán của giải thuật: O(f(n))
• Việc xác định độ phức tạp tính toán của giải thuật trong thực tế có thể tính bằng một số quy tắc đơn giản sau:
– Quy tắc bỏ hằng số:
T(n) = O(c.f(n)) = O(f(n)) với c là một hằng số dương
– Quy tắc lấy max:
T(n) = O(f(n)+ g(n)) = O(max(f(n), g(n)))
– Quy tắc cộng:
T1(n) = O(f(n)) T2(n) = O(g(n))
T1(n) + T2(n) = O(f(n) + g(n))
– Quy tắc nhân:
Đoạn chương trình có thời gian thực hiện T(n)=O(f(n))
Nếu thực hiện k(n) lần đoạn chương trình với k(n) = O(g(n)) thì độ phức tạp sẽ là O(g(n).f(n))
PHÉP TOÁN TÍCH CỰC (BEST PROXY)
• Trong một thuật toán, ta chú ý đặc biệt đến một phép toán gọi là phép toán tích cực. Đó là phép toán mà số lần thực hiện không ít hơn các phép toán khác
• Ví dụ 1:
s = 0;
for (i=0; i<=n;i++){
p =1;
for (j=1;j<=i;j++)
p=p * x / j;
s = s+p;
}
Phép toán tích cực là p = p * x / j
Số lần thực hiện phép toán này là
0+1+2+…+n = n(n-1)/2 = n2/2 – n/2
=> Vậy độ phức tạp là O(n2/2 – n/2)
= O(n2/2) sử dụng quy tắc lấy max
= O(n2) sử dụng quy tắc bỏ hằng số
• Ví dụ 2:
s = 1; p = 1;
for (i=1;i<=n;i++) {
p = p * x / i;
s = s + p;
}
Phép toán tích cực là p = p * x / i
Số lần thực hiện phép toán là n
=> Vậy độ phức tạp của thuật toán là O(n)
• Ví dụ 3:
s=n*(n-1) /2;
=> Độ phức tạp của thuật toán là O(1), nghĩa là thời gian tính toán không phụ thuộc vào n
• Ví dụ 4:
Thuật toán tính tổng các số từ 1 đến n
s=0;
for (i= 1;i<=n;i++)
s=s+i;
Vòng lặp lặp n lần phép gán s = s+i, nên thời gian tính toán tỉ lệ thuận với n, tức độ phức tạp là O(n).
=> độ phức tạp là O(n)
• Ví dụ 5:
for (i= 1;i<=n;i++) for (j= 1;j<=n;j++) //Lệnh
=> Dùng quy tắc nhân ta có O(n^2) tương tự như vậy ta sẽ có O(n^3), O(n^4).
• Ví dụ 6:
for (i= 1;i<=n;i++) for (j= 1;j<=m;j++)
//Lệnh => Dùng quy tắc nhân ta có O(n*m)
• Ví dụ 7:
for (i= 1;i<=n;i++) //lệnh1 for (j= 1;j<=m;j++) //lệnh 2 => Dùng quy tắc cộng và quy tắc lấy max, sẽ có
O(max (n,m))
• Ví dụ 8:
for (i= 1;i<=n;i++) {
for (u= 1;u<=m;u++)
for (v= 1;v<=n;v++)
//lệnh
for j:= 1 to x do
for k:= 1 to z do
//lệnh
}
=> O(n*max (n*m,x*z))
• Ví dụ 9:
for (i= 1;i<=n;i++)
for (j= 1;j<=m;j++) {
for (k= 1;k<=x;k++)
//lệnh
for (h= 1;h<=y;h++)
//lệnh
}
=> O(n*m* max (x,y))
• Ví dụ 10:
for (i= 1;i<=n;i++)
for (u= 1;u<= m;u++)
for (v= 1;v<=n;v++)
//lệnh
for (j= 1;j<=x;j++)
for (k= 1;k<=z;k++)
//lệnh
=> O(max (m*n^2,x*z))
• Ví dụ 11: Đoạn chương trình tính tổng 2 đa thức
P(x) = xmxm+am-1xm-1+ …+a1x+a0
Q(x) = bnxn+bn-1xn-1+…+b1x+b0
if (m<n) p = m; else p =n;
for (i=0;i<=p;i++)
c[i]=a[i] + b[i];
if (p<m)
for (i=p+1;i<=m;i++) c[i] = a[i];
else
for (i=p+1;i<=n;i++) c[i] = b[i];
while (p>0 && c[p] = 0) p = p-1;
=> Độ phức tạp: O(max(m,n))
• Ví dụ 12: Đoạn chương trình tính tích hai đa thức
P(x) = xmxm+am-1xm-1+ …+a1x+a0
Q(x) = bnxn+bn-1xn-1+…+b1x+b0
p = m+n;
for (i=0;i<=p;i++) c[i] = 0;
for (i=0;i<=m;i++)
for (j=0;j<=n;j++)
c[i+j] = c[i+j] + a[i] + b[j];
=> Độ phức tạp là O(m.n)
Sắp xếp theo chiều tăng của độ phức tạp, các độ phức tạp đặt trên cùng hàng là tương đương
1, 2100
log n
n log n, log (n!)
n2
(log n)log n, nlog(log n)
2n
3n n!
Tôi là Nguyễn Văn Sỹ có 15 năm kinh nghiệm trong lĩnh vực thiết kế, thi công đồ nội thất; với niềm đam mê và yêu nghề tôi đã tạo ra những thiết kếtuyệt vời trong phòng khách, phòng bếp, phòng ngủ, sân vườn… Ngoài ra với khả năng nghiên cứu, tìm tòi học hỏi các kiến thức đời sống xã hội và sự kiện, tôi đã đưa ra những kiến thức bổ ích tại website nhaxinhplaza.vn. Hy vọng những kiến thức mà tôi chia sẻ này sẽ giúp ích cho bạn!