You are on page 1of 22

TRƯỜNG ĐẠI HỌC SƯ PHẠM TPHCM

LOGO KHOA CÔNG NGHỆ THÔNG TIN


LỚP TIN HỌC KHÓA 35

BÁO CÁO BÀI TẬP LỚN


MÔN: CẤU TRÚC DỮ LIỆU 2

GVHD: ThS. NGUYỄN THỊ BÍCH NGÂN


THỰC HIỆN: NHÓM 25
NGUYỄN NGỌC NHẤT LINH
ĐINH VĂN QUYÊN
ĐỀ BÀI
 Tên đề bài: Bố trí phòng họp.
 Mô tả: Có n cuộc họp, cuộc họp thứ i bắt đầu
vào thời điểm si và kết thúc ở thời điểm fi.
Do chỉ có một phòng hội thảo nên 2 cuộc
họp bất kì sẽ được cùng bố trí phục vụ nếu
khoảng thời gian làm việc của chúng chỉ giao
nhau tại đầu mút. Hãy bố trí phòng họp để
phục vụ được nhiều cuộc họp nhất.
PHÂN TÍCH BÀI TOÁN
 Giả sử ta có một tập S = {1, 2, …, n} gồm n cuộc
họp nhưng chỉ có 1 phòng hội thảo nên chỉ có
thể được dùng cho một cuộc họp tại một lúc.
 Mỗi cuộc họp i có thời điểm bắt đầu si và một
thời điểm kết thúc fi, mà si ≤ fi. Nếu được lựa
chọn, cuộc họp i diễn ra trong thời khoảng [si, fi).
Cuộc họp i và j là tương thích nếu thời khoảng
[si, fi) và [sj, fj) không phủ lấp lên nhau (tức là, i
và j là tương thích nếu si >= fj hay sj >= fi).
MĐFBM HDJF HJFD JDKF
PHÂN TÍCH BÀI TOÁN

S1 S2 F1 S3 F2 F3

CuỘC HỌP 1

CuỘC HỌP 2

CuỘC HỌP 3

Khởi tạo: A={1}

S2<F1  không chọn cuộc họp 2


S3>F1  chọn cuộc họp 3. A={1;3}
GIẢI THUẬT SƠ BỘ
 Trong thủ tục áp dụng giải thuật tham lam để
giải bài toán bố trí cuộc họp, ta cần phải sắp
các cuộc họp theo thứ tự tăng của thời điểm
kết thúc: f1 ≤ f2 ≤ … ≤ fn.
procedure MEETING-SELECTOR(S, f) ; /* S là mảng giữ
thời điểm bắt đầu và f là mảng giữ thời điểm kết
thúc */
begin
n := length[s]; A := {1}; i: = 1;
for j: = 2 to n do
if sj >= fi then /*i tương thích với mọi
cuộc họp trong A */
begin A: = A ∪ {j}; i: = j end
end
TỔ CHỨC DỮ LIỆU
int s[MAX];//lưu thời gian bắt đầu
cuộc họp
int f[MAX];//lưu thời gian kết thúc
cuộc họp
char *name[MAX];//Lưu tên khoa có
cuộc họp
int luu[MAX];//Lưu cuộc họp đã xếp
lịch
int n;//số cuộc họp có thể có
int dem=0;//lưu tổng số cuộc họp
hiện tại đã được bố trí
CÁC HÀM CHÍNH

void nhapDuLieuCuocHop();
void sapXep();//sắp xếp tăng theo
thời gian kết thúc
void boTriLichHop();
void xuatLichHop();
HÀM BỐ TRÍ LỊCH HỌP
void boTriLichHop()
{
//dem=0;
luu[dem]=0;
for(int i=1; i<n; ++i)
{
if(s[i]>=f[luu[dem]])
{
dem++;
luu[dem]=i;
}
}
}
THÍ DỤ
i si fi
1 1 3
2 5 7
3 8 10
4 6 11
5 11 14
6 15 17
7 17 19
8 19 26
9 23 25
10 24 29
NHẬN XÉT

 Giải thuật tham lam áp dụng vào bài toán lựa


chọn một khả năng tối ưu cục bộ với hy vọng
sẽ dẫn đến một lời giải tối ưu toàn cục.
 Giải thuật không nhất thiết đem lại lời giải tối
ưu. Tuy nhiên thủ tục void boTriLichHop() ở
trên thường tìm được một lời giải tối ưu cho
một thể hiện của bài toán bố trí phòng họp.
MỘT HƯỚNG ĐI KHÁC…

 Giả sử dãy cuộc họp đã được sắp xếp tăng


dần theo thời gian kết thúc.
 Hàm mục tiêu : y = độ dài dãy cuộc họp
được sắp
 Gọi L(i) là độ dài dãy cuộc họp được sắp dài
nhất, các phần tử lấy trong miền từ 1 đến i
và phần tử cuối cùng là i.

1 2 3 … i i+1 Dãy cuộc họp


PP QUY HOẠCH ĐỘNG

 Nhận xét: Với cách làm này ta đã chia 1 bài


toán lớn (dãy con của n cuộc họp) thành các
bài toán con cùng kiểu có kích thước nhỏ
hơn (dãy con của dãy có i cuộc họp đầu
tiên). Vấn đề là công thức truy hồi để phối
hợp kết quả của các bài toán con.
PP QUY HOẠCH ĐỘNG

 Ta có công thức QHĐ để tính L(i) như sau:


 L(0) = 1. (Hiển nhiên)
 L(i) = 1+ LMax với LMax=max{L(j), với mọi
phần tử j: 0≤j<i và fj≤si}
 Tính L(i) : phần tử đang được xét là i .Ta tìm
đến phần tử j có fj <si có L(j) lớn nhất. Khi đó
nếu bổ sung i vào sau dãy con j cuộc họp
đầu tiên ta sẽ được dãy cuộc họp được sắp
dài nhất xét từ 0 đến i.
TỔ CHỨC DỮ LIỆU
 s[MAX], f[MAX], *name[MAX], n, luu[MAX]
giống như khai báo ở trên
 int truoc[MAX];//truoc[i] luu chi so cua
cuoc hop da duoc sap xep truoc cuoc hop
thu i
 int L[MAX];//phan tu L[i] luu so luong
cuoc hop da duoc sap xep trong day i+1
cuoc hop dau tien
 int LMax;//luu so phan tu lon nhat hien
tai cua day con s[i]
 int luuj=-1;//luu vi tri ma BMax thay doi
 int y;//ham muc tieu - so cuoc hop lon
nhat co the sap
TẠO BẢNG

 TH riêng đơn giản nhất: khi i=0:


 L[0]=1 (hiển nhiên)
 truoc[0]=-1
 TH i>0:
 Đặt LMax={L[j]: f[j]<=s[i], 0<=j<i}
 L[i]=LMax+1;
 truoc[i]=j tương ứng khi tìm thấy LMax
TẠO BẢNG

 Ví dụ:
i 0 1 2 3 4 5 6 7
s[i] 1 4 3 12 11 10 14 27
f[i] 3 6 9 13 18 22 27 31
L[i] 1 2 2 3 3 3 4 5
truoc[i] -1 0 0 1 1 1 3 6
TẠO BẢNG
 HÀM TẠO BẢNG
void taoBangLichHop()
{
//TH i=0
L[0]=1;
truoc[0]=-1;
//TH i>0
for(int i=1; i<n; ++i)
{
LMax=0;
for(int j=0; j<i; ++j)
if(f[j]<=s[i] && LMax<L[j])
{
LMax=L[j];
luuj=j;
}
L[i]=LMax+1;
truoc[i]=luuj;
}
}
TRA BẢNG
 Chiều dài dãy cuộc họp được sắp dài nhất là
Max{L[i]} với i=1..n-1
 Dựa vào mảng truoc[] ta tìm được dãy cuộc
họp cần tìm.
 Ví dụ:

i s[i] f[i] truoc[i]


7 27 31 6
6 14 27 3
3 12 13 1
1 4 6 0
0 1 3 -1
 Output là 0 1 3 6 7
Dừng
TRA BẢNG
 HÀM TRA BẢNG:
void traBangLichHop()
{
int i=0;
for(int j=1; j<n; ++j)
if(L[i]<L[j])
i=j;
int max=y=L[i]-1;//i la chi so co L[i] lon nhat
// vi mang trong C++ bat dau tu 0 nen phai -1
while(i>-1)
{
luu[max--]=i;
i=truoc[i];
}
}
NHẬN XÉT
 Giải thuật Quy hoạch động có ưu thế hơn giải
thuật Quay lui khi biết lợi dụng những bài
toán con trùng lắp bằng cách giải mỗi bài toán
con một lần, cất lời giải vào trong một bảng mà
bảng này sẽ được tham khảo đến khi cần.
 Giải thuật Quy hoạch động sẽ đưa ra một lời
giải tối ưu hơn so với giải thuật Tham lam. Tuy
nhiên, giải thuật Quy hoạch động thường có độ
phức tạp không dưới O(n2) nên khi không gian
bài toán lớn thì thời gian chạy là không thể
chấp nhận được.
TÀI LIỆU THAM KHẢO
 PGS.TS Dương Tuấn Anh, Bài giảng điện tử
Phân tích và Thiết kế giải thuật.
 Trần Hữu Quốc Thư, Giáo trình Phân tích
thiết kế giải thuật.
 ThS. Nguyễn Thị Bích Ngân, Một số bài toán
quy hoạch động điển hình.
 Và một số tài liệu khác từ Internet.
THE END

CẢM ƠN CÔ VÀ CÁC BẠN


ĐÃ QUAN TÂM THEO DÕI

You might also like