Professional Documents
Culture Documents
Lê Thanh Hà
Thuật toán xếp các nhóm thivào các phòng thi (Thuật toán 2):
Sắp xếp các nhóm thi tăng dầntheo số lượng thí sinh trong nhóm e1, e2,..., en.Kí hiệu |ei| là
số lượng của nhóm ei.
Tương tự sắp xếp các phòng theothứ tự tăng dần theo kích cỡ R1, R2,..., Rn.Kí hiệu |Ri| là
độ lớn của phòng thi Ri.
Bước 3: Đặt k = j.
Bước 4: Nếu ≥ |Rk|, tìm tập các nhóm trong Rk sao chotổng số số lượng của các nhóm lớn
nhất, nhưng chứa được trong Rkhay.
Ngược lại đặt chúng vào Rk+1, k = k+1, Di+1 = Di và lặp lại bước 4.
Thuật toán bắt đầu xếp lần lượttừ nhóm nhỏ nhất trong danh sách vào các phòng. Thuật
toán đặt mỗi nhóm vàophòng nhỏ nhất có thể chứa nó. Nếu số lượng thí sinh trong phòng
đó lớn hơn khảnăng chứa của phòng, thuật toán sẽ đẩy một số ít thí sinh nhất lên phòng
cókích thước lớn hơn. Nếu số phòng đã hết trong khi số nhóm vẫn còn, thì số nhómđó sẽ
được đặt trong tập DUD (tập Di ở vòng lặp cuối cùng), tập DUD chứa nhữngnhóm không
thể xếp vào các phòng trong đợt thi này.
Cài đặt:
Mảng 1 chiều chứa sức chứa của mphòng đã được sắp xếp tăng dần: R, R[i] là sức chứa
của phòng i.
Mảng 1 chiều xác định nhóm thuộcphòng: p, p[i] là chỉ số phòng mà nhóm i thuộc.
P[I]=DUD=m+1 nếu phòng đó khôngđược xếp vào một phòng nào cả.
procedure input; Nhập hai mảng Evả R, khởi tạo tất cả các phòng đều chưa được xếp
(p[i]=0). Chú ý: phòng chưađược xếp khác với phòng không được xếp (p[i]=DUD)
procedure output; Xuất mảng p thểhiện nhóm nào đã được xếp vào phòng nào.
var i:byte;
Begin
for i:=1 to n do
if (p[i]=k) and sum-e[i] ≤ r[k]) then {Tìm một nhóm thuộc phòng k sao cho nếu loại
nhóm
begin
else
p[i]:=DUD;{Khôngxếp phòng cho nhóm này, đẩy nhóm này vào tập DUD}
break;
end;
End;
{Chú ý: ở đây ta chỉ xét việc đẩy1 phòng ra, nếu muốn bạn có thể cài đặt đẩy số nhiều
nhóm ra hơn sao cho tổngsố thí sinh được đẩy ra là nhỏ nhất, càng ít thí sinh bị đẩy ra thì
càng tốt}
procedure main;
var i,j,k,t:byte;
sum:integer;
Begin
Input;
begin
for j:=1 to m do
if (e[i] ≤ r[j])then {Tìm phòng nhỏ nhất có thể chứa được nhóm i}
begin
break;
end;
k:=j;
while(sum>r[k]) do{Nếu số thí sinh lớn hơn khả năng chứa của phòng k}
begin
inc(k);
sum:=SumK(k);{Làmtương tự đối với phòng trên}
end;
end;
Ouput;
end;
Hai thuật toán trên đã được xâydựng xong. Thuật toán thứ nhất dùng để phân chia các
nhóm thành những tập hợpđộc lập với nhau. Thuật toán thứ hai sẽ xếp các tập đó vào các
phòng thích hợp.Ta có thể sử dụng cả hai thuật toán để được một công cụ xếp lịch thi
tương đốitốt.
Cho một số phòng thi, cho các nhóm thi và các ràng buộc của chúng được thể hiệntrên đồ
thị G. Mỗi nhóm là một đỉnh của đồ thị, hai đỉnh có cạnh nối với nhaunếu hai nhóm
tương ứng xung đột nhau.
Bước 1: Đặt p = 1.
Bước 2: Dùng thuật toán 1để tìm ra một tập các nhóm không xung đột với nhau, tập I.
Bước 3: Từ tập I, sử dụng thuật toán 2 để đặt mỗi nhóm trong I vào phòngthích hợp.
Những nhóm chưa được xếp (nằm trong DUD) sẽ được xếp trong đợt thisau.
Bước 5: Xoá tất cả cácđỉnh (và các cạnh nối đến chúng) trong I trừ các đỉnh có nhóm
tương ứng nằmtrong DUD, ta có đồ thị G. Nếu G là một đồ thị rỗng, việc xếp thời khoá
biểuhoàn thành.
Bước 6: Bắt đầu với từ đỉnh được nhập bởi nhiều đỉnh mà nhóm tương ứng cótrong
DUD. Nếu DUD rỗng chọn đỉnh có bậc lớn nhất. Sử dụng thuật toán 1 để tạotập I mới có
từ đồ thị G. Đặt G = G, Quay lại bước 3.
Thuật toán trên là tổng hợp củahai thuật toán đã trình bày trước. Cài đặt thuật toán này
không quá khó khăn.Bạn có thể tự mình cài đặt được.
Bài toán xếp lịch, cụ thể là bàitoán xếp lịch thi tuy đã được chứng minh là thuộc lớp bài
toán NP-đầy đủ(NP-complete), nhưng nếu biết sử dụng một một chiến thuật thuật toán
hợp lýcùng với sự phát triển như vũ bão của công nghệ máy tính bài toán trên cũngphần
nào đã được giải quyết.