+ Bước 2: Tiến hành giải quyết bài toán bằng quy cách truy hồi dựa trên kết quả củaviệc lựa chọn các cuộc họp.+ Chi phí của bài toán sẽ bao gồm chi phí cho việc sử dụng thuật toán của bư
Trang 2Mục lục
I Tìm hiểu bài toán 3
1 Nội dung bài toán 3
2 Diễn giả bài toán 3
3 Hướng giải quyết bài toán 3
II Thuật toán quy hoạch động 4
1 Thuật ngữ 4
2 Phương thức tiếp cận 4
3 Các bước để giải bài toán Quy Hoạch Động 4
III Ứng dụng thuật toán QHD để giải quyết bài toán thực tế 5
1 Mô hình bài toán 5
2 Xây dựng thuật toán QHD để tìm nghiệm tối ưu của bải toán 5
3 Đánh giá thuật toán 7
a Độ phức tạp dữ liệu 7
b. Độ phức tạp tính toán 7
4 Cải tiến thuật toán: 7
a Đổi thuật toán sắp xếp 7
b. Cải tiến thuật toán quy hoạch động tìm nghiệp tối ưu 7
5 Kết quả thức nghiệm 9
a Sử dung thuật toán ban đầu 9
b. Sử dụng thuật toán cải tiến 10
IV.Chương trình ( Lập trình bằng ngôn ngữ C) 11
1 Chương trình ban đầu 11
a Mô tả 11
b. Code 11
2 Chương trình cải tiến 15
a Mô tả 15
b. Code 15
Trang 3Do điều kiện về thời gian và hạn chế về kiến thức nên bài tập lớn này không tránh khỏi nhiều thiếu sót Vì vậy tôi mong muốn nhận được nhiều ý kiến đónh góp của thầy và bạn bè.
Tôi xin chân thành cảm ơn!
Trang 4I Tìm hiểu bài toán
1 Nội dung bài toán
Có 1 phòng để để chức các cuộc họp Các cuộc họp được xếp vào lịch nếu khoảng thờigian làm việc của chúng giao nhau không nhiều hơn thời điểm tiếp nối Cho n cuộc họp, cuộchọp thứ i bắt đầu vào thời điểm ai và kết thúc ở thời điểm bi Hãy xếp lịch để phục vụ đượcnhiều cuộc họp nhất
2 Diễn giả bài toán.
Bài toàn bao gồm
Dữ liệu vào: S={[a1, b1],…, [an-1, bn-1], [an, bn]} trong đó :
+ n : Số lượng cuộc họp (n>0)
+ [ai, bi] : Khoảng thời gian diễn ra cuộc họp thứ i (1 i n) với:
- ai là thời điểm bắt đầu cuộc họp và
- bi là thời điểm kết thúc cuộc họp
Dữ liệu ra:
+ Tập hợp Smax= {[ai1, bi1], [ai2, bi2], …, [aimax, bimax]} , 1<= i1, , imax<= n
Thỏa mãn :
- bik aik+1,với k [1 max-1] )
- Số cuộc họp của tập Smax là lớn nhất
3 Hướng giải quyết bài toán.
- Nhận xét: Với các bài toán như trên thì thông thường thuật toán đầu tiên mà nhữngngười đọc vào có thể nghĩ tới là dùng thuật toán vét cạn, có nghĩa chúng ta sẽ quét tất cả cáctrường hợp có thể xảy ra, với mỗi trường hợp người ta sẽ kiểm tra xem có thể bố trí chúngtrong cùng một phòng hay không và số lượng cuộc họp là bao nhiêu, tuy nhiên chi phí choviệc làm này là không nhỏ Để quét hết các trường hợp xảy ra người ta có thể sử dụng thuậttoán liệt kê tổ hợp Cn với k = 1 n và trong trường hợp xấu nhất thì chi phí chỉ cho việc đưa
ra tất cả các trường hợp đã là O(Cn +Cn+ … +Cn) = O(2n) còn chưa kể đến việc với mỗitrường hợp xảy ra chúng ra lại phải vét thêm một lần nữa cho việc xét xem chúng có bố tríđược hay không, ví dụ với trường hợp ta chọn ra được một trường hợp là ba cuộc họp theothứ tự là 1, 4, 6 dễ thấy có thể bố trí chúng trong cùng một phòng với số lượng các cuộc họplớn nhất là 3 và theo thứ tự các cuộc họp là 4, 1, 6, tuy nhiên ta còn phải chi phí cho việc xét
và kiểm tra chúng thì mới có được thứ tự này mà thời gian chi cho nó cũng khá lớn
- Giải quyết bài toán bằng Quy Hoạch Động được thực hiện bằng 2 xử lý chính
+ Bước 1: Sắp xếp dữ liệu các cuộc họp ban đầu tăng dần theo thời gian kết thúc củacuộc họp
Trang 5+ Bước 2: Tiến hành giải quyết bài toán bằng quy cách truy hồi dựa trên kết quả củaviệc lựa chọn các cuộc họp.
+ Chi phí của bài toán sẽ bao gồm chi phí cho việc sử dụng thuật toán của bước 1 vàthuật toán của bước 2
Để giải quyết bài toán ta cần tìm hiểu các lý thuyết về quy hoạch động như sau:
II Thuật toán quy hoạch động
1 Thuật ngữ.
- Trong ngành Khoa học máy tính, Quy Hoạch Động là một phương pháp giáp thời gian
chạy của các thuật toán thể hiện các tính chất của các “Bài toán con gối
nhau”(overlapping Subproblem) và “Cấu trúc con tối ưu”(optimal substructure)
- Cấu trúc con tối ưu có nghĩa là các lời giải tối ưu cho các bài toán con có thể được sử
dụng để tìm các lời giải tối ưu cho bài toán toàn cục
Thường dùng để giải các bài toán tối ưu
Phân rã thành bài toán con, hình thành lời giải từ bài toán con
Lưu trữ lời giải của bài toán con trong một bảng dữ liệu thay cho giải lại cácbài toán con (đệ quy)
2 Phương thức tiếp cận
Quy hoạch động thường dùng một trong hai cách tiếp cận:
- Top-down (Từ trên xuống): Bài toán được chia thành các bài toán con, các bài toán
con này được giải và lời giải được ghi nhớ để phòng trường hợp cần dùng lại chúng.Đây là đệ quy và lưu trữ được kết hợp với nhau
- Bottom-up (Từ dưới lên): Tất cả các bài toán con có thể cần đến đều được giải trước,
sau đó được dùng để xây dựng lời giải cho các bài toán lớn hơn Cách tiếp cận này hơitốt hơn về không gian bộ nhớ dùng cho ngăn xếp và số lời gọi hàm Tuy nhiên, đôi khiviệc xác định tất cả các bài toán con cần thiết cho việc giải quyết bài toán cho trướckhông được trực giác lắm
3 Các bước để giải bài toán Quy Hoạch Động.
- Giải tất cả các bài toán cơ sở (thông thường rất dễ), lưu các lời giải vào bảng phươngán
- Dùng công thức truy hồi phối hợp những lời giải của các bài toán nhỏ đã lưu trongbảng phương án để tìm lời giải của những bài toán lớn hơn và lưu chúng vào bảngphương án Cho tới khi bài toán ban đầu tìm được lời giải
- Dựa vào bảng phương án, truy vết tìm ra nghiệm tối ưu
Trang 6III Ứng dụng thuật toán QHĐ để giải quyết bài toán thực tế.
1 Mô hình bài toán.
- Phần dữ liệu đầu vào:
Nhập bằng tay qua màn hình (với số lượng cuộc họp ít)
Nhập bằng file (dữ liệu nhiều cuộc họp)
- Phần thực hiện chương trình:
Dùng thuật toán sắp xếp để sắp xếp, để sắp xếp dữ liệu cuộc họp đầu vào tăngdần theo thời gian kết thúc cuộc họp
Xây dựng thuật toán quy hoạch động để tìm ra nghiệm tối ưu của bài toán
- Phần dữ liệu đầu ra:
Hiển thị kết quả trên màn hình
Xuất kết quả ra file
2 Xây dựng thuật toán QHĐ để tìm nghiệm tối ưu của bài toán.
Hàm mục tiêu: f là số lượng cuộc họp
- Gọi S là dãy các cuộc họp được bố trí thoả mãn yêu cầu đầu bài Vì số lượng cuộc họptrong S chỉ phụ thuộc vào dãy các cuộc họp đã cho ban đầu chính vì vậy bảng phương ánchỉ là một bảng 1 chiều
- Ta bổ xung vào 2 đầu của dãy S hai cuộc họp thứ 0 ([-maxint, -maxint]) và cuộc họp thứn+1 ([maxint, maxint]) như sau:
S= {[-maxint, -maxint], [a1, b1], [a2, b2], …, [an, bn], [maxint, maxint]},
Chắc chắn dãy các cuộc họp có số lượng dài nhất sẽ bắt đầu ở cuộc họp thứ 0 và kếtthúc ở cuộc họp n+1
- Gọi L(i) là độ dài lớn nhất của dãy các cuộc họp thoả mãn yêu cầu đầu bài bắt đầu từcuộc họp thứ i L(i) sẽ được tính trong điều kiện các giá trị L(i+1)…L(n+1) đã biết
Các bước xây dựng thuật toán QHĐ cho bài toán như sau:
Bước 1: Tìm cơ sở của phương án.
Dễ thấy nếu n = 1 hay nói cách khác là có 1 cuộc họp cần bố trí thì S = {[a1, b1]} hayphương án cơ sở L(1) = 1
Bước 2: Tìm công thức truy hồi.
Tính L(i): Dãy các cuộc họp được bố trí dài nhất bắt đầu từ cuộc họp thứ i sẽ được bốtrí bằng cách ghép cuộc họp thứ i vào đầu dãy các cuộc họp dài nhất bắt đầu từ cuộc họp jđứng sau cuộc họp i Vậy ta chỉ ghép cuộc họp i vào đầu những dãy bắt đầu từ cuộc họp jnào đó thoả mãn điều kiện bi aj , và dĩ nhiên ta chọn dãy dài nhất để ghép vào
Trang 7a L(i) được tính như sau:
1 Chọn trong số các chỉ số j từ i+1 đến n+1 mà bi aj
2 Chọn ra chỉ số jmax có L(jmax) lớn nhất
3 Đặt L(i)= L(jmax)+1: L(i)= Max (L(j))+1 (với i<jn+1 và bi aj )
Cách xây dựng mảng L có thể diễn tả thông qua thủ tục xử lí sau:
Sử dụng mảng 1 chiều Trace[] để lưu lại dãy các cuộc họp theo nguyên tắc Trace[i]
sẽ cho biết cuộc họp đứng liền sau cuộc họp i trong dãy các cuộc họp dài nhất bắt đầu từcuộc họp i
Bước 4: Tìm nghiệm của bài toán con thông qua nghiệm của bài toán con nhỏ hơn dựa
vào công thức truy hồi tại bước 2
Bước 5: Xây dựng nghiệm của bài toán thông qua bảng phương án (mảng 1 chiều
Trang 8Quá trình truy vết có thể diễn tả thông qua thủ tục sau:
- Trong quá trình lập bảng phương án và tính công thức truy hồi ta đã sử dụng 2 vòngfor lồng nhau nên độ phức tạp của đoạn chương trình này là O(n2)
- Tóm lại về tổng thể độ phức tạp dữ liệu và độ phức tạp tính để giải quyết bài toán này
là O(n2) và nó đã nhỏ hơn rất nhiều so với độ phức tạp của thuật toán vét cạn
4 Cải tiến thuật toán:
a Đổi thuật toán sắp xếp
- Sử dụng thuật toán sắp xếp nhanh, với độ phức tạp là O(nlogn)
b Cải tiến thuật toán quy hoạch động tìm nghiệp tối ưu.
- Với mỗi số k, gọi St[k] là chỉ số x của cuộc họp x thoả mãn:
Trang 9 Dãy các cuộc họp dài nhất bắt đầu từ x có độ dài k Nếu có nhiều cuộc họpcùng thoả mãn điều kiện này thi ta chọn cuộc họp có ax là phần tử lớn nhất.Việc tính các giá trị của St[k] được thực hiện đồng thời với việc tính các giátrị L[?] bằng phương pháp sau:
Khi bắt đầu vào một lần lặp với một giá trị i, ta biết được:
+ m: Độ dài dãy các cuộc họp dài nhất có chỉ số từ i+1 tới n+1 thoả mãn yêucầu đầu bài
+ St[k] (1km): Giá trị của aSt[k] là giá trị lớn nhất trong số các giá trị a1 chođến aSt[k-1] hay nói cách khác dãy các cuộc họp dài nhất bắt đầu từ cuộc họp thứ St[k]
sẽ có độ dài k Do cách tính toán nên ta dễ thấy rằng : aSt[k] < aSt[k-1] <…<aSt[1]
- Vậy điều kiện để có dãy các cuộc họp thoả mãn yêu cầu của đầu bài có độ dài p+1 bắtđầu từ cuộc họp i chính là biaSt[p] .Mặt khác nếu đem cuộc họp i ghép vào đầu dãycác cuộc họp đã có trước đó có độ dài lớn nhất bắt đầu từ cuộc họp St[p] mà thu đượcdãy phù hợp thì đem cuộc họp i ghép vào đầu dãy cuộc họp tăng dài nhất bắt đầu từSt[p-1] cũng thu được dãy thoả mãn yêu cầu đầu bài Vậy để tính L(i) ta có thể tìm số
p lớn nhất thoả mãn biaSt[p] bằng thuật toán tìm kiếm nhị phân và rồi đặt L(i)= p+1
5 Kết quả thức nghiệm
a Sử dung thuật toán ban đầu.
- Dữ liệu đầu vào :
Trang 10Số thứ tự các cuộc họp Thời điểm bắt đầu Thời điểm kết thúc
Kết quả là dãy các cuộc họp được bố trí như sau:
S Max = {[1, 2], [3, 5], [5, 8], [8, 10]}, độ dài Max= 4.
b Sử dụng thuật toán cải tiến.
- Dữ liệu đầu vào:
Số thứ tự các cuộc họp Thời điểm bắt đầu Thời điểm kết thúc
Trang 11- Sau khi sắp xếp nhanh:
Số thứ tự các cuộc họp Thời điểm bắt đầu Thời điểm kết thúc
Kết quả là dãy các cuộc họp được bố trí như sau:
S Max = {[1, 2], [4, 6], [7, 8], [9, 15]}, độ dài Max= 4.
IV Chương trình ( Lập trình bằng ngôn ngữ C)
Trang 121 Chương trình ban đầu
a Mô tả.
- Đầu vào : Nhập từ bàn phím
- Chương trình:
Thuật toán sắp xếp chọn Phức tạp O(N2)
Thuật toán chưa cải tiến Phức tạp O(N2)
- Đầu ra: Hiển thị kết quả trên màn hình
- File Source : Source.c
void SelectionSort(intbatdau[],intketthuc[],intn)
if (ketthuc[min] > ketthuc[j]){
min =j;
}}
// chi doi cho khi phan tu min khong lam vi tri dau tien
if (min !=i){
Trang 13// Đổi chỗ giá trị ketthuc cuộc họp
swap(int,ketthuc[min],ketthuc[i]);
swap(int,batdau[min],batdau[i]);
}}
int batdau[1001]; // Mảng lưu thời gian bắt đầu của các cuộc họp
int ketthuc[1001]; // Mảng lưu thời gian kết thúc của các cuộc họpint L[1001];// Lưu lại số lượng cuộc họp được bố trí vi trí thứ i, i=1,nint VT[1001]; // Lưu lại vị trí mà L[i] đạt max
int jmax;
int i;// Chỉ số duyệt dùng để duyệt mảng
int j;// Chỉ số duyệt dùng để duyệt mảng
/* - Phần nhập dữ liệu đầu vào -*/// Nhập số lượng cuộc họp, nếu số cuộc < 1 và lớn hơn 1000 thì nhập lạido
Trang 14// Nhập thời gian bắt đầu và thời gian kết thúc của n cuộc họp
for (i=1;i<=n;i++)
{
// Cuộc họp phải có thời gian kết thúc lớn hơn bắt đầu
// bắt đầu phải lớn hơn 1
// Nếu thời gian không thỏa mãn thì bắt buộc phải nhập lại
Trang 15// chỉ thay đổi Jmax khi tìm được cuộc họp i thỏa mãn ĐK dưới.
if (ketthuc[i] <= batdau[j] && L[j] > L[jmax]){
jmax =j;
}}
printf("Do dai Max :=%4d",L[0]-2);
// Hiển thị các cuộc họp được chọn
printf("\nDanh sach cuoc hop can tim la:=");
Trang 162 Chương trình cải tiến.
a Mô tả.
- Đầu vào : File Input.txt ( hoặc Input1.txt kết quả thực nghiệm)
- Chương trình:
Thuật toán sắp xếp nhanh Phức tạp O(NlogN)
Thuật toán cải tiến Phức tạp O(NlogN)
if(i <= j){
if (i < j){
swap(int, [i], b[j]);
swap(int, a[i], a[j]);
}i++;
j ;
}}
Trang 17//bay gio ta co 1 mang : a[l] a[j] a[i] a[r]
if (l < j) quickSort(a,b l, j); // lam lai voi mang a[l] a[j]
if (i < r) quickSort(a,b, i, r); // lam lai voi mang a[i] a[r]
Trang 18int VT[1001]; // Lưu lại vị trí mà L[i] đạt max
// fInp = fopen ("Input1.txt", "r");
fInp = fopen ("Input.txt", "r");
Trang 19ST[k]= i;
}}
fprintf(fOutp,"Do dai Max :=%4d",L[0]-2);
// Luu ket qua ra file
printf("Du lieu ket qua duoc ghi ra file, Hay mo file OutPut.txt de xem ket qua");fOutp = fopen("OutPut.txt","w");
fprintf(fOutp,"Do dai Max :=%4d",L[0]-2);
fprintf(fOutp,"\nDanh sach cuoc hop can tim la:={");
Trang 20fclose(fOutp);
// hien thi ket qua ra man hinh
printf("\nDo dai Max :=%4d",L[0]-2);
printf("\nDanh sach cuoc hop can tim la:=");
}
printf("}");
getch();
}
Trang 21Tài liệu tham khảo
[1] Quy hoạch động – wiki.
[2] Dynamic Programing – Phân tích và đánh giá thuật toán – Đào Thanh Tĩnh – HV Kỹ Thuật Quân sự.
[3] Cấu trúc dữ liệu và thuật giải – Tạ Thúc Nhu – Đại học Lạc Hồng [4] Lý thuyết quy hoạch động và áp dụng – Nguyễn Khắc Nho.
[5] Giáo trình lập trình C – Đại học FPT.