1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài toán xếp lịch

7 1,9K 11
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 7
Dung lượng 29,66 KB

Nội dung

Bài toán xếp lịch

Trang 1

Bài toán xếp lịch

18 Tháng Ba 2011

11:48 SA

Ứng dụng thuật toán tô màu đồ thị để giải quyết Bài toán xếp lịch

Giới thiệu bài toán

Bài toán xếp lịch có một lịch sử phát triển dài, trải qua nhiều sự thay đổi lớn Kể từ những thế hệ đầu tiên

của máy tính,người ta đã nghĩ đến việc sử dụng máy tính để trợ giúp người xếp lịch Ban đầu đó chỉ là những

công cụ trợ giúp cho việc phân công những công việc điều hành phối hợp Sau này mới thực sự được phát triển

thành những công cụ xếp lịch cụ thể

Bài toán xếp lịch được chia thành những lớp bài toán cụ thể sau:

- Xếp thời khoá biểu Thường được sử dụng trong các trường Phổ thông, Đại học

- Xếp lịch thi Được quan tâm mỗi khi kì thi tuyển sinh Đại học hoặc thi học kì ở các trường Đại học và Cao đẳng

- Xếp lịch công tác cán bộ Được sử dụng chủ yếu ở các cơ quan, tổ chức lớn

Tuy nhiên trong bài báo này chúng ta chỉ quan tâm đến bài toán xếp lịch thi trong các trường Đại học

Phát biểu bài toán

Bài toán được phát biểu như sau: Vào cuối mỗi một học kì, các trường đại học phải tổ chức một đợt thi cho từng

khoa hoặc cả trường

Trường có một nhiều phòng thi, các phòng có kích cỡ khác nhau (khả năng chứa thí sinh)

Mỗi lớp có thể được chia thành nhiều nhóm thi, mỗi nhóm thi thi trong một phòng, mỗi phòng có thể có nhiều

nhóm cùng thi Và tổng số lượng thí sinh của các nhóm phải nhỏ hơn hoặc bằng kích cỡ của phòng

Kì thi được chia thành các đợt thi Mỗi nhóm sẽ thi một môn trong một đợt thi

Yêu cầu chặt chẽ: có một số môn thi không được thi cùng đợt với môn thi khác, các nhóm của cùng một lớp

(nếu có thể) phải thi trong cùng một đợt

Ta có thể chia bài toán trên thành 2 bài toán đơn giản hơn:

- Phân bổ các nhóm thi vào các đợt thi sao cho chúng không xung đột nhau (không vi phạm ràng buộc)

Xây dựng một đồ thị G, với mỗi đỉnh là một nhóm, nối cạnh giữa hai đỉnh mà nhóm của chúng có ràng

buộc với nhau, tìm cách tô màu và sắc số p của đồ thị G Số p là giới hạn dưới của số các đợt thi Các

đỉnh được tô cùng màu có nhóm tương ứng được xếp vào một đợt thi

Trang 2

- Tìm cách xếp các nhóm trong một đợt thi (đã tìm được ở trên) vào các phòng thi của trường

Bài toán tô màu đồ thị và sắc số đồ thị

Cho trước một số nguyên dương P, ta nói rằng đồ thị G có P sắc có nghĩa là: chỉ bằng P màu khác

nhau ta có thể tô màu tất cả các đỉnh sao cho 2 đỉnh liền kề bất kỳ có màu khác nhau Khi số p nhỏ

nhất thì ta gọi P là sắc số của đồ thị và việc tìm cách tô P màu lên đồ thị chính là bài toán tô màu đồ thị

Ví dụ:

Việc tô màu bản đồ hành chính, ta phải tô màu các nước sao cho: mỗi Quốc gia được tô một màu,

hai nước có liền kề (có chung biên giới) không được tô cùng một màu

Ta thiết lập một đồ thị G, có tập các đỉnh là tập tất cả các quốc gia trên bản đồ Hai nước liền kề nhau

thì có cạnh nối hai đỉnh tương ứng với nhau Ta tiến hành tìm sắc số của đồ thị này Đây là trường hợp riêng của bài toán tô màu đồ thị Khi đồ thị chỉ là đồ thị phẳng Người

ta đã chứng

minh được rằng: chỉ cần nhiều nhất là 4 màu để tô đồ thị này Từ lâu người ta đã chứng minh bài toán

tô màu đồ thị thuộc lớp NP - đầy đủ Tuy nhiên nếu dùng một chiến thuật thuật hợp lý thì kết quả thu được

cũng có thể chấp nhận được

Thuật toán tìm sắc số của đồ thị (Thuật toán 1):

Giả sử chúng ta có một đồ thị chứa các đỉnh x và y G: xy là một đồ thị thu được từ đồ thị G bằng

cách thay thế hai đỉnh x và y bằng một đỉnh, đỉnh đó có cạnh nối tới tất cả các đỉnh kề với đỉnh x, y

hoặc cả x lẫn y Hay là hai đỉnh x và y đã được nhập với nhau Đồ thị G - {x} là một đồ thị thu được

từ đồ thị G bằng cách loại bỏ đỉnh x cùng với tất cả các cạnh nối tới đỉnh x đó Một đồ thị trống là đồ

thị không chứa một đỉnh hay một cạnh nào Hai đỉnh gọi là kề nhau nếu có cạnh nối với nhau

Với một đỉnh x bất kỳ, ta xây dựng một tập các bộ 3 như sau:

Graph Code:

L ựa chọn code | Ẩ n/Hi ệ n code (x, z(1,1), y1)

(x, z(1,2), y1)

(x, z(1,m1), y1)

Trang 3

(x, z(i,1), yi)

(x, z(i,2), yi)

(x, z(i,mi), yi)

(x, z(n,mn), yn)

Trong đó đỉnh thứ nhất kề với đỉnh thứ hai, đỉnh thứ 2 kề với đỉnh thứ 3 Và không tồn tại một bộ 3 nào mà:

đỉnh thứ nhất kề hoặc trùng với đỉnh thứ 3 Từ tập các bộ 3 đó, ta tìm các đỉnh yi sao cho có:

mi = max(m1, m2, , mn) và đặt yi = x Nếu có nhiều đỉnh y đạt max ta chọn đỉnh đầu tiên

Ta có thể hình dung: Chọn một đỉnh trong số những đỉnh không kề với đỉnh x, kề với đỉnh (đỉnh trung gian)

kề với đỉnh x, có số đỉnh trung gian là lớn nhất

Các bước của thuật toán (đồ thị G là dữ liệu vào):

Bước 1: Đặt j = 1, H=G

Bước 2: Đặt vj là đỉnh có bậc cao nhất trong H

Bước 3: Từ vj xây dựng tất cả các bộ 3 như trên và tìm đỉnh x Nếu không tìm được x, trong trường hợp

không tìm được bộ 3 nào, chọn một đỉnh có bậc lớn nhất không kề với vj

Bước 4: Nhập x vào vj và quay lại bước 3 cho tới khi không chọn được một đỉnh nào nữa thì quay lại bước 2

với : H=H-{vj}, j=j+1

Bước 5: Khi không còn một đỉnh nào còn lại trong H, dựng lại và tô màu i cho tất cả các đỉnh được

nhập vào vi với (1 =< i =< j) Khi đó j là sắc số của đồ thị G

Cài đặt:

Dữ liệu:

Mảng hai chiều M chứa ma trận thể hiện đồ thị n đỉnh

Mảng 1 chiều n phần tử: Color đánh dấu màu của đỉnh i là Color[i]

Mảng 1 chiều n phần tử: Merged, Merged[i]=true nếu đỉnh i đã bị nhập vào 1 đỉnh khác Sắc số của đồ thị: Cromatic

Một số thủ tục và hàm sử dụng trong chương trình:

Procedure Input; Nhập ma trận thể hiện đồ thị G từ file

Trang 4

Procedure Output; Xuất mảng Color[i] là màu của đỉnh i ra file.

Function Degree(x:byte):byte; Tính bậc của đỉnh x, bậc của đỉnh x là số đỉnh chưa bị nhập vào đỉnh

khác (hay Merge[I]=false) có cạnh nối với x (M[x,i]=true)

Function MaxDegree:byte; Trả lại đỉnh chưa được tô màu (Color[i]=0) và có bậc lớn nhất (Degree(i) * Max)

Function NumIntermediate(x,y:byte):byte; Trả về số đỉnh trung gian giữa hai đỉnh x và

y (Đỉnh i là trung gian

của x và y (i<>x; i<>y; Merged[i]=false; M[x,i]=true và M[i,y]=True)

Function MaxIntermediate(x:byte):byte; Trả về đỉnh có số đỉnh trung gian với đỉnh x là lớn nhất

NumIntermediate(x,I) * Max

Function Merge(i,x:byte); Nhập đỉnh I vào đỉnh x Tìm tất cả các đỉnh chưa nhập vào đỉnh

nào có cạnh nối với đỉnh i (Merged[j]=false; M[i,j]=true), nối đỉnh đó với đỉnh x

(M[j,x]:=true;M[x,j]:=true),

xoá cạnh nối giữa đỉnh đó với đỉnh i (M[i,j]:=0;M[j,i]=0)

Function NonMaxDegree(x:byte):byte; Tương tự như hàm MaxDegree, tìm đỉnh khác đỉnh x (i<>x),

không có cạnh nối với x (M[i,x]=false) có bậc lớn nhất (Degree(i) * Max)

Chương trình chính:

Pascal Code:

Lựa chọn code | Ẩn/Hiện code

Procedure main;

var ncol,m,i,mx:byte;

Begin

input;

ncol:=0;{Đặt màu ban đầu bằng 0}

m:=MaxDegree;{m là đỉnh có bậc lớn nhất}

while(m<>0) do {Nếu đồ thị chưa rỗng}

begin

inc(ncol) {Tăng màu, sắc số đồ thị tại vòng lặp này}

color[m]:=ncol;{tô màu đỉnh m}

mx:=MaxIntermediate(m); {mx là đỉnh có số đỉnh trung gian với

đỉnh m là lớn nhất}

if (mx=0) then mx:=Non_MaxDegree(m) {Không tìm được đỉnh có đỉnh

trung gian với đỉnh m, tìm đỉnh không kề với m có bậc lớn nhất}

while(mx<>0) do

begin

Merge(mx,m) {Nhập mx vào m}

color[mx]:=ncol; {Tô màu cho đỉnh mx, mx có cùng màu với đỉnh m}

mx:=MaxIntermediate(m)

if (mx=0) then mx:=Non_MaxDegree(m)

{Tiếp tục tìm đỉnh mx như trên cho đến khi không còn tìm được nữa}

end;

m:=MaxDegree;{m là đỉnh có bậc lớn nhất trong đồ thị còn lại,

nếu m=0 thì đồ thị đã rỗng và việc tô màu đã hoàn thành}

Trang 5

end;

Cromatic:=ncol;{Đặt sắc số của đồ thị là ncol}

Ouput;

End;

Thuật toán trên không phải là một thuật toán tốt trong mọi trường hợp, nhưng nó cố gắng để tìm một giải

pháp có thể chấp nhận được để tìm sắc số cho đồ thị

(Còn nữa)

Ứng dụng thuật toán tô màu đồ thị

Lê Thanh Hà

(Tiếp theo số trước)

Thuật toán xếp các nhóm thi vào các phòng thi (Thuật toán 2):

Sắp xếp các nhóm thi tăng dần theo 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 theo thứ 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 1: Đặt i=1 , j=1, D1=phi

Bước 2: Nếu |ei| =< |Rj| thì thêm ei vào Rj

Ngược lại đặt j=j+1, lặp lại Bước 2

Bước 3: Đặt k = j

Bước 4: Nếu ³ |Rk|, tìm tập các nhóm trong Rk sao cho tổng số số lượng của các nhóm lớn nhất, nhưng chứa được trong Rk hay

Nếu k=m đặt Di+1 = Di hợp {các nhóm còn lại}

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

Bước 5: Đặt i = i+1

Nếu i =< n, lặp lại bước 2

Thuật toán bắt đầu xếp lần lượt từ 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ào phò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ững nhóm không thể xếp vào các phòng trong đợt thi này

Cài đặt:

Trang 6

Cấu trúc dữ liệu

Mảng 1 chiều chứa kích thước của n nhóm đã được sắp xếp tăng dần: E, E[i] là số thí sinh trong nhóm i

Mảng 1 chiều chứa sức chứa của m phò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ộc phò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ả

Các thủ tục và hàm sử dụng trong chương trình:

procedure input; Nhập hai mảng E vả 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

Pascal Code:

L ựa chọn code | Ẩ n/Hi ệ n code

procedure PushUp(k:byte; sum:integer) {Đẩy nhóm lên phòng có kích thước lớn hơn}

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 đó đi thì phòng đó chứa đủ số nhóm còn lại}

begin

if (k<m) then{Nếu chưa phải là phòng cuối cùng}

p[i]:=k+1{đẩy nhóm lên phòng cao hơn}

else

p[i]:=DUD;{Không xế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 đẩy 1 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ổng số thí sinh được đẩy ra là nhỏ nhất, càng ít thí sinh bị đẩy ra thì càng tốt}

function SumK(k:byte):integer; Tính tổng số thí sinh trong phòng k

Chương trình chính:

Pascal Code:

L ựa chọn code | Ẩ n/Hi ệ n code

procedure main;

var i,,k,t:byte;

sum:integer;

Begin

Input;

for i:=1 to n do {Bắt đầu từ nhóm có số thí sinh nhỏ nhất}

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

p[i]:=j; {Đặt nhóm i vào phòng j}

break;

Trang 7

end;

k:=j;

sum:=SumK(k); {Tính số thí sinh trong phòng k}

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

PushUp(k,sum) {Đẩy một số nhóm lên phòng có sức chứa lớn hơn}

inc(k)

sum:=SumK(k) {Làm tương tự đối với phòng trên}

end;

end;

Ouput;

end;

Lập lịch thi theo hai thuật toán trên

Hai thuật toán trên đã được xây dự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 đối tố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ện trên

đồ thị G Mỗi nhóm là một đỉnh của đồ thị, hai đỉnh có cạnh nối với nhau nếu hai nhóm tương ứng xung đột nhau

Đồ thị G là dữ liệu vào

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òng thích hợp Những nhóm chưa được xếp (nằm trong DUD) sẽ được xếp trong đợt thi sau

Bước 4: Đặt p = p+1

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ằm trong DUD, ta có đồ thị G’ Nếu G’ là một đồ thị rỗng, việc xếp thời khoá biểu hoà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ạo tậ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ủa hai 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ài toá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ũng phần nào đã được giải quyết

(Nguồn: Báo Tin Học Nhà Trường, tác giả Lê Thanh Hà)

Ngày đăng: 23/01/2013, 09:14

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w