Bài tập phân tich thiết kế thuật toán năm 2024
Ngày đăng:
06/03/2024
Trả lời:
0
Lượt xem:
39
các bạn tự tìm sách trên google theo gợi ý bên dưới nhé! Show
algorithms and complexity.pdf bài tập thực hành phân tích thuật toán.pdf generating functionology.pdf pttt01_phân tích và thiết kế thuật toán.pdf pttt02_đá á nh giá bằng công cụ toán học cơ bản.pdf pttt03_đệ quy và đánh giá.pdf pttt04_hàm sinh và ứng dụng.pdf pttt05_hoán vị và ứng dụng.pdf pttt06_đá á nh giá một số thuật toán thông dụng.pdf pttt08_chia để trị divide and conquer.pdf pttt09_kỹ thuật greedy (tham lam).pdf Bài tập môn phân tích và thiết kế thuật toán:Bài 1: giải thuật tìm n!Ý tưởng bài toán:Để tính giai thừa của một số nguyên dương n, ta có thể sửdụng công thức:n! = n x (n-1) x (n-2) x ... x 2 x 1Ta có thể sử dụng đệ quy để tính giai thừa của n bằng cáchtính giai thừa của (n-1) và nhân với nCode trong python:def giai_thua(n):if n == 1 :return 1else:return n * giai_thua(n- 1 )n = int(input("nhap vao n: "))print(giai_thua(n))Đánh giá độ phức tạp:Độ phức tạp của thuật toán tính giai thừa bằng đệ quy cóthể được đánh giá qua 3 mức độ như sau: Tốt nhất: O(1) Trung bình: O(n) Xấu nhất: O(n)Giải thích: Tốt nhất: khi giá trị đầu vào là 1, thì thuật toán sẽ thựchiện 1 lần phép so sánh và 1 lần trả về giá trị 1, vì vậy độphức tạp là O(1). Trung bình và xấu nhất: khi giá trị đầu vào là n, thìthuật toán sẽ thực hiện n lần phép nhân và n lần phép gọiđệ quy, vì vậy độ phức tạp của thuật toán là O(n).BÀI 2: giải thuật Eculid. ( tìm ước chung lớn nhất của 2 sốnguyên )Ý tưởng bài toán:Giả sử ta có hai số nguyên dương a và b (a > b), ta muốn tìm ước chunglớn nhất của chúng. Nếu b = 0, kết quả là a. Nếu b khác 0, ta thực hiện đệ quy với hai số nguyên b và a % b(phần dư của a khi chia cho b).Hình ảnh minh h a ọCode trong python:Bài 3:thuật toán tìm maxÝ tưởng bài toán:sử dụng đệ quy để liên tục giảm độ dài của mảng và so sánh giá trị của phần tửcuối cùng với giá trị lớn nhất hiện tại. Nếu phần tử cuối cùng lớn hơn giá trị lớnnhất hiện tại, ta cập nhật giá trị lớn nhất hiện tại. Sau đó, ta gọi đệ quy với độ dàicủa mảng giảm đi một đơn vị và giá trị lớn nhất hiện tại. Tiếp tục thực hiện đệquy đến khi độ dài của mảng bằng 0 và trả về giá trị lớn nhất tìm được.Code trong python:def findMax(arr, n, maxVal):if n == 0 :return maxValelse:if arr[n- 1 ] > maxVal:maxVal = arr[n- 1 ]return findMax(arr, n- 1 , maxVal)# Ví dụarr = [ 3 , 5 , 2 , 9 , 7 , 1 , 8 , 4 ]maxValue = findMax(arr, len(arr), float("-inf"))print(maxValue) # Kết quả: 9Đánh giá độ phức tạp: Tốt nhất: O(1), khi mảng chỉ có một phần tử và giá trị của phần tửđó là giá trị lớn nhất. Xấu nhất: O(n), khi mảng có n phần tử và phần tử lớn nhất nằm ởcuối mảng. Trung bình: O(n), khi mảng có n phần tử và phần tử lớn nhất xuấthiện ở bất kỳ vị trí nào.Giải thích: Đối với mỗi lần gọi đệ quy, ta sẽ giảm độ dài của mảng đi 1. Vì vậy, sốlần gọi đệ quy sẽ là n. Trong mỗi lần gọi đệ quy, ta sẽ thực hiện một số thao táccơ bản như so sánh giá trị của phần tử cuối cùng với giá trị lớn nhất hiện tại vàcập nhật giá trị lớn nhất hiện tại nếu cần. Vì vậy, độ phức tạp của giải thuật làO(n).BÀI 4: tìm số fibinacciÝ tưởng bài toán: nếu n = 0, số Fibonacci thứ n là 0 nếu n = 1, số Fibonacci thứ n là 1 nếu n > 1, số Fibonacci thứ n là tổng của hai số Fibonacci liền trướcnóVì vậy, để tính số Fibonacci thứ n, chúng ta cần tính số Fibonacci thứ n-và n-2.Code trong python:def fibonacci(n):if n <= 1 :return nelse:return fibonacci(n- 1 ) + fibonacci(n- 2 )n = int(input("Nhập n: "))fib_n = fibonacci(n)print(f"Số Fibonacci thứ {n} là {fib_n}")Đánh giá độ phức tạp thuật toán:Tốt nhất: O(1). Khi n = 0 hoặc 1 hoặc 2, ta trả về giá trị cố định 0 hoặc 1, do đóthời gian thực hiện của thuật toán là rất nhanh và không phụ thuộc vào n.Trung bình, xấu nhất; O(2^n). Khi n lớn, thuật toán sẽ gọi đệ quy nhiều lần đểtính toán số Fibonacci thứ n. Mỗi lần gọi đệ quy sẽ tạo ra hai lần gọi đệ quy khác,do đó số lần gọi đệ quy tăng theo cấp số nhân. Thời gian thực hiện của thuậttoán tăng theo cấp số nhân 2^n, vì mỗi lần gọi đệ quy tốn O(1) và ta phải gọi đệquy 2 lần.Ví d ụtnh f(5).Chứng minh độ phức tạp thuật toán với phương pháp truyhồi: (gõ lại bằng máy cho chuyên nghiệp nhá)Ý tưởng giải:1. Đưa n-1 đĩa từ cọc A đến cọc B bằng cách sử dụng cọc C làm cọctrung gian.2. Di chuyển đĩa còn lại từ cọc A đến cọc C.3. Đưa n-1 đĩa từ cọc B đến cọc C bằng cách sử dụng cọc A làm cọctrung gian.Code trong python:def tower_of_hanoi(n, source, target, auxiliary):# n: số lượng đĩa cần di chuyển# source: cọc ban đầu# target: cọc đích# auxiliary: cọc trung gian# nếu chỉ có một đĩa, di chuyển nó từ cọc ban đầu đến cọc đích và kếtthúcif n == 1 :print("Move disk 1 from source", source, "to target", target)return# di chuyển n-1 đĩa từ cọc ban đầu đến cọc trung giantower_of_hanoi(n - 1 , source, auxiliary, target)# di chuyển đĩa cuối cùng từ cọc ban đầu đến cọc đíchprint("Move disk", n, "from source", source, "to target", target)# di chuyển n-1 đĩa từ cọc trung gian đến cọc đíchtower_of_hanoi(n - 1 , auxiliary, target, source)# ví dụ sử dụng hàm trên cho 3 đĩa, bắt đầu từ cọc A, di chuyển đến cọc C,sử dụng cọc B làm cọc trung giann = 3tower_of_hanoi(n, &039;A&039;, &039;C&039;, &039;B&039;)Kết quả:Đánh giá độ phức tạp thuật toán: Tốt nhất: O(1) - khi n = 1 , ta chỉ cần di chuyển đĩa từ cọc ban đầuđến cọc đích và kết thúc hàm. Trung bình: O(2^n) - khi n > 1 , ta cần di chuyển n-1 đĩa từ cọc banđầu đến cọc trung gian, sau đó di chuyển đĩa cuối cùng từ cọc ban đầuđến cọc đích và cuối cùng di chuyển n-1 đĩa từ cọc trung gian đến cọcđích. Vì mỗi lần di chuyển đĩa đều có hai lựa chọn (từ cọc ban đầu đến cọcđích hoặc từ cọc đích đến cọc ban đầu), nên số lần di chuyển là 2^n - 1. Xấu nhất: O(2^n) - khi n > 1 , ta vẫn phải di chuyển n-1 đĩa từ cọcban đầu đến cọc trung gian, sau đó di chuyển đĩa cuối cùng từ cọc banđầu đến cọc đích và cuối cùng di chuyển n-1 đĩa từ cọc trung gian đến cọcđích. Vì số lần di chuyển là 2^n - 1, nên độ phức tạp là O(2^n).Bài 6: Tìm hiểu thêm về đệ quy_Duyệt đồ thị theo chiềusâu bằng đệ quyÝ tưởng bài toán:Ý tưởng chính của thuật toán là thực hiện duyệt DFS trên đồ thị, bắt đầu từ mộtđỉnh bất kỳ, sau đó tiếp tục duyệt trên các đỉnh kề với đỉnh hiện tại chưa đượcduyệt. Trong quá trình duyệt, lưu lại danh sách các đỉnh đã được duyệt và in rakết quả cuối cùngCode trong python:def DFS_traversal(graph):visited_nodes = [] # khởi tạo danh sách các đỉnh đã được duyệtnum_nodes = len(graph) # số lượng đỉnh trong đồ thị# định nghĩa hàm đệ quy DFS để duyệt đồ thịdef DFS(current_node):visited_nodes(current_node) # thêm đỉnh hiện tại vào danhsách đã duyệtfor neighbor in range(num_nodes): # duyệt qua tất cả các đỉnh kềvới đỉnh hiện tạiif graph[current_node][neighbor] == 1 and neighbor not invisited_nodes:# nếu đỉnh kề chưa được duyệt, thực hiện DFS trên đỉnh đóDFS(neighbor) |