Bài giảng cấu trúc dữ liệu và giải thuật phân tích thuật toán nguyễn mạnh hiển

37 8 0
Bài giảng cấu trúc dữ liệu và giải thuật phân tích thuật toán   nguyễn mạnh hiển

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Phân tích thuật tốn (Algorithm Analysis) Nguyễn Mạnh Hiển hiennm@tlu.edu.vn Nội dung Phân tích thuật tốn gì? Các ký hiệu tiệm cận Tốc độ tăng hàm Các ví dụ phân tích thuật tốn Phân tích thuật tốn gì? Phân tích thuật tốn • Nhằm xác định thời gian chạy (độ phức tạp) thuật toán dạng hàm f kích thước đầu vào n − Ví dụ: Thời gian tìm kiếm phần tử x dãy n phần tử f(n) = n (phép so sánh, trường hợp tồi/xấu nhất) • Đơn vị thời gian: − Không phải giờ, phút, giây − Mà thao tác bản; ví dụ: cộng, nhân, so sánh… − Mỗi thao tác có thời gian chạy (một lượng thời gian nhỏ khơng phụ thuộc vào kích thước đầu vào n) Đếm số thao tác • Nhận diện thao tác thuật tốn • Xác định thao tác T chiếm nhiều thời gian chạy so với thao tác lại − Thao tác T thường xuất vịng lặp • Đếm số lần thực thao tác T, thu hàm thời gian chạy f(n) • Chú ý: Trong trường hợp khó tìm thao tác T, đếm tất thao tác Khi đó, thu hàm f’(n)  f(n), áp dụng thêm phép phân tích tiệm cận (học sau) kết cuối giống Ví dụ đếm số thao tác Ví dụ 1: In phần tử (C++) Ví dụ 3: Kiểm tra tính xếp (C++) for (i = 0; i < n; i++) cout cho f(n)  cg(n) n  n0 cg(n) f(n) f(n) bị chặn g(n) theo nghĩa tiệm cận n0 10 Ký hiệu  f(n) = (g(n))  c > n0 > cho cg(n)  f(n) n  n0 f(n) cg(n) n0 f(n) bị chặn g(n) theo nghĩa tiệm cận 23 Các vòng lặp lồng for (i = 0; i < n; i++) { // giả sử có thao tác for (j = 0; j < n; j++) // giả sử có thao tác } • Phân tích vịng lặp từ ngồi: − Vịng lặp bên thực 3n thao tác − Mỗi bước lặp vịng lặp bên ngồi thực + 3n thao tác • Thời gian chạy tổng thể: t(n) = (2 + 3n)n = 3n2 + 2n = O(n2) 24 Câu lệnh if-else if (x > 0) i = 0; else for (j = 0; j < n; j++) a[j] = j; • Có thao tác bản: x > (dòng 1), i = (dòng 2) a[j] = j (dịng 5) • Trong trường hợp tồi nhất, tức điều kiện x > sai: − Phép gán i = chạy lần − Phép gán a[j] = j chạy n lần (vì nằm vịng lặp) • Thời gian chạy trường hợp tồi nhất: t(n) = + n = O(n) 25 Hàm đệ quy long factorial(int n) { if (n 1) = + + t(n – 2) = + + + t(n – 3) = 3k + t(n – k) • Chọn k = n – 1, đó: t(n) = 3(n – 1) + t(1) = 3n – = O(n) 27 Tìm kiếm for (i = 0; i < n; i++) { if (a[i] == x) return i; } return -1; • Trong trường hợp tồi nhất, tức x nằm cuối mảng x khơng có mảng, ta phải thực n phép so sánh a[i] == x • Thời gian chạy trường hợp tồi nhất: t(n) = n = O(n) 28 Tìm kiếm nhị phân • Cho mảng a xếp tăng dần • Tìm x mảng a: − So sánh x với phần tử mảng a[mid] (mid vị trí giữa) − Nếu x < a[mid], tìm x nửa bên trái mảng − Nếu x > a[mid], tìm x nửa bên phải mảng − Nếu x = a[mid], báo cáo vị trí tìm x mid − Nếu khơng cịn phần tử để xét, báo cáo khơng tìm x 29 Tìm kiếm nhị phân – ví dụ Giả sử x = 11 ta phải tìm x mảng a bên a 11 15 20  x = 8? a 11 15 20  x = 15? a 11 15 20  x = 11? 30 Tìm kiếm nhị phân – mã giả function binarySearch(a, n, x) { left  0, right  n – while (left  right) { mid  (left + right) / if (x < a[mid]) right  mid – else if (x > a[mid]) left  mid + else return mid } return –1 } 31 Tìm kiếm nhị phân – phân tích • Nếu n = 1, phép so sánh x với phần tử mảng • Nếu n > 1, phép so sánh x với phần tử mảng, sau thời gian tìm x nửa (trái phải) mảng • Suy thời gian chạy thuật toán: t(1) = (với n = 1) t(n) = + t(n/2) (với n > 1) = + + t(n/4) = + + + t(n/8) = k + t(n/2k) • Chọn k = log n, đó: t(n) = log n + t(1) = log n + = O(log n) 32 Bài tập Xét thuật toán có thời gian chạy bên Hỏi thuật tốn chậm lần gấp đơi kích thước đầu vào? a b c d e f n n2 n3 100n2 n log n 2n 33 Bài tập Sắp xếp hàm sau theo thứ tự tăng dần tốc độ tăng; nghĩa là, hàm f(n) xếp trước hàm g(n) f(n) = O(g(n)) f1(n) = n2,5 f2(n) = 2𝑛 f3(n) = n + 10 f4(n) = 10n f5(n) = 100n f6(n) = n2 log n 34 Bài tập Phân tích thời gian chạy (dùng ký hiệu O) thuật tốn tìm phần tử lớn max  a0 for i  to n-1 if (ai > max) max  35 Bài tập Phân tích thời gian chạy (dùng ký hiệu O) đoạn chương trình C++ sau (a) sum = 0; for (i = 0; i < n; i++) sum++; (b) sum = 0; for (i = 0; i < n; i++) for (j = 0; j < n; j++) sum++; 36 Bài tập Phân tích thời gian chạy (dùng ký hiệu O) đoạn chương trình C++ sau (c) sum = 0; for (i = 0; i < n; i++) for (j = 0; j < n*n; j++) sum++; (d) sum = 0; for (i = 0; i < n; i++) for (j = 0; j < i; j++) sum++; 37 Bài tập Phân tích thời gian chạy (dùng ký hiệu O) đoạn chương trình C++ sau (e) sum = 0; for (i = 0; i < n; i++) for (j = 0; j < i*i; j++) for (k = 0; k < j; k++) sum++; (f) sum = 0; for (i = 0; i < for (j = 0; if (j % for n; i++) j < i*i; j++) i == 0) (k = 0; k < j; k++) sum++; ... dung Phân tích thuật tốn gì? Các ký hiệu tiệm cận Tốc độ tăng hàm Các ví dụ phân tích thuật tốn Phân tích thuật tốn gì? Phân tích thuật tốn • Nhằm xác định thời gian chạy (độ phức tạp) thuật toán. .. = 100n f6(n) = n2 log n 34 Bài tập Phân tích thời gian chạy (dùng ký hiệu O) thuật tốn tìm phần tử lớn max  a0 for i  to n-1 if (ai > max) max  35 Bài tập Phân tích thời gian chạy (dùng ký... t(1) = log n + = O(log n) 32 Bài tập Xét thuật tốn có thời gian chạy bên Hỏi thuật toán chậm lần gấp đơi kích thước đầu vào? a b c d e f n n2 n3 100n2 n log n 2n 33 Bài tập Sắp xếp hàm sau theo

Ngày đăng: 26/12/2021, 17:20

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan