1. Trang chủ
  2. » Luận Văn - Báo Cáo

Bài báo cáo phân tích thiết kế giải thuật

18 0 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Thông tin cơ bản

Tiêu đề Bài Báo Cáo Phân Tích Thiết Kế Giải Thuật
Tác giả Nguyễn Tiến Vươn
Người hướng dẫn Giảng Viên: Huỳnh Thanh Việt
Trường học Trường Đại Học Giao Thông Vận Tải Tp.Hcm
Chuyên ngành Công Nghệ Thông Tin
Thể loại bài báo cáo
Năm xuất bản 2024
Thành phố Tp.Hồ Chí Minh
Định dạng
Số trang 18
Dung lượng 1,84 MB

Nội dung

Các chiến lược như quy hoạch động dynamic programming, chia để trị divide and conquer, tham lam greedy, và quay lui backtracking không chỉ giúp tìm ra lời giải chính xác mà còn đảm bảo h

Trang 1

TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI TP.HCM

VIỆN ĐÀO TẠO CHẤT LƯỢNG CAO KHOA CÔNG NGHỆ THÔNG TIN

BÀI BÁO CÁO PHÂN TÍCH THIẾT KẾ GIẢI THUẬT

Giảng Viên: Huỳnh Thanh Việt

Sinh viên: Nguyễn Tiến Vươn

MSSV: 0522050110044

TP.Hồ Chí Minh, ngày 23 tháng 11 năm 2024

Trang 2

MỤC LỤC

MỞ ĐẦU 3

I BÀI TOÁN 4

1 Lịch thuê máy tối ưu 4

2 Bài toán tìm lộ trình tối ưu trong bảng A 8

II ƯU ĐIỂM VÀ NHƯỢC ĐIỂM 17

1 Ưu điểm 17

2 Nhược điểm 17

III HƯỚNG PHÁT TRIỂN 18

KẾT LUẬN 19

Trang 3

MỞ ĐẦU

Môn Phân tích Thiết kế Giải thuật đóng vai trò quan trọng trong việc trang bị các kỹ năng và phương pháp giải quyết bài toán một cách tối ưu Các chiến lược như quy hoạch động (dynamic programming), chia để trị (divide and conquer), tham lam (greedy), và quay lui (backtracking) không chỉ giúp tìm ra lời giải chính xác mà còn đảm bảo hiệu quả về mặt thời gian và không gian

Hai bài toán được trình bày trong bài tiểu luận này là minh chứng cho sức mạnh của chiến lược quy hoạch động Bài toán thứ nhất tập trung vào việc tối ưu hóa doanh thu trong một lịch trình có ràng buộc thời gian, trong khi bài toán thứ hai là bài toán tìm đường tối ưu trong một bảng hai chiều

Trang 4

I BÀI TOÁN

1 Lịch thuê máy tối ưu

Trung tâm tính toán hiệu năng cao nhận được đơn đặt hàng của n khách hàng Khách hàng i muốn sử dụng máy trong khoảng thời gian từ ai đến bi Hãy thiết kế chương trình

để bố trí lịch thuê máy để tổng số tiền thu được là lớn nhất mà thời gian sử dụng máy của 2 khách hàng bất kì được phục vụ đều không giao nhau (cả trung tâm chỉ có một máy cho thuê)

Sử dụng chiến lược quy hoạch động

a.1) Ý tưởng thực hiện

1 Nhập liệu:

Người dùng sẽ nhập số lượng khách hàng và thông tin về thời gian bắt đầu (ai), thời gian kết thúc (bi), và lợi nhuận (vi) cho mỗi khách hàng

2 Sắp Xếp Dữ Liệu:

Các cuộc hẹn (hoặc khoảng thời gian thuê máy) sẽ được sắp xếp theo thời gian kết thúc (bi) Điều này giúp chúng ta dễ dàng xác định các khoảng thời gian không giao nhau

3 Xây Dựng Bảng Quy Hoạch Động:

Sử dụng một mảng f để lưu trữ lợi nhuận tối đa có thể thu được cho mỗi khách hàng

Với mỗi khách hàng, chúng ta sẽ xem xét hai lựa chọn: Lựa chọn 1: Không phục vụ khách hàng này (lợi nhuận là lợi nhuận tối đa của khách hàng trước đó)

Lựa chọn 2: Phục vụ khách hàng này, cộng với lợi nhuận từ khách hàng không giao nhau trước đó

4 Tìm Lợi Nhuận Tối Đa:

Cuối cùng, giá trị lớn nhất trong mảng f sẽ là lợi nhuận tối đa

có thể đạt được

Trang 5

b.1) Giải thích thuật toán

#include <iostream>: Thư viện cần thiết để sử dụng các chức năng nhập xuất như cin và cout

#include <vector>: Cho phép sử dụng cấu trúc dữ liệu vector

để lưu trữ các giá trị động

#include <algorithm>: Cung cấp các hàm hỗ trợ như sort và max_element

int n;: Khai báo biến n để lưu số lượng khách hàng

vector<int> s(n + 1), e(n + 1), v(n + 1);: Khai báo ba vector: s: Lưu thời gian bắt đầu cho từng khách hàng

e: Lưu thời gian kết thúc cho từng khách hàng

v: Lưu lợi nhuận tương ứng với từng khách hàng

s[0] = 0; e[0] = 0; v[0] = 0;: Khởi tạo phần tử đầu tiên của mỗi vector với giá trị 0 để dễ dàng xử lý trong thuật toán

Trang 6

Vòng lặp for từ 1 đến n yêu cầu người dùng nhập thời gian bắt đầu, thời gian kết thúc và lợi nhuận cho từng khách hàng Sắp Xếp:

 Hai vòng lặp lồng nhau để sắp xếp các lần thuê theo thời gian kết thúc tăng dần Nếu thời gian kết thúc của lần thuê i nhỏ hơn thời gian kết thúc của lần thuê j, nó sẽ hoán đổi thông tin giữa chúng

 Sử dụng swap để hoán đổi giá trị giữa các vector

Khởi tạo giá trị:

 f[i] là một mảng dùng để lưu lợi nhuận tối đa đạt được khi chọn đến lần thuê thứ i

 v[i] là mảng lợi nhuận của từng lần thuê

 s[i] là thời gian bắt đầu của lần thuê thứ i

 e[i] là thời gian kết thúc của lần thuê thứ i

Duyệt qua các cuộc họp:

 for (int i = 1; i <= n; i++): Vòng lặp này duyệt qua tất cả các lần thuê từ 1 đến n

 f[i] = v[i];: Khởi tạo lợi nhuận ban đầu cho lần thuê thứ i

là giá trị lợi nhuận của nó (v[i]), giả định rằng nếu chỉ chọn một mình lần thuê i, thì lợi nhuận đạt được là v[i]

So sánh với các lần thuê trước đó:

 for (int j = 1; j < i; j++): Vòng lặp lồng trong để duyệt qua tất cả các lần thuê j trước i (từ 1 đến i-1)

Trang 7

 if (s[i] >= e[j] && f[i] < f[j] + v[i]): Kiểm tra xem lần thuê i có thể chọn được sau lần thuê j (nghĩa là s[i] >= e[j]) và liệu lợi nhuận thu được khi chọn lần thuê i sau j có lớn hơn lợi nhuận hiện tại của f[i] hay không

o Nếu điều kiện này thỏa mãn, thì cập nhật lợi nhuận tối đa cho f[i] bằng cách thêm lợi nhuận v[i] vào lợi nhuận tối

đa của f[j]

Vd minh họa:

Áp dụng đoạn mã:

 Khởi tạo:

o f[1] = v[1] = 5

o f[2] = v[2] = 6

o f[3] = v[3] = 5

o f[4] = v[4] = 8

 Duyệt từng lần thuê:

o Lần thuê2:

 Không thể chọn cuộc họp 2 sau cuộc họp 1 vì s[2] < e[1]

o Lần thuê 3:

 So với lần thuê 1: s[3] >= e[1] và f[3] < f[1] + v[3], nên f[3] = f[1] + v[3] = 5 + 5 = 10, và t[3] = 1

 So với lần thuê 2: không thỏa mãn điều kiện

o Lần thuê 4:

 So với lần thuê 1: s[4] >= e[1] và f[4] < f[1] + v[4], nên f[4] = f[1] + v[4] = 5 + 8 = 13, và t[4] = 1

Trang 8

 So với lần thuê 3: s[4] >= e[3] và f[4] < f[3] + v[4], nên f[4] = f[3] + v[4] = 10 + 8 = 18, và t[4] = 3 Kết quả, lợi nhuận tối đa là 18, và các lần thuê được chọn

là lần thuê 1, 3 và 4

Tìm lợi nhuận và in ra kết quả

2 Bài toán tìm lộ trình tối ưu trong bảng A.

Cho bảng A gồm M N ô Từ ô (i,j) có thể di chuyển sang∗

3 ô (i+1, j), (i+1, j−1) và (i+1, j+1) Hãy thiết kế giải thuật để xác định một lộ trình đi từ hàng 1 đến hàng M sao cho tổng các ô đi qua là lớn nhất

a.2) Ý tưởng thực hiện

1 Khởi tạo mảng DP:

Gọi dp[i][j] là tổng giá trị lớn nhất có thể đạt được khi đến ô (i, j) từ hàng đầu tiên

2 Công thức quy hoạch động:

dp[i][j]=A[i][j]+max(dp[i−1][j],dp[i−1][j−1],dp[i−1][j+1])

3 Tính toán cho các hàng tiếp theo:

Với mỗi ô (i, j), cập nhật dp[i][j] bằng tổng của A[i][j] và giá trị lớn nhất trong ba ô phía trên: Ô trên (i-1, j), Ô trên bên trái (i-1, j-1) ,Ô trên bên phải (i-1, j+1)

4 Truy vết để tìm lộ trình

Trang 9

5 Kết quả:

Tìm giá trị lớn nhất trong hàng cuối của dp, đây là tổng lớn nhất có thể đạt được từ hàng đầu đến hàng cuối cùng

b.2) Giải thích thuật toán

Thư viện:

· #include <iostream>: Thư viện cho phép sử dụng các hàm nhập/xuất như cin và cout

· #include <vector>: Thư viện cho phép sử dụng cấu trúc

dữ liệu vector

· #include <algorithm>: Thư viện cung cấp các hàm thuật toán như reverse

Hằng số:

const int MAX = 100;: Đặt hằng số MAX là 100, đại diện cho kích thước tối đa của bảng A (100x100) Kích thước này

có thể thay đổi tùy theo yêu cầu bài toán

Hàm maxPathSum:

int maxPathSum( ): Định nghĩa hàm maxPathSum, nhận các tham số:

Trang 10

A[MAX][MAX]: Bảng giá trị đầu vào A có kích thước tối

đa MAX x MAX

M: Số hàng của bảng A

N: Số cột của bảng A

path: Tham chiếu đến một vector lưu các cặp tọa độ (i, j)

để theo dõi lộ trình tối ưu

int dp[MAX][MAX], trace[MAX][MAX];: Khai báo mảng

dp lưu tổng lớn nhất đạt được khi đến mỗi ô (i, j) và mảng trace để lưu lại cột trước đó từ đó ta đi đến ô (i, j) trong lộ trình tối ưu

Khởi tạo hàng đầu tiên của dp:

· Vòng lặp for (int j = 0; j < N; ++j): Duyệt qua từng ô trong hàng đầu tiên (hàng 0)

· dp[0][j] = A[0][j];: Khởi tạo dp[0][j] bằng giá trị tại ô A[0] [j] vì hàng đầu tiên không có ô phía trên, nên tổng lớn nhất đến ô này chính là giá trị của nó

· trace[0][j] = -1;: Gán -1 cho trace[0][j] vì hàng đầu tiên không có ô trước đó

Tính toán dp cho các hàng tiếp theo:

Trang 11

· for (int i = 1; i < M; ++i): Vòng lặp chạy qua từng hàng từ hàng 1 đến hàng M-1

· for (int j = 0; j < N; ++j): Vòng lặp chạy qua từng cột trong mỗi hàng

· int maxPrev = dp[i - 1][j];: Giả sử ô tối ưu phía trên là ô trực tiếp trên (i-1, j)

· trace[i][j] = j;: Ghi nhận vị trí cột của ô phía trên (i-1, j) làm ô trước đó

Kiểm tra các ô phía trên bên trái và bên phải:

· if (j > 0 && dp[i - 1][j - 1] > maxPrev): Nếu tồn tại ô phía trên bên trái (i-1, j-1) và nó có tổng lớn hơn maxPrev, thì cập nhật:

 maxPrev = dp[i - 1][j - 1];: Cập nhật maxPrev bằng tổng lớn nhất từ ô phía trên bên trái

 trace[i][j] = j - 1;: Cập nhật trace[i][j] để chỉ đến ô phía trên bên trái (i-1, j-1)

· if (j < N - 1 && dp[i - 1][j + 1] > maxPrev): Nếu tồn tại

ô phía trên bên phải (i-1, j+1) và nó có tổng lớn hơn maxPrev, thì cập nhật:

 maxPrev = dp[i - 1][j + 1];: Cập nhật maxPrev bằng tổng lớn nhất từ ô phía trên bên phải

 trace[i][j] = j + 1;: Cập nhật trace[i][j] để chỉ đến ô phía trên bên phải (i-1, j+1)

Cập nhật tổng lớn nhất cho dp[i][j]:

Trang 12

dp[i][j] = A[i][j] + maxPrev;: Tổng lớn nhất để đến ô (i, j)

là giá trị của ô đó A[i][j] cộng với tổng lớn nhất từ ô phía trên tối ưu (maxPrev)

Tìm tổng đường đi lớn nhất ở hàng cuối cùng:

· int result = dp[M - 1][0], lastCol = 0;: Khởi tạo result là tổng lớn nhất của cột đầu tiên ở hàng cuối và lastCol là chỉ số cột này

· for (int j = 1; j < N; ++j): Duyệt qua tất cả các ô trong hàng cuối để tìm tổng lớn nhất

· if (dp[M - 1][j] > result): Nếu tìm được ô có tổng lớn hơn result, thì cập nhật result và lastCol với giá trị mới

Truy ngược lại lộ trình:

· for (int row = M - 1, col = lastCol; row >= 0; row): Bắt đầu từ hàng cuối cùng M-1 và cột có tổng lớn nhất lastCol, đi ngược lên đầu bảng

Trang 13

· path.push_back({ row, col });: Thêm vị trí (row, col) vào path

· col = trace[row][col];: Cập nhật col để chuyển sang cột của ô trước đó từ trace

· reverse(path.begin(), path.end());: Đảo ngược path để lộ trình hiển thị theo thứ tự từ trên xuống dưới

Trả về kết quả:

return result;: Trả về tổng lớn nhất của lộ trình

Hàm main:

· int main() { }: Hàm chính của chương trình

· int M, N, A[MAX][MAX];: Khai báo M và N là số hàng và cột của bảng A

· cin >> M >> N;: Nhập vào M và N từ người dùng

Nhập giá trị cho bảng A:

· cout << "Nhap cac phan tu bang A:\n";: In ra dòng nhắc để người dùng nhập vào các phần tử của bảng

Trang 14

· for (int i = 0; i < M; ++i) và for (int j = 0; j < N; ++j): Hai vòng lặp lồng nhau để duyệt qua từng ô (i, j) trong bảng A, với i là chỉ số hàng (chạy từ 0 đến M-1) và j là chỉ số cột (chạy từ 0 đến N-1)

· cin >> A[i][j];: Tại mỗi ô (i, j), người dùng nhập vào giá trị A[i][j] của bảng A

Phần tính và hiển thị kết quả:

Sau khi nhập bảng A, chúng ta gọi hàm maxPathSum() để tính tổng lớn nhất và lộ trình Sau đó, in ra kết quả

· vector<pair<int, int>> path;: Khai báo một vector path để lưu lộ trình tối ưu Mỗi phần tử của path là một cặp (i, j), biểu thị vị trí của ô trên lộ trình

· int maxSum = maxPathSum(A, M, N, path);: Gọi hàm maxPathSum với các tham số là bảng A, số hàng M, số cột N,

và path

Hàm này sẽ trả về maxSum, tức là tổng lớn nhất của lộ trình

từ hàng đầu đến hàng cuối

Tiếp theo là phần hiển thị kết quả:

· cout << "Tong lon nhat cua lo trinh la: " << maxSum << endl;: In ra tổng lớn nhất của lộ trình, tức là giá trị maxSum

· cout << "Cac buoc di chuyen:\n";: In ra một dòng thông báo rằng các bước di chuyển sẽ được liệt kê tiếp theo

Trang 15

· for (auto& p : path): Dùng vòng lặp để duyệt qua từng ô (i, j) trong lộ trình path

· cout << "(" << p.first << ", " << p.second << ") ";: In tọa độ của từng ô trên lộ trình, biểu thị theo dạng (i, j)

· cout << endl;: Kết thúc dòng in ra

c.2) Ví dụ:

Giả sử bảng A là:

1 2 3

4 5 6

7 8 9

Bước 1: Khởi tạo mảng dp bằng hàng đầu của A:

1 2 3

0 0 0

0 0 0

Bước 2: Tính toán hàng thứ 2 của dp:

1 2 3

5 7 9

0 0 0

Ví dụ: dp[1][1] = A[1][1] + max(dp[0][0], dp[0][1]) = 5 + max(1, 2) = 7 Bước 3: Tính toán hàng thứ 3 của dp:

1 2 3

5 7 9

12 15 18

Kết quả: Tổng lớn nhất là 18, đạt được bằng cách đi theo lộ trình 1 -> 2 -> 9

Trang 16

II ƯU ĐIỂM VÀ NHƯỢC ĐIỂM

1 Ưu điểm

Quy hoạch động là một kỹ thuật hiệu quả để giải quyết các bài toán có tính chất đệ quy và con

Các bước cơ bản của quy hoạch động:

Xác định cấu trúc của lời giải tối ưu: Tìm cách biểu diễn lời giải tối ưu thông qua các lời giải con

Xây dựng công thức truy hồi: Lập công thức liên hệ giữa lời giải của bài toán con với lời giải của bài toán lớn hơn

Tính toán từ dưới lên: Tính toán các giá trị con trước rồi mới tính toán các giá trị lớn hơn

Ứng dụng: Quy hoạch động có thể được áp dụng vào rất nhiều lĩnh vực khác nhau, từ khoa học máy tính đến kinh

tế, tài chính

Quy hoạch động giúp giảm thiểu thời gian tính toán và tránh tính toán trùng lặp

2 Nhược điểm

Không phải bài toán nào cũng có thể giải quyết bằng quy hoạch động Chỉ những bài toán có tính chất đệ quy và con mới phù hợp

Độ phức tạp của thuật toán: Trong một số trường hợp, việc thiết kế thuật toán quy hoạch động có thể khá phức tạp

Trang 17

III HƯỚNG PHÁT TRIỂN

Tìm hiểu sâu hơn về các biến thể của quy hoạch động:

Ví dụ như quy hoạch động top-down, bottom-up,

memoization

Áp dụng quy hoạch động vào các bài toán thực tế: Tìm

kiếm các bài toán trong lĩnh vực bạn quan tâm và thử giải quyết bằng quy hoạch động

Kết hợp quy hoạch động với các kỹ thuật khác: Ví dụ

như thuật toán tham lam, chia để trị

Trang 18

KẾT LUẬN

Môn Phân tích Thiết kế Giải thuật là một trong những môn

học cốt lõi trong ngành khoa học máy tính, cung cấp cho sinh viên những kiến thức và kỹ năng cần thiết để phân tích, thiết

kế và đánh giá hiệu quả của các thuật toán Qua môn học này, chúng ta đã được trang bị những công cụ và phương pháp để giải quyết các bài toán thuật toán một cách hiệu quả

Hai bài toán về lịch thuê máy tối ưu và tìm đường đi tối ưu trong bảng đã minh họa rất rõ ràng cách áp dụng quy hoạch

động để giải quyết các bài toán tối ưu hóa Quy hoạch động là một kỹ thuật mạnh mẽ, cho phép ta chia nhỏ bài toán lớn thành các bài toán con nhỏ hơn, từ đó tìm ra lời giải tối ưu cho toàn bộ bài toán

Ngày đăng: 24/12/2024, 16:09

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN