Professional Documents
Culture Documents
Đỗ Huy Thịnh
HÀ NỘI – 2006
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Đỗ Huy Thịnh
HÀ NỘI – 2006
LỜI CẢM ƠN
Lời đầu tiên em xin bày tỏ lòng biết ơn sâu sắc tới thầy giáo PGS.TS.Nguyễn
Văn Vỵ, thầy đã tận tình hướng dẫn giúp em hoàn thành khóa luận.
Em xin bày tỏ lòng biết ơn tới các thầy cô giáo trong khoa Công nghệ thông tin
- Trường Đại học Công nghệ - ĐHQGHN. Các thầy cô đã dạy bảo và luôn tạo điều
kiện tốt nhất cho chúng em học tập trong suốt quá trình học đại học đặc biệt là trong
thời gian làm khóa luận tốt nghiệp.
Tôi xin cảm ơn các bạn sinh viên lớp K47CA trường Đại học Công nghệ,
những người bạn luôn bên cạnh ủng hộ tôi trong suốt những năm học đại học.
Cuối cùng con xin gửi tới Bố Mẹ và gia đình tình thương yêu và lòng biết ơn.
Bố mẹ luôn là nguồn động viên và là chỗ dựa vững chắc cho con.
Hà Nội, ngày 20 tháng 5 năm 2006
Sinh viên
Đỗ Huy Thịnh
♦ Chương I: Giới thiệu bài toán lập thời khóa biểu nói chung và bài toán
lập thời khóa biểu học kỳ mà khóa luận giải quyết.
♦ Chương II: Giới thiệu tổng quan và trình bày các thành phần của ngôn
ngữ ràng buộc đối tượng.
♦ Chương III: Giới thiệu tổng quan và cấu trúc khung làm việc thông qua
một số ví dụ.
♦ Chương IV: Phân tích, thiết kế và cài đặt hệ thống cho bài toán xếp thời
khóa biểu học kỳ.
♦ Tìm một thuật toán kiểu heuristic đủ đơn giản để giải bài toán. Do đó dễ cải
biên mỗi khi thêm ràng buộc.
♦ Sử dụng hai công nghệ tiên tiến là Framework và lập trình ràng buộc. Vì lớp bài
toán thời khóa biểu có phần lõi chung, nên Framework trợ giúp thiết kế xây
dựng ứng dụng cho lớp này dễ dàng thay đổi ràng buộc bổ sung. Còn lập trình
ràng buộc trợ giúp việc lâp trình có ràng buộc tiện lợi, nhanh chóng.
Chương 1.
Là loại thời khóa biểu khuôn dạng tuần, tuy nhiên thời gian phân bố cho thời
khóa biểu được chia làm nhiều khoảng trong một học kỳ hay năm học. Với mô hình
này các môn học được sắp xêp không dàn đều trong một học kỳ mà thường co dãn
trong những khoảng thời gian nhỏ hơn.
♦ Giáo viên giảng dạy: người trực tiếp giảng dạy theo các học phần môn học
được quy định chặt chẽ về thời lượng kiến thức và hình thức học.
♦ Phòng học: địa điểm học các môn và bài giảng do giáo viên đảm nhận.
♦ Học sinh: đối tượng học tập trực tiếp của giáo viên giảng dạy. Học sinh được
phân công vào các lớp học. Do có hai kiểu lớp học khác nhau tạo nên sự khác
biệt của mô hình Thời khóa biểu:
♦ Mô hình lớp học niên chế: học sinh nhập học và phân cố định vào lớp
theo năm học. Mô hình lớp này đơn giản về mặt tổ chức, quản lý nhưng
lại phức tạp trong việc xếp Thời khóa biểu.
♦ Mô hình lớp học tín chỉ: học sinh tự do đăng ký vào các bài giảng đã
chuẩn bị trước của thời khóa biểu. Các lớp học thực chất là các bài giảng
được thiết kế thời khóa biểu giảng dạy chi tiết. Thường thì sau khi thời
khóa biểu các lớp được lên kế hoạch thì học sinh mới căn cứ vào thời
khóa biểu cụ thể để đăng ký lớp học. Việc tổ chức Thời khóa biểu theo
lớp tín chỉ sẽ đơn giản hơn cho việc xếp Thời khóa biểu nhưng lại phức
tạp cho công việc quản lý chuyên môn đào tạo nhà trường.
1.1.3. Các đối tượng liên quan đến Thời khóa biểu
Các đối tượng liên quan trực tiếp đến Thời khóa biểu bao gồm: Giáo viên giảng
dạy, Phòng học và Môn học ( học phần giảng dạy):
♦ Giáo viên: trong mô hình bài toán xếp Thời khóa biểu vai trò các giáo viên là
ngang nhau. Mỗi giáo viên về nguyên tắc thuộc một Khoa hay Bộ môn và sẽ có
một Thời khóa biểu lịch giảng dạy riêng của mình trong học kỳ hay năm học
hiện thời.
♦ Môn học: môn học hay học phần là một đơn vị quản lý chính của chương trình
đào tạo và là đối tượng chính của cả hai mô hình lớp niên chế và tín chỉ. Chính
vì vậy môn học có vai trò quan trọng trong mô hình bài toán xếp Thời khóa
biểu. Mỗi môn học thuộc khoa hay bộ môn trực tiếp phụ trách và đặc trưng bởi
số đơn vị học trình ( thời lượng học).
♦ Phòng học: phòng học cũng đóng vai trò quan trọng trong bài toán xếp thời
khóa biểu. Phòng học đặc trưng bởi loại hình thức học ( lý thuyết, thực hành)
hay sức chứa và căn cứ vào đó phân công cho các lớp.
1.2. Bài toán lập thời khóa biểu giải quyết trong khóa luận
Trong khóa luận này chỉ xét bài toán lập thời khoá biểu cho trường đại học ở
Việt Nam mà cụ thể là trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội ( có thể
tổng quát cho các trường vẫn giảng dạy theo hệ lớp- môn- giáo viên giảng dạy).
Bài toán được phát biểu như sau:
Có một danh sách các lớp học học trong học kỳ, danh sách các môn học tương
ứng cho từng lớp học và danh sách giảng viên tương ứng với mỗi môn cho từng lớp.
Giảng đường cho mỗi lớp đã được xếp trước.
Một lời giải hay một thời khoá biểu chấp nhận được là tất cả các môn học được
chia vào các tiết học trong một tuần thoả mãn các điều kiện ngặt sau:
♦ Giảng viên không dạy hai lớp khác nhau ở cùng một thời điểm.
♦ Tại một thời điểm mỗi lớp học chỉ học một môn.
Thêm vào đó, một thời khoá biểu chấp nhận được sẽ được đánh giá bằng số vi
phạm các ràng buộc mềm được cho như sau:
♦ Giáo viên giảng dạy có không quá một tiết trống ở giữa các ca dạy trong ngày.
♦ Giáo viên giảng dạy có thể không dạy vào buổi nào đó.
♦ Lớp học có một ngày nghỉ ( ngoài chủ nhật) trong tuần.
1.2.1.1. Lên danh sách các lớp sẽ được học trong học kỳ
Vào đầu năm học, nhân viên phòng Đào Tạo phụ trách phần quản lí giảng dạy
và học tập phải ra kế hoạch lập thời khóa biểu. Trước tiên nhân viên phòng Đào Tạo sẽ
lập danh sách các lớp sẽ học trong học kỳ đó. Đồng thời gửi số lớp học về phòng Hành
Chính Tổng Hợp đề nghị chuẩn bị lớp. Phòng Hành Chính Tổng Hợp gửi lại danh
sách và qui mô phòng học cho phòng Đào Tạo.
1.2.1.2. Xác định môn học cho mỗi lớp ( lớp- môn)
Với mỗi lớp học trong danh sách ở trên, nhân viên phòng Đào Tạo đối chiếu
với chương trình đào tạo đã được áp dụng để đưa ra danh sách môn học của từng lớp.
Từ danh sách các môn học, nhân viên phòng Đào Tạo trích ra các môn học cho mỗi bộ
môn và số trình phải dạy và gửi về các bộ môn để bộ môn đăng kí hay phân công giáo
viên giảng dạy. Đồng thời gửi danh sách này cho lãnh đạo khoa để lấy ý kiến đánh giá
giúp cho việc chỉnh sửa bổ sung chương trình đào tạo được khoa học hơn.
1.2.2. Bảng tổng hợp các chức năng của hệ thống “Lập thời khóa biểu
học kỳ”
Bảng 1. Tổng hợp các chức năng hệ thống "Lập thời khóa biểu học kỳ"
1 Class Lớp
13 Department Bộ phận
Hình 1. Mô hình lĩnh vực nghiệp vụ bài toán xếp thời khóa biểu
Chương 2.
Trong mô hình, quan hệ giữa lớp Flight ( chuyến bay) và lớp Person ( khách
hàng), phía lớp Person có bản số là 0…* tức là số khách hàng là không giới hạn.
Trong thực tế số khách hàng bị giới hạn bởi số ghế mà máy bay có, và giới hạn này
không thể biểu diễn trong biểu đồ. Trong ví dụ này có một cách chỉ định ràng buộc về
bản số thể hiện là thêm vào biểu đồ ràng buộc OCL sau:
context Flight
inv: passengers-> size () <= plane.numberOfSeats
2.2.2. Ngôn ngữ dựa trên cơ sở toán học nhưng không có các ký hiệu
toán học
Đặc điểm nổi bật của OCL là xây dựng dựa trên cơ sở toán học. Nó dựa trên lý
thuyết tập hợp và logic vị từ. Tuy nhiên OCL lại không dùng các ký hiệu toán học.
Một ngôn ngữ mô hình cần sự chặt chẽ và chính xác của toán học nhưng lại đòi hỏi
đặc điểm dễ hiểu của ngôn ngữ tự nhiên. OCL dùng các khái niệm toán học nhưng bỏ
qua các ký hiệu khó hiểu của toán học. Thay vì dùng ký hiệu toán học để biểu diễn
cùng một khái niệm, OCL dùng các từ khóa dễ hiểu.
Lớp trung tâm của mô hình là LoyaltyProgram. Một hệ thống mà quản lý chỉ
một chương trình Loyalty đơn chứa chỉ một thể hiện của lớp này. Trong trường hợp
R& L, nhiều thể hiện của lớp này được biểu diễn trong hệ thống. Một công ty tham dự
chương trình mà cấp cho khách hàng thẻ thành viên trong chương trình Loyalty được
gọi là ProgramPartner. Có thể có nhiều công ty đăng ký cùng chương trình. Trong
trường hợp đó các khách hàng đăng ký chương trình Loyalty có thể thu lợi từ các dịch
vụ đưa ra do bất kỳ công ty tham dự nào.
Mọi khách hàng thành viên của chương trình có thể đăng ký chương trình
Loyalty bằng cách điền vào một form và nhận được một thẻ hội viên. Các đối tượng
của lớp Customer biểu diễn cho những người đã đăng ký chương trình. Thẻ thành
viên, biểu diễn bởi lớp CustomerCard, thuộc về một người. Một thẻ có thể dùng cho
cả gia đình hay cửa hàng. Hầu hết các chương trình Loyalty cho phép các khách hàng
tích lũy điểm thưởng. Mỗi công ty tham dự chương trình quyết định khi nào và bao
nhiều điểm thưởng sẽ chuyển khi khách hàng trả giá. Những điểm thưởng tích lũy
được có thể dùng để mua các dịch vụ cụ thể từ một trong các công ty tham gia chương
trình.
Để ghi lại điểm thưởng một khách hàng có được, mọi khách hàng thành viên
được kết hợp với một tài khoản LoyaltyAccount. Có 2 loại giao dịch đối với tài khoản
này. Thứ nhất là các giao dịch trong đó khách hàng nhận được điểm thưởng. Trong mô
hình các giao dịch này được biểu diễn bằng một lớp con Earning của lớp Transaction.
Thứ hai là các giao dịch trong đó khách hàng tiêu tốn điểm thưởng. Trong mô hình các
giao dịch loại này được biểu diễn bằng lớp con Burning.
Ngoài ra, căn cứ vào các dịch vụ đã sử dụng và lượng tiền chi trả mà khách
hàng có thể được xét lên khách hàng “vàng”. Khi đó khách hàng sẽ được sử dụng ưu
đãi các dịch vụ mức độ cao hơn. Để quản lý các cấp độ dịch vụ khác nhau dùng lớp
ServiceLevel. Một ServiceLevel được chương trình Loyalty định nghĩa và mỗi khách
hàng thành viên dùng.
Mỗi khi khách hàng thành viên được tăng bậc thẻ, R& L gửi tới khách hàng thẻ
mới cùng các thông tin về dịch vụ ưu đãi đi kèm, đồng thời làm mất hiệu lực thẻ cũ.
Khách hàng có thể rút khỏi chương trình. Khi đó thẻ của khách hàng đó sẽ mất
hiệu lực, số điểm thưởng còn lại bị xóa. R& L sẽ xóa quyền thành viên nếu khách hàng
không dùng thẻ trong một thời gian nhất định.
trong OCL) mà không gắn với các biểu đồ hay các thực thể trong biểu đồ. Có thể biểu
diễn quan hệ này bằng hai cách. Một là các biểu thức gắn với các thực thể cụ thể chỉ
có các hàm cụ thể. Ví dụ: một biểu thức định nghĩa một thuộc tính mới gắn với một
lớp, giao diện hay kiểu dữ liệu. Hai là thực thể mô hình UML mà có một biểu thức
được gắn vào xác định rõ các thực thể khác và có thể được tham chiếu. Ví dụ: một
biểu thức gắn với một lớp, tất cả các thuộc tính, kết hợp và phép toán truy vấn của lớp
đó được dùng.
Liên kết giữa một thực thể trong mô hình UML và một biểu thức OCL được gọi
là định nghĩa ngữ cảnh của biểu thức OCL đó.
Khi biểu thức OCL được viết trong một file text riêng, định nghĩa ngữ cảnh
được viết theo khuôn dạng: từ khóa context theo sau là tên của kiểu. VD:
context Customer
inv: name = 'Edward'
context Membership
inv: participants.cards.Membership.includes( self )
Có thể có hơn một biểu thức với mỗi ngữ cảnh và tùy theo ngữ cảnh mà biểu
thức OCL có các chức năng khác nhau.
Trong ví dụ trên bất biến được đặt tên là myInvariant23, chỉ ra ràng buộc tất cả
thể hiện của lớp Customer có tên là Edward.
Để chỉ ra biểu thức là định nghĩa, sau khai báo ngữ cảnh là từ khóa def , dấu hai
chấm: và biểu thức. Ví dụ :
context Customer
def: initial : String = name.substring(1,1)
context CustomerCard
def: getTotalPoints( d: Date ) : Integer =
transactions->select( date.isAfter(d) ).points->sum()
Trong trường hợp định nghĩa thuộc tính, tên và loại của thuộc tính phải được
chỉ ra, theo sau là dấu = và giá trị gán cho thuộc tính.
Tất cả các phương thức định nghĩa trong OCL là các thao tác truy vấn. Tên, các
tham số ( gồm cả kiểu dữ liệu) và giá trị trả lại phải được đưa ra.
2.4.3. Các thuộc tính và các đầu mút của liên kết
Chú ý rằng, có sự khác nhau giữa quy tắc dẫn xuất và giá trị khởi tạo. Quy tắc
dẫn xuất phát biểu một bất biến: thành phần dẫn xuất luôn nhận giá trị mà quy tắc đưa
ra. Một giá trị khởi tạo chỉ nhận ngay tại thời điểm tạo thể hiện ngữ cảnh. Sau đó,
thuộc tính có thể nhận giá trị khác tại các thời điểm khác.
Chú ý rằng, đối lập với các bất biến luôn đúng thì các điều kiện trước và sau chỉ
cần đúng tại thời điểm nhất định, lần lượt là trước và sau khi thực hiện các phương
thức.
(có tên gọi Liskov's Substitution) được phát biểu: bất cứ một thể hiện của một lớp được
tạo ra, nó luôn có thể thay thế một thể hiện của bất kỳ lớp con của nó. Các biểu thức
OCL tuân theo nguyên tắc này.
Trong mô hình trên có thể định nghĩa lớp cha Stove một bất biến : nhiệt độ của
nó không được lớn hơn 200 độ C
context Stove
inv: temperature <= 200
Sẽ rất nguy hiểm nếu một lớp con ElectricStove có thể vượt giới hạn nhiệt độ
đó. Ví dụ , giả sử ElectricStove có thể có nhiệt độ không vượt quá 300 độ C:
context ElectricStove
inv: temperature <= 300
Khi đó việc dùng ElectricStove sẽ không đảm bảo an toàn ở nơi nào mà Stove
được dùng. Nếu tại một nơi mà nhiệt độ an toàn báo động hoản hoạn là 250 độ C, có
thể đặt một Stove ở đó. Nhưng nếu đặt một Stove tại đó và Stove trở thành
ElectricStove, nơi đó có thể bị đặt báo động có hỏa hoạn.
Trong một số trường hợp, nguyên tắc Liskov’s Substitution cũng có những hạn
chế. Các lớp con có thể thay đối các phương thức lớp cha và thêm vào các phương
thức hay thuộc tính, khi đó các bất biến của lớp cha có thể được thay đổi để phù hợp
với sự biến đổi đó. Việc một bất biến trên một lớp cha có cần phải thay đối hay không
khi một lớp con được thêm vào phụ thuộc vào nội dung của bất biến.
Biểu thức trên có nghĩa là có thể mở một Stove khi trạng thái của nó là off. Sau
khi đã mở, trạng thái mong muốn là off và biến isOpen có giá trị true. Giả sử lớp con
ElectricStove định nghĩa lại phương thức open() với các điều kiện trước và sau khác:
context ElectricStove::open()
pre : status = StoveState::off and temperature <= 100
post: isOpen
Điều kiện trước của phương thức open() định nghĩa lại có một điều kiện mở
rộng ( temperature<= 100). Khi đó ElectricStove sẽ không thể mở dưới các điều kiện
mà Stove có thể mở. Để đảm bảo một ElectricStove có thể thay thế một Stove tiền điều
kiện khi định nghĩa lại open() không được chặt hơn.
Điều kiện sau của open() khi định nghĩa lại bị yếu đi vì điều kiện status=
StoveState::off bị loại bỏ. Kết quả là ElectricStove không thực hiện như một Stove (
sau khi mở Stove ở trạng thái off).
♦ Các kiểu cơ bản: gồm các kiểu dữ liệu số nguyên, số thực, xâu ký tự và logic (
tương tự các ngôn ngữ lập trình.)
Bảng 3. Các phép toán định nghĩa trên kiểu dữ liệu boolean
Toán tử Ký hiệu Kết quả trả về
hoặc a or b boolean
và a and b boolean
loại trừ a xor b boolean
phủ định not a boolean
bằng a=b boolean
khác a <> b boolean
bao hàm a implies b boolean
Các toán tử trong OCL đều phổ biến trong các ngôn ngữ lập trình trừ toán tử
implies. Phép toán này trả lại kết quả true nếu toán hạng thứ nhất có giá trị true và
toán hạng thứ hai cũng có giá trị true hoặc toán hạng thứ nhất có giá trị false.
Xét một VD của lớp Service từ ví dụ R & L ở trên. Kết quả của biểu thức sau có
giá trị true nếu một dịch vụ cung cấp điểm thưởng thì khách hàng không thể dùng
điểm thưởng để trả cho dịch vụ đó:
context Service
inv: self.pointsEarned > 0 implies not (self.pointsBurned = 0)
VD :
2654 * 4.3 + 101 = 11513.2
(3.2).floor() / 3 = 1
1.175 * (-8.9).abs() - 10 = 0.4575
12 > 22.7 = false
12.max(33) = 33
33.max(12) = 33
13.mod(2) = 1
13.div(2) = 6
33.7.min(12) = 12.0
-24.abs() = 24
(-2.4).floor() = -3
Trường hợp các phương thức hay thuộc tính không thuộc lớp trong biểu thức
OCL trước tên phương thức hay thuộc tính là dấu chấm ( .). Tuy nhiên có một hạn chế
trong OCL: các phương thức có thể trả lại giá trị nhưng không được thay đổi trạng thái
của bất kỳ đối tượng nào ( hay còn gọi là phương thức truy vấn). Theo các đặc tả
UML, mỗi phép toán có nhãn logic isQuery. Nếu nhãn có giá trị true, phép toán không
có tác dụng thay đổi đối tượng và có thể dùng trong các biểu thức OCL.
nối với đầu kết hợp. Trong ví dụ trên kiểu kết quả của điều hướng owner từ
CustomerCard là một kiểu người dùng định nghĩa Customer. Kiểu kết quả của cả
programs và cards từ Customer là các tập hợp.
Trong ví dụ hình trên có thể định nghĩa một bất biến dùng điều hướng owner từ
ngữ cảnh CustomerCard. Vì biểu thức OCL này cho kết quả một giá trị của kiểu
Customer, tất cả các thuộc tính và phương thức trong Customer có thể xuất hiện trong
biểu thức:
context CustomerCard
inv: self.owner.dateOfBirth.isBefore( Date::now )
context CustomerCard
inv: self.owner.programs->size() > 0
Trong hình MemberShip là một lớp kết hợp. Lớp này có ba điều hướng:
programs của kiểu LoyaltyProgram, participants của kiểu Customer, và currentLevel
của kiểu ServiceLevel. Bất biến sau phát biểu một mức dịch vụ thực sự của một thành
viên phải luôn là một mức dịch vụ của chương trình Loyalty chứa thành viên đó:
context Membership
inv: programs.levels->includes( currentLevel )
Cũng có thể điều hướng từ lớp kết hợp Customer và LoyaltyProgram tới
Membership. Do lớp kết hợp không có tên vai trò, tên của điều hướng là tên của lớp
kết hợp.
Bản số tại các đầu mút kết hợp sẽ quyết định kiểu của biểu thức. Nếu một ngữ
cảnh nào đó bản số lớn hơn 1, điều hướng tới lớp kết hợp sẽ cho kết quả một tập hợp
các thể hiện lớp kết hợp. Ngược lại, điều hướng sẽ cho kết quả một thể hiện lớp kết
hợp. Ví dụ, điều hướng từ Customer tới MemberShip sẽ cho kết quả là giá trị kiểu tập
hợp Set(LoyaltyProgram).
Bất biến sau cũng phát biểu tương tự bất biến ở trên, nhưng là từ ngữ cảnh của
LoyaltyProgram: tập các mức dịch vụ phải chứa tất cả các mức của tất cả các thành
viên. Chú ý rằng từ ngữ cảnh LoyaltyProgram, Membership.currentLevel là một kiểu
Bag(ServiceLevel). Do đó dùng phép toán includesAll thay cho includes:
context LoyaltyProgram
inv: levels->includesAll( Membership.currentLevel )
Các giá trị được định nghĩa trong <<enumeration>> có thể được dùng như các
giá trị trong một biểu thức OCL.
Ở VD trên lớp Customer thuộc tính isMale được thay đối thành gender. Bất
biến sau phát biểu các khách hàng nam tên phải bắt đầu bằng ‘Mr.’ :
context Customer
inv: gender = Gender::male implies title = 'Mr.'
Chỉ có hai toán tử dùng cho các giá trị liệt kê là toán tử = và <>.
Nếu có dãy số nguyên liên tiếp nhau, có thể biểu diễn theo dạng miền con
m…n. Ví dụ dãy [2…6] tương đương với {2, 3, 4, 5, 6}
2.7.1.4. Các thể hiện được đối xử như là các tập hợp
Do cú pháp của các phép toán tập hợp khác với các phép toán kiểu người dùng
định nghĩa nên có thể dùng một thể hiện đơn như một tập hợp. Tập hợp này được xem
như một tập thể hiện chỉ có một phần tử. Ví dụ , trong mô hình R & L, các ràng buộc
sau cho kết quả là giá trị của phép toán người dùng định nghĩa isEmpty() và một thể
hiện của LoyaltyAccount:
context Membership
inv: account.isEmpty()
Ngược lại, ràng buộc sau cho kết quả giá trị của phép toán isEmpty của tập Set,
trong đó account được dùng như một tập hợp:
context Membership
inv: account->isEmpty()
Biểu thức có giá trị true nếu liên kết từ thể hiện của MemberShip tới một thể
hiện của LoyaltyAccount rỗng, có nghĩa là MemberShip không gắn với
LoyaltyAccount.
Phép toán Mô tả
count( đối tượng ) Trả lại số các sự kiện của đối tượng trong tập hợp
excludes( đối tượng) Có giá trị true nếu đối tượng không là một phần tử của
tập hợp
excludesAll( tập hợp) Có giá trị true nếu tất cả phần tử của tập hợp ( tham
số) không ở trong tập hợp hiện tại
includes( đối tượng ) Có giá trị true nếu đối tượng là một phần từ của tập
hợp
includeAll( tập hợp ) Có giá trị true nếu tất cả các phần tử của tập hợp (
tham số) có trong tập hợp hiện tại
isEmpty() Có giá trị true nếu tập hợp không chứa phần tử nào
notEmpty() Có giá trị true nếu tập hợp chứa ít nhất một phần tử
size() Trả lại số các phần tử trong tập hợp
sum() Cộng tổng tất cả các phần tử trong tập hợp. Các thành
phần phải là một kiểu hỗ trợ phép cộng ( như số nguyên
hay số thực)
Các ví dụ sau dùng các phép toán includes và includesAll. Bất biến phát biểu
mức dịch vụ của mỗi thành viên phải là một trong các mức của chương trình mà thành
viên đó tham dự:
context Membership
inv: programs.levels ->includes(currentLevel)
Bất biến sau ràng buộc các dịch vụ có sẵn cho một mức dịch vụ được cung cấp
bởi một đối tác của chương trình Loyalty:
context ServiceLevel
inv: program.partners
->includesAll(self.availableServices.partner)
Bảng 8. Các phép toán biến đổi trên kiểu tập hợp
last() - X - X
prepend( đối tượng) - X - X
subOrderedSet( lower, upper) - X - -
subSequence( lower, upper) - - - X
symmetricDifference( 2 đối X - - -
tượng cộng tác)
unicon( 2 đối tượng cộng tác) X X X X
Toán tử = trả lại giá trị true nếu tất cả các phần tử ở hai tập hợp giống nhau.
Đối với tập có thứ tự đòi hỏi cả thứ tự xuất hiện các phần tử phải như nhau. Đối
với tập có lặp lại phần tử thì số lần lặp lại của các phần tử cũng phải như nhau.
Ngược lại, toán tử <> trả lại true nếu tất cả các phần tử ở hai tập hợp không
giống nhau.
a-> including( b): cho một tập mới gồm tất cả các phần tử của a thêm vào các
phần tử trong b mà không có trong a.
a->excluding( b): cho một tập mới gồm tất các các phần tử của a trừ ra các
phần tử cũng có trong b.
Phép toán flatten biến đổi một tập hợp các tập hợp thành một tập hợp của các
đối tượng đơn.
Các thể hiện của một trong bốn kiểu tập hợp Set, Sequence, Bag, OrderedSet có
thể được chuyển sang thể hiện của các kiểu kia, thực hiện tương ứng bởi các
phép toán asSet, asSequence, asBag, asOrderedSet.
Phép toán union nối hai tập hợp thành một tập hợp mới. Một set nối với một set
cho một set. Một set nối với một bag cho một bag. Một sequence hay
orderedSet không thể nối với một set hay một bag, chỉ nối được với một tập
hợp có thứ tự khác.
Phép toán intersection cho kết quả là một tập hợp mới gồm các phần tử trong cả
hai tập hợp. Phép toán áp dụng được đối với hai set, một set và một bag, hay hai
bag, nhưng không áp dụng cho sequence và orderedSet.
♦ Phép toán -
a- b: cho tập mới gồm các phần tử thuộc tập a nhưng không thuộc tập b.
a.symmetricDifference(b): cho tập mới gồm các phần tử thuộc tập a nhưng
không thuộc tập b hoặc thuộc tập b nhưng không thuộc tập a.
2.7.2.2. Các phép toán chỉ cho các tập hợp kiểu OrderedSet và Sequence
♦ Các phép toán first và last cho kết quả tương ứng là phần tử đầu và cuối của tập
hợp.
♦ Phép toán at cho kết quả là phần tử tại vị trí là tham số đưa ra.
♦ Phép toán indexOf cho kết quả là một số nguyên chỉ ra vị trí của phần tử trong
tập hợp. Nếu trong tập hợp phần tử xuất hiện nhiều lần thì kết quả là vị trí xuất
hiện đầu tiên của phần tử. Chỉ số của vị trí bắt đầu tính từ 1.
♦ Phép toán insertAt cho kết quả là một tập mới chèn thêm phần tử vào vị trí đưa
ra trong tham số.
♦ Phép toán append và prepend tương ứng thêm một phần tử vào một sequence ở
cuối và đầu tập hợp.
Một số VD:
equence{'a','b','c','c','d','e'}->first() = 'a'
OrderedSet{'a','b','c','d'}->last() = 'd'
Sequence{'a','b','c','c','d','e'}->at( 3 ) = 'c'
Sequence{'a','b','c','c','d','e'}->indexOf( 'c' ) = 3
OrderedSet{'a','b','c','d'}->insertAt( 3, 'X' ) =
OrderedSet{'a','b','X','c','d'}
Sequence{'a','b','c','c','d','e'}->subSequence( 3, 5 ) =
Sequence{'c','c','d'}
OrderedSet{'a','b','c','d'}->subOrderedSet( 2, 3 ) =
OrderedSet{'b','c'}
Sequence{'a','b','c','c','d','e'}->append( 'X' ) =
Sequence{'a','b','c','c','d','e','X'}
Sequence{'a','b','c','c','d','e'}->prepend( 'X' ) =
Sequence{'X','a','b','c','c','d','e'}
Bảng 9. Các phép toán duyệt định nghĩa trên kiểu tập hợp
Phép toán Mô tả
any ( biểu thức) trả lại một phần tử ngẫu nhiên trong tập hợp nguồn mà
biểu thức tham số có giá trị đúng.
collect ( biểu thức) trả lại tập các đối tượng là kết quả của biểu thức tham
số áp dụng trên mỗi phần tử của tập hợp nguồn.
collectNested( biểu trả lại tập các tập hợp là kết quả của biểu thức tham số
thức) áp dụng trên mỗi phần tử của tập hợp nguồn.
exitst( biểu thức) trả lại true nếu có ít nhất một phần tử trong tập hợp
nguồn thỏa mãn biểu thức.
forAll( biểu thức) trả lại true nếu biểu thức đúng đối với tất cả các phần
tử của tập hợp nguồn.
isUnique( biểu thức) trả lại true nếu biểu thức có một giá trị duy nhất đối
với tất cả các phần tử của tập hợp nguồn.
điều kiện sau phát biểu rằng giữa khoảng điều kiện trước và điều kiện sau, ít nhất một
khách hàng được thêm vào tập những người tham gia. Đối tượng khách hàng này được
tạo ra trong khoảng điều kiện trước và sau, có tên bằng tham số n, ngày sinh bằng
tham số d:
context LoyaltyProgram::enrollAndCreateCustomer( n : String,
d: Date ) : Customer
pre : -- none
post: result.oclIsNew() and
result.name = n and
result.dateOfBirth = d and
participants->includes( result )
Chú ý rằng một điều kiện sau không chỉ ra các câu lệnh trong phần thân của
phép toán.
Chương 3.
3.1.1.1. Thừa kế
Khi một lớp thừa kế từ một lớp khác, lớp thừa kế được gọi là một lớp con và
lớp được thừa kế được gọi là một lớp cha. Lớp con thừa kế từ lớp cha các phương thức
và các cấu trúc bên trong. Trong một lớp con, các phương thức mới có thể được thêm
vào và các phương thức thừa kế có thể được định nghĩa lại.
Thừa kế có một vài ưu điểm. Mã nguồn được sử dụng lại, do thừa kế cho phép
các lớp chia sẽ mã nguồn chung. Thừa kế cũng thích hợp trong giai đoạn bảo trì vì nó
có thể định nghĩa mã nguồn gốc trong lớp cha và thi hành trong một lớp con. Thừa kế
là một cách tốt để xây dựng mã nguồn và thiết kế. Theo lý thuyết, một thiết kế tốt là
thiết kế mà một lớp con là một trường hợp đặc biệt ( specialization- chuyên môn hóa)
lớp cha của nó.
Tuy có nhiều điểm mạnh nhưng thừa kế cũng có một số nhược điểm. Ví dụ,
thừa kế phá vỡ che dấu thông tin của các đối tượng- các lớp con phụ thuộc vào các lớp
cha của chúng và mã được phân bố trên toàn hệ thống. Điều này làm tăng khó khăn
khi tìm hiểu các hệ thống lớn các lớp theo cấp bậc.
class Shape
-move()
//thi hành
-draw()
//ảo
-draw() -draw()
//thi hành //thi hành
Shape S;
S = new Circle(); liên kết động
Đa hình S.draw();
// gọi draw() trong lớp Circle
S = new Square();
S.draw();
// gọi draw() trong lớp Square
Hình 9. Ví dụ liên kết động và đa hình
Liên kết động là quy trình liên két một lời gọi hàm với một định nghĩa hàm tại
thời gian chạy. Với liên kết động, quyết định chạy định nghĩa hàm nào đó được đưa ra
tại thời điểm chạy chứ không phải trong quá trình biên dịch, khi ta biết chắc đối tượng
thuộc lớp nào. Trong ví dụ trên, kiểm tra trên các đối tượng:
và thay thế bởi một lời gọi hàm chung chung S.draw()
Trong một lời gọi tại thời điểm chạy, hệ thống quyết định thực thi hàm draw()
của lớp Circle hay của lớp Square.
Kết quả của liên kết động tạo ra đa hình. Đa hình dẫn đến các biến và tham số
có thể nhận giá trị của các kiểu khác nhau.
Hình 10. Sự khác nhau trong điều khiển giữa khung làm việc và thư viện lớp
Khung làm việc cung cấp một kiến trúc dựa trên điều khiển với một tầng điều
khiển dữ liệu. Các nhà phát triển dùng tiện ích xây dựng trong khung làm việc bằng
cách tạo thể hiện các lớp và gọi các hàm thành viên ( điều khiển dữ liệu) của chúng,
mở rộng và thay đổi tiện ích bằng cách tạo ra các lớp dẫn xuất mới và chồng đè các
hàm thành viên ( điều khiển kiến trúc)
Khi một số ứng dụng được phát triển dùng khung làm việc, các thư viện của các
lớp con được chọn ra và sự tùy biến tăng lên bởi việc lựa chọn kết hợp các thành phần.
Khi đó sẽ tiết kiệm được thời gian tối thiểu vì không cần cài đặt và thử nghiệm.
Theo lĩnh vực ứng dụng khung làm việc chia ra thành các loại:
♦ Khung làm việc hỗ trợ: cung cấp các dịch vụ mức hệ thống, như truy nhập file,
hỗ trợ tính toán phân tán hay các điều khiển thiết bị. Các nhà phát triển ứng
dụng thường dùng trực tiếp các khung làm việc hỗ trợ. Các khung làm việc hỗ
trợ vẫn có thể được tùy biến, ví dụ khi phát triển một hệ thống file hay một điều
khiển thiết bị mới.
♦ Khung làm việc ứng dụng: đóng gói thành các chương trình ứng dụng theo chức
năng. Ví dụ, các khung làm việc ứng dụng giao diện đồ họa người dùng (GUI)
thương mại hiện nay cung cấp các tính năng chuẩn yêu cầu bởi tất cả các ứng
dụng GUI.
♦ Khung làm việc miền: đóng gói trong một miền vấn đề cụ thể. Vd, khung làm
việc hệ thống điều khiển cho phát triển các ứng dụng điều khiển quá trình sản
xuất, khung làm việc đa phương tiện, khung làm việc truy nhập dữ liệu…
a. Ưu điểm
♦ Giảm thời gian hoàn thành: khi viết các ứng dụng xây dựng trên một khung làm
việc làm cơ sở, chỉ cần viết phần mã khác với các ứng dụng đã được viết trước
đó. Khối lượng mã phải viết sẽ ít hơn, có nghĩa là thu ngắn thời gian phát triển
và dó đó giảm thời gian hoàn thành.
♦ Chi phí bảo trì: các hệ thống bảo bảo trì chi phí thường rất cao. Một hệ thống
lớn thường bỏ ra 60-85% tổng chi phí cho bảo trì. Do đó giảm chi phí trong
khâu bảo trì có ý nghĩa rất lớn. Khi bảo trì các ứng dụng của một khung làm
việc, chỉ khung làm việc và mã là khác so với các ứng dụng đã được bảo trì
trước đó. Điều này có nghĩa những thay đổi chỉ thực hiện ở một nơi. So với bảo
trì các hệ thống khác, khi dùng các thiết kế khung làm việc tiết kiệm được chi
phí một cách đáng kể.
♦ Kiểm thử: khi dùng lại một khung làm việc, các kiểm thử cũng được dùng lại.
Các kiểm thử cần tạo mới là các kiểm thử của các module mới và tương tác
giữa các module mới và khung làm việc ( các kiểm thử hệ thống). Do đó, giảm
thời gian kiểm thử và soát lỗi. ( Với giả thiết các kiểm thử hệ thống kiểm tra
khung làm việc được dùng một cách đúng đắn).
♦ Tính tin cậy: một khung làm việc cũng như tất cả các phần mềm khác, chứa các
lỗi và hỏng hóc, nhưng khi khung làm việc được dùng lại nó có xu hướng trở
nên ổn định hơn và các lỗi hỏng hóc mới ngày càng giảm. Dùng lại một khung
làm việc ổn định sẽ tăng tính tin cậy so với việc viết mã mới hoàn toàn.
♦ Tuân theo các chuẩn: một khung làm việc được thiết kế tốt tuân theo các chuẩn.
Khi phát triển các ứng dụng từ khung làm việc, khung làm việc thiết lập các
ràng buộc trên các mã ứng dụng được viết. Điều này dẫn đến ứng dụng tuân
theo các chuẩn.
♦ Các khung làm việc bao gồm các kỹ thuật: thiết kế phần mềm tốt trong một lĩnh
vực cụ thể đòi hỏi kiến thức thu được từ kinh nghiệm. Do các khung làm việc
bao gồm các kỹ thuật, các vấn đề được giải quyết một lần, các quy tắc nghiệp
vụ và thiết kế không thay đổi khi dùng lại. Điều này cho phép một tổ chức xây
dựng trên nền tảng đã làm trong thời gian trước. Các khung làm việc cũng cho
phép các nhà phát triển phần mềm tập trung vào giải quyết ứng dụng và dựa
trên khung làm việc cung cấp các dịch vụ thích hợp. Nó giúp các nhà phát triển
không phải là các chuyên gia trong một lĩnh vực nhất định tránh được sự phức
tạp của các chi tiết cơ bản. Điều này có được là do khung làm việc ở trong tầm
kiểm soát. Khung làm việc cung cấp luồng điều khiển, trong khi phần mã của
lập trình viên ứng dụng chờ khung làm việc gọi. Có nghĩa là các nhà phát triển
không phải quan tâm tới các chi tiết và họ có thể tập trung giải quyết miền vấn
đề.
b. Khó khăn
Việc thiết kế các thành phần và kiến trúc cho sử dụng lại đòi hỏi nhiều thời gian
hơn so với thiết kế bình thường. Thiết kế một khung làm việc khó khăn hơn thiết kế
một thư viện thành phần, nhưng lợi ích tiềm năng của việc dùng lại một khung làm
việc lớn hơn nhiều so với dùng lại một thành phần từ thư viện. Một khung làm việc
gặp khó khăn hơn trong việc thiết kế vì kiến trúc của khung làm việc phải được thiết
kế bao gồm cả giao tiếp giữa các thành phần bên trong của khung làm việc. Khi thiết
kế một thành phần cho một thư viện thì không phải làm điều này.
nói cách khác khi khung làm việc được triển khai, thì trong đó sẽ có sự thay thế. Sau
khi thay thế ta sẽ được một phiên bản khung làm việc mới có nội dung cụ thể nhưng
lại dựa trên nội dung của khung làm việc ban đầu.
Khung làm việc có thể là sự trừu tượng hóa bản đặc tả của một kiểu thông
thường, một họ các kiểu phụ thuộc lẫn nhau, một sự cộng tác, một khuôn mẫu làm
mịn, mô hình tạo nên chính chúng, thậm chí là một nhóm các thuộc tính cơ bản thông
thường (kết hợp, giao hoán,…).
Observation
Observer
Subject [view_value/reading]
[value/level]
Meter
Stock
Khung làm việc quan sát thể hiện một loạt các quyết định thiết kế về cách thức
mà hai kiểu đối tượng sẽ cộng tác với nhau như thế nào để đạt được kết quả mong
muốn mà không quan tâm đến bất kỳ một vai trò hay cộng tác cụ thể giữa các đối
tượng này. Sự khái quát này phân rã công việc thiết kế cho bất kỳ một miền xác định
nào. Đó chính là một trong rất nhiều những hiệu quả của việc sử dụng mô hình khung
làm việc.
Một mẫu thiết kế là một tập các ý tưởng có thể được áp dụng cho nhiều tình
huống trong phát triển phần mềm. Một khung làm việc là “trái tim” của các mẫu thiết
kế. Khi lưu khung làm việc trong thư viện, ta nên đóng gói nó cùng với các tài liệu.
Một khái niệm liên quan nữa, đó là các khuôn mẫu lớp được sử dụng trong một số
ngôn ngữ lập trình. Một khuôn mẫu lớp cũng là một khung mô hình nhưng nó chỉ chứa
một lớp duy nhất.
Sự đa dạng của các kỹ thuật hướng đối tượng cho phép ta xây dựng các khung
làm việc có thể thực thi được, bằng cách chia nhỏ nó thành các lớp, cắm thêm các
thành phần mới, và bằng cách thể hiện các lớp qua các ngôn ngữ được xây dựng để
phục vụ cho các mục đích này.
Các công cụ hỗ trợ cho các khung làm việc và các khuôn mẫu cho phép mở mỗi
ứng dụng của mô hình khung làm việc để có thể nhìn thấy mô hình kết quả với đầy đủ
thực thi được với tất cả những thành phần thay thế đã được tạo ra, tức là tất cả các
thành phần đã thay thế vào các điểm đặt chỗ trước của khung làm việc nguyên thủy
ban đầu. Về mặt ý tưởng, các khung làm việc sẽ lưu các định nghĩa của khung làm
việc, các định nghĩa ban đầu của các kiểu áp dụng, các biểu đồ trong khung làm việc
được sử dụng. Nếu như người dùng thay đổi bất cứ thành phần nào trong số chúng thì
mô hình kết quả đã mở ra và được thay đổi từng bước.
Để minh họa, ta xem xét sự cộng tác Subject-Observer. Trong hình 12 chúng ta
chỉ ra các giao diện bên ngoài của mỗi đối tượng chia được thành các vai trò trong các
sự cộng tác khác nhau cho dù các thuộc tính bên trong có thể được chia sẻ. Sự cộng
tác này “quản lý” hai vai trò: Subject và Observer. Subject có thuộc tính value và
Observer có thuộc tính khác được gọi là value_view. Một hành động update (cập nhật)
được khởi tạo bởi Subject và làm cho Observer cập nhật theo.
Các vai trò được nắm giữ bởi phần này của
mỗi đối tượng
Subject Observer
value value_view
Cập nhật
Tất nhiên một cặp các lớp bất kỳ có mối quan hệ như vậy trong một chuỗi các
mã chương trình có thể không được gọi là Subject và Observer. Chúng có vai trò lớn
và đáng quan tâm hơn trong chương trình của chúng, có lẽ giống như các thành phần
của GUI hay các ủy nhiệm trong các hệ thống phân tán. Nhưng cái đó mới nói lên
chính xác khung làm việc là gì: Chúng ta có thể chỉ định nghĩa các khía cạnh về một
cái gì đó mà ta muốn nói và sau đó cho phép người dùng sử dụng các tên khác và mở
rộng các định nghĩa khi họ áp dụng khung làm việc của ta.
Chính vì thế, đúng như chúng ta chỉ ra trong hình 12, chúng ta thực sự chỉ biết
một phần của đối tượng mà chúng ta đang miêu tả: phần còn lại phụ thuộc vào bất cứ
ai sử dụng khung làm việc. Trong ví dụ này, chúng ta không biết cách thức và tại sao
value của Subject thay đổi. Chúng ta chỉ biết rằng nó có thể thay đổi và khi nó thay đổi
Observer phải được cập nhật.
3.2.1.1. Các hành động trong khung làm việc cộng tác
Sự khác nhau lớn nhất giữa khung làm việc này và các khung làm việc khác là
khung làm việc này có các hành động. Thực tế, khung làm việc này có các hành động
sau:
♦ Tất cả các hành động khác mà ta không biết về chúng, các hành động đó thay
đổi giá trị của Subject.
Việc xác định hành động đầu tiên là khá dễ dàng:
action Observer :: update ()
post value_view = subject.value
- - phản ánh một cách chính xác giá trị value của Subject
Hành động update chỉ là một trong rất nhiều hành động có thể làm thay đổi giá
trị value của Subject. Nói một cách hình thức, ta sử dụng một kết quả bất biến, tức là ta
không quan tâm đến các hành động xảy ra đối với hệ thống như thế nào, khi nào và
như thế nào. Ta chỉ cần biết rằng, khi có một hành động xảy ra thì ta thu được một kết
quả bất biến. Ở đây cũng vây, ta không quan tâm xem hành động nào xảy ra, xảy ra
khi nào và xảy ra như thế nào đối với giá trị của Subject, nhưng ta chỉ biết một kết quả
bất biến là khi giá trị bị thay đổi thì hành động update luôn xảy ra: nó là một điều kiện
sau :
inv effect Subject ::
post value@pre <> value _ [[ observers.update() ]]
---Bất cứ hành động nào thay đổi giá trị value cũng đảm bảo
Observer phản ánh chính xác giá trị mới.
Điều kiện sau không chỉ áp dụng cho khung làm việc, mà nó còn phải được
thực hiện một cách chính xác trong các chương trình cụ thể là trong các lớp của
Subject và Observer. Không những thế các đặc tả (làm tài liệu) của nó cũng phải miêu
tả chính xác về các điều kiện sau này.
Hình sau đây chỉ ra khung làm việc cộng tác như chúng ta đã miêu tả nó trong
phần trước. Sự kết hợp Subject-Observer liên kết các thể hiện cụ thể của hai kiểu này
và hành động update chỉ áp dụng cho các Observer có một Subject hiện tại. Hành động
register liên kết một Subject cụ thể tới một Observer cụ thể. Nó là một hành động kết
nối mà chúng ta không xác định cách thức nó xảy ra, thậm chí ai là người gửi thông
điệp làm cho nó xảy ra, chúng ta chỉ xác định được là sẽ có một hành động như thế,
với trách nhiệm thực thi nó được phân bố giữa Subject và Observer.
Register
<Subject> <Observer>
subject observers
<value> <value_view>
0,1 0..*
update
Observer ::
action update ( )
pre subject <> null
post value_view = subject.value
Subject ::
inv effect
post value @ pre <> value ® [[observers.update()]]
cần thiết. Hình 13 hiển thị mô hình được mở: kết quả của việc áp dụng khung làm việc
và đưa ra đặc tả.
calls Call
CallQueue
0..*
{seq}
addCall (c : Call) Thermometer
post calls = calls @ pre + c
getCall ( ) : Call temperature : int
post result = calls @ pre->head other stuff
& calls = calls @ pre->tail about
Thermometers
Hình 14. Mô hình kiểu đích cho việc sử dụng sự quan sát
Observation
Subject
Observer
[value\calls->size]
[value_view\reading]
CallQueue
Thermometer
reading
0..* calls
Call
calls
CallQueue Call
0..*
{seq}
addCall (c : Call)
post calls = calls @ register Thermometer
pre + c
& [[observers.update ( reading
)]] subject observers other stuff
getCall ( ) : Call about
post result = calls @ 0,1 0..* Thermometers
pre->head
& calls = calls @ pre-
>tail update
& [[observers.update (
)]]
Thermometer ::
action update ( )
pre subject <> null
post reading = subject.calls->size
Hình 16. Kết quả mở của ứng dụng khung làm việc
Khi nhìn vào ứng dụng khung làm việc, ta thấy tên Subject và Observer đã được
thay thế và các phương thức addCall và getCall cũng đã được đưa vào, chúng luôn
luôn thay đổi độ lớn các cuộc gọi vào mọi lúc, chính vì vậy cần loại bỏ
value<>value@pre từ các hậu điều kiện của chúng. Tại đây, hành động update có thể
được nhận diện như thông điệp notify (newvalue) hay theo kiểu MVC (Model, View,
Control) thì có thể bao gồm thông điệp update() tới Thermometer, và sau đó, nó phải
quay ngược trở lại CallQueue để yêu cầu chi tiết về sự thay đổi đã xảy ra.
Hành động register có thể được khởi tạo bằng một đối tượng giám sát để chỉ ra
một Thermometer cụ thể quan sát một CallQueue cụ thể. Tiếp đó, Thermometer phải
chỉ ra chính bản thân nó cho CallQueue biết, có như vậy thì chúng mới biết về nhau.
<Trader>
* *
Cho
0,1 Đã phân phối
<Sản phẩmt> Ngày
Hình 17. Khung làm việc cho việc thương mại: duy trì kho hàng
Khung làm việc cũng chỉ ra rằng nhà kinh doanh luôn có một hoá đơn khi kho
hàng ở mức thấp hơn mức quy định. Chính vì vậy mà kho hàng có thể luôn luôn tránh
được việc thiếu hàng. Đây chính là một khung làm việc mức cao, nói lên nhiệm vụ
tổng thể của hệ thống mà không đi vào các chi tiết quá cụ thể như cách thức các hóa
đơn tạo ra như thế nào- đó chính là các công việc mà các nhà thiết kế phải làm. Để làm
điều này, có thể định nghĩa những chi tiết trong chính mô hình đó hoặc xây dựng một
khung làm việc khác chứa các thông tin này.
Chúng ta hãy xem xét khung làm việc trong hình 18, một khung làm việc làm
mịn của khung làm việc trong hình 17, khi sản phẩm của bất kỳ kho hàng nào ở mức
thấp, nhà kinh doanh tạo ra một đơn hàng gửi người phân phối bằng cách sử dụng
hành động make_order. Khi Order được tạo ra, người phân phối có thể giao hàng và
người kinh doanh có thể trả tiền. Trong ví dụ trước (hình 17), chúng ta chỉ sử dụng
“kết quả”, tức là chỉ biết kết quả của hành động mà không nói đến nguyên nhân của
các hành động đó, thì ở đây ta chia ra nguyên nhân và kết quả. Đầu tiên ta tạo ra kết
quả có tên depletion(p) (sự làm rỗng: ở đây có nghĩa là làm giảm sản phẩm p trong
kho hàng) là một tên đặt sẵn trong khung làm việc cho bất cứ hành động nào là nguyên
nhân cho việc làm giảm p. Thứ hai, chúng ta tạo ra một điều kiện sau cho depletion;
đó chính là yêu cầu thực hiện hành động make_order. Việc phân chia nguyên nhân kết
quả như vậy rất có ích khi chúng ta có các mối quan hệ nhiều nhiều và ta muốn làm rõ
các nguyên nhân dẫn đến mỗi kết quả.
depletion (p:Product)
Từ
<Order >
Tới
* stock( product): int *
Các hoá đơn lowLimit( product): Chưa trả
int
* *
Cho
0,1 Đã phân phối
<Product> Date
inv effect
post t:Trader, p:Product::
t.stock(p) < t.stock@pre(p) ==> t.depletion (p))
effect Trader:: depletion (p:Product)
post stock(p) < lowLimit(p) ==>
exists dist:Distributor, n: integer, n> 0 &
[[ this –> d.make_order (p, n) ]]
Yêu cầu cung cấp hàng cho Bất kỳ hành động nào đều phải gọi
make_order nếu kho hàng của thương
nhân bị thiếu hàng. Đối số liên quan:
Hình 19. Làm tài liệu sự làm mịn khung làm việc
Chương 4.
Xây dựng hệ thống cho bài toán lập Thời khóa biểu
4.1. Mô hình ca sử dụng
4.1.1. Xác định tác nhân
♦ Nhân viên phòng đào tạo ( người lập thời khóa biểu)
♦ Giáo viên và học viên ( những người xem thời khóa biểu)
♦ Mục đích: đưa ra danh sách các lớp học sẽ học trong học kỳ
♦ Mô tả: Lần lượt thêm các lớp sẽ học trong kỳ học tiếp theo vào danh sách, hoặc
xóa bỏ một lớp ra khỏi danh sách các lớp sẽ học.
♦ Luồng sự kiện:
Bảng 10. Bảng luồng sự kiện ca sử dụng lập danh sách lớp học
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
1. Chọn chức năng lập
danh sách các lớp 2. Hiện form điều chỉnh
học danh sách lớp học Danh sách các lớp
4.1.2.2. Ca sử dụng lập danh sách các môn học cho mỗi lớp
♦ Mục đích: Đưa ra danh sách các môn học tương ứng với từng lớp(ClassSubject)
♦ Mô tả: trên cơ sở chương trình đào tạo đã được lãnh đạo khoa xem xét và phê
duyệt, cán bộ phòng Đào Tạo lên danh sách các môn học sẽ học trong học kỳ
cho mỗi lớp
♦ Luồng sự kiện:
Bảng 11. Bảng luồng sự kiện ca sử dụng lập danh sách môn học
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
5. Chọn chức năng lập 6. Hiện form điều chỉnh Danh sách môn học
danh sách các môn danh sách môn học cho Danh sách lớp- học
học cho lớp từng lớp tương ứng kỳ
8. Hiện danh sách các môn
7. Chọn lớp và chọn học tương ứng với lớp Danh sách môn học
môn tương ứng đã chọn - lớp
9. Chỉnh sửa danh 10. Chỉnh sửa danh và lưu Danh sách môn học
sách lại - lớp
4.1.2.3. Ca sử dụng lập danh sách các giáo viên giảng dạy trong học kỳ
♦ Mục đích: Đưa ra danh sách tất cả các giáo viên giảng dạy sẽ tham gia giảng
dạy cho các lớp
♦ Mô tả: Lần lượt bổ xung vào danh sách giáo viên giảng dạy những giáo viên
giảng dạy thiếu và loại bỏ ra khỏi danh sách những giáo viên giảng dạy sẽ
không giảng dạy trong kỳ tiếp theo
♦ Luồng sự kiện:
Bảng 12. Bảng luồng sự kiện ca sử dụng lập danh sách giáo viên giảng dạy
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
11. Chọn chức năng lập 12. Hiện form điều chỉnh
danh sách giáo viên danh sách giáo viên
giảng dạy giảng dạy
14. Thể hiện danh sách các
giáo viên giảng dạy đã
13. Xác định các giáo được chọn, cập nhật
viên giảng dạy cho danh sách vào cơ sở dữ
học kỳ tiếp theo liệu Bảng tblTeacher
4.1.2.4. Ca sử dụng xác định giáo viên giảng dạy các môn học của các lớp
♦ Mục đích: đưa ra được danh sách các giáo viên giảng dạy đảm nhận việc giảng
dạy các môn học của mỗi lớp
♦ Mô tả: trước tiên phòng Đào Tạo gửi danh sách các môn học phân theo bộ môn
gửi đến bộ môn và giáo viên, từ đó bộ môn sẽ tiến hành phân công, đăng kí
giảng dạy và lập ra danh sách giáo viên giảng dạy gửi cho phòng Đào Tạo. Từ
danh sách này phòng Đào Tạo sẽ đưa ra được danh sách các giáo viên giảng dạy
dạy mỗi môn của các lớp(lớp – môn – giáo viên giảng dạy)
♦ Luồng sự kiện:
Bảng 13. Bảng luồng sự kiện ca sử dụng xác định giáo viên dạy môn học cho lớp
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
15. Chọn chức năng 16. Hiện form điều chỉnh
xác định giáo viên giáo viên giảng dạy cho
giảng dạy cho các các môn học của từng Danh sách môn học
môn học lớp - lớp
18. Thể hiện danh sách các
17. Xác định giáo viên môn học và các giáo
giảng dạy cho các viên giảng dạy tương
môn học của từng ứng của từng lớp, và cập Danh sách giáo viên,
lớp nhật vào cơ sở dữ liệu tblLink
♦ Mục đích: liệt kê các ràng buộc của thời khóa biểu
♦ Mô tả: Căn cứ vào quy định của bộ Giáo dục, các quy chế giảng dạy,… đưa ra
danh sách các ràng buộc để áp dụng cho việc lập thời khoá biểu.
♦ Luồng sự kiện:
Bảng 14. Bảng luồng sự kiện ca sử dụng lập danh sách ràng buộc
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
Chọn chức năng lập danh
sách các ràng buộc Hiện form nhập liệu Danh sách ràng buộc
Cập nhật thông tin và ghi Danh sách Ràng
Xem, cập nhật các ràng buộc nhận buộc
♦ Mục đích: Đưa ra được thời khóa biểu dự kiến và gửi cho các đơn vị liên quan
để lấy ý kiến, hoàn thiện thành thời khóa biểu chính thức.
♦ Mô tả: Từ danh sách lớp, danh sách các môn học của từng lớp, danh sách các
giáo viên giảng dạy, phòng học, và các ràng buộc… cán bộ phòng Đào Tạo tiến
hành chạy chương trình ( có thể kết hợp gắp thả) để có được thời khóa biểu dự
kiến, sau đó gửi cho các đơn vị để lấy ý kiến phản hồi, hoàn thiện thành thời
khóa biểu chính thức.
♦ Luồng sự kiện:
Bảng 15. Bảng luồng sự kiện ca sử dụng lập thời khóa biểu
Hành động của tác nhân Phản ứng của hệ thống Dữ liệu liên quan
Danh sách môn -
lớp - Giáo viên,
Danh sách ràng
19. Chọn chức năng lập 20. Xử lí và hiện ra kết quả buộc, thời khóa
thời khóa biểu có được biểu.
22. Hiện thời khóa biểu của Danh sách lớp - học
21. Chọn lớp học lớp học kỳ, Thời khóa biểu.
Danh sách Giáo
23. Chọn giáo viên 24. Hiện thời khóa biểu của viên, Thời khóa
giảng dạy giáo viên giảng dạy biểu.
♦ Lớp thực thể DS_Lop-HocKy chứa danh sách các lớp học trong học kỳ.
♦ Lớp giao diện: Lớp giao diện frmDS_Lop cho phép tác nhân tạo danh sách các
lớp sẽ học trong học kỳ, cũng như xem hay sửa đổi danh sách hiện thời.
♦ Lớp điều khiển: Lớp điều khiển LapDS_Lop-HocKy có chức năng điều khiển
việc truy xuất và cập nhật danh sách các lớp học sẽ được học trong học kỳ.
– Biểu đồ cộng tác thực thi ca sử dụng:
3: LayThongTin
1: LenDS_Lop 2: LapDS
: DS_Lop
4: TaoMoi
: frmDS_Lop : LapDS_Lop-HocKy
: NhanVienPDT
: DS_Lop - HocKy
Hình 21. Biểu đồ cộng tác ca sử dụng lập danh sách lớp học
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: Nhân viên phòng
Đào Tạo chọn vào danh sách các lớp sẽ học trong học kỳ tiếp theo thông qua
các điều kiện (chương trình đào tạo, hệ đào tạo…), thông qua giao diện người
dùng (frmDS_Lop). Giao diện cung cấp cho người dùng danh sách các lớp học
đã được chọn, và thông tin về các lớp học. Người dùng qua đó thể thể sửa đổi
danh sách các lớp học bằng cách thêm, hoặc xóa một lớp học.
4.2.2.2. Ca sử dụng lập danh sách các môn học trong học kỳ
– Tác nhân: nhân viên phòng Đào Tạo
– Các lớp phân tích:
♦ Lớp thực thể DS_MonHoc chứa danh sách các môn học trong khung
chương trình.
♦ Lớp thực thể DS_MonHoc-HocKy chứa danh sách các môn học trong học
kỳ.
♦ Lớp giao diện: Lớp giao diện frmDS_MonHoc cho phép tác nhân xây dựng
danh sách các môn sẽ được giảng dạy trong học kỳ
♦ Lớp điều khiển: Lớp điều khiển LapDS_MonHoc có chức năng điều khiển việc
truy suất và cập nhật danh sách các lớp học sẽ được học trong học kỳ
– Biểu đồ cộng tác thực thi ca sử dụng :
3: LayThongTin
1: LapDS_MonHoc 2: ThucHien
: DS_MonHoc
4: TaoMoi
: frmDS_MonHoc : LapDS_MonHoc
: NhanVienPDT
: DS_MonHoc - HocKy
Hình 22. Biểu đồ cộng tác ca sử dụng lập danh sách môn học trong học kỳ
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: Nhân viên phòng
Đào Tạo dựa vào chương trình đào tạo của học kỳ để lên danh sách các môn
học sẽ được đưa vào giảng dạy trong học kỳ. Thông qua giao diện
frmDS_MonHoc để có thể biết thêm thông tin thông tin về một môn học và
chỉnh sửa danh sách các môn học
4.2.2.3. Ca sử dụng lập danh sách các giáo viên giảng dạy trong học kỳ
– Tác nhân: nhân viên phòng Đào Tạo
– Các lớp phân tích:
♦ Lớp thực thể frmDS_GiaoVien chứa thông tin về các giáo viên giảng dạy.
♦ Lớp thực thể DS_GiaoVien-HocKy chứa danh sách các giáo viên giảng
dạy giảng dạy trong học kỳ.
♦ Lớp thực thể giao diện: lớp giao diện frmDS_GiaoVien cho phép tác nhân xác
định, xây dựng và chỉnh sửa danh sách giáo viên giảng dạy cũng như các thông
tin về các giáo viên giảng dạy
♦ Lớp điều khiển: lớp điều khiển LapDS_GiaoVien có chức năng điều khiển việc
truy suất và cập nhật danh sách giáo viên giảng dạy cũng như thông tin về các
giáo viên giảng dạy của kỳ học
– Biểu đồ lớp cộng tác thực thi ca sử dụng :
3: LayThongTin
4: TaoMoi
: frmDS_GiaoVien : LapDS_GiaoVien
: NhanVienPDT
: DS_GiaoVien- HocKy
Hình 23. Biểu đồ cộng tác ca sử dụng lập Danh sách giáo viên trong học kỳ
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: Nhân viên phòng
Đào Tạo dựa vào danh sách các giáo viên giảng dạy đăng kí giảng dạy ở các bộ
môn, thông qua giao diện frmDS_GiaoVien để chỉnh sửa
♦ Lớp thực thể DS_Lop-HocKy chứa danh sách các lớp học trong học kỳ.
♦ Lớp thực thể DS_Lop-MonHoc chứa danh sách các môn học mà lớp đó
sẽ được học trong một học kỳ
♦ Lớp thực thể DS_MonHoc-HocKy chứa danh sách các môn học trong học
kỳ của tất cả các lớp.
♦ Lớp giao diện: lớp giao diện frm_Lop-Mon cho phép người dùng chọn lớp học
cần lập danh sách và đồng thời cho phép chọn các môn học cho lớp học đó.
♦ Lớp điều khiển: lớp điều khiển LapDS_Lop-Mon có chức năng sửa đổi danh
sách môn học cho một lớp.
– Biểu đồ cộng tác thực thi ca sử dụng :
3: LayThongTin
: DS_Lop - HocKy
5: TaoMoi
: frm_Lop-Mon : LapDS_Lop- Mon : DS_MonHoc - HocKy
: NhanVienPDT
: DS_Lop- MonHoc
Hình 24. Biểu đồ cộng tác ca sử dụng lập danh sách lớp- môn học
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: trước tiên, nhân
viên phòng Đào Tạo chọn ra một lớp cần thao tác trong danh sách các lớp học.
Rồi sau đó thông qua giao diện người dùng, thêm các môn học trong danh sách
các môn học vào lớp đó hoặc xóa các môn học trong danh sách môn lớp ra khỏi
danh sách các môn học của lớp đó.
4.2.2.5. Ca sử dụng xác định giáo viên giảng dạy mỗi môn cho từng lớp
– Tác nhân: nhân phòng Đào Tạo viên.
– Các lớp phân tích:
♦ Lớp DS_Lop-Mon-GV lưu thông tin về các môn học mà lớp đó sẽ học
trong học kỳ và giáo viên giảng dạy tương ứng sẽ dạy môn đó.
♦ Lớp DS_Lop-MonHoc lưu danh sách các môn học cùng với lớp học trong
học kỳ.
♦ Lớp DS_GiaoVien-Hocky lưu danh sách các giáo viên dạy trong học kỳ.
♦ Lớp giao diện: lớp giao diện frmDS_Lop-Mon-GV cho phép hiển thị danh sách
các lớp sẽ học trong học kỳ, cho phép người dùng chọn lớp cần thao tác trong
danh sách các lớp và hiển thị danh sách các môn học tương ứng của lớp đó. Cho
phép người dùng xác định giáo viên giảng dạy (trong danh sách các giáo viên
giảng dạy) tương ứng sẽ dạy một môn học cho lớp đó.
♦ Lớp điều khiển: lớp điều khiển LapDS_Lop-Mon_GV thực hiện việc tạo và
chỉnh sửa liên kết các giáo viên giảng dạy với từng môn học của một lớp.
– Biểu đồ cộng tác thực thi ca sử dụng :
3: LayThongTin
: DS_Lop- MonHoc
1: LapDS_Lop-Mon-GV
2: ThucHien
4: LayThongTin
5: TaoMoi
: frmDS_Lop-Mon-GV : LapDS_Lop-Mon-GV : DS_GiaoVien- HocKy
: NhanVienPDT
Hình 25. Biểu đồ cộng tác ca sử dụng lập danh sách lớp- môn- giáo viên
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: trước tiên nhân
viên phòng Đào Tạo duyệt danh sách các lớp học trong học kỳ, sau đó chọn một
lớp cần lên danh sách giáo viên giảng dạy thông qua giao diện frmDS_Lop-
Mon-GV. Giao diện frmDS_Lop-Mon-GV sẽ hiện danh sách các môn học mà
lớp đó sẽ học trong học kỳ. Từ danh sách các giáo viên giảng dạy tương ứng với
mỗi môn học, người dùng sẽ chọn ra các giáo viên giảng dạy sẽ dạy cho các
môn học của lớp đó.
♦ Lớp thực thể RangBuoc chứa thông tin về các qui tắc nghiệp vụ cần phải
tuân theo trong việc lập thời khóa biểu.
♦ Lớp thực thể DS_RangBuoc chứa thông tin về danh sách các ràng buộc
mà nhân viên phòng Đào Tạo đã thiết lập.
♦ Lớp giao diện: lớp giao diện frmDS_RangBuoc cho phép cho phép người dùng
lựa chọn và hiển thị danh sách các ràng buộc đã thiết lập.
♦ Lớp điều khiển: lớp điều khiển LapDS_RangBuoc làm nhiệm vụ liên kết các lớp
ràng buộc và danh sách các ràng buộc và tạo ra thực thể danh sách các ràng
buộc chứa danh sách các ràng buộc phải tuân theo và lưu vào cơ sở dữ liệu.
– Biểu đồ cộng tác thực thi ca sử dụng :
4: LayThongTin
1: LapDS_RangBuoc 2: ThucHien
: RangBuoc
3: TaoMoi
: frmDS_RangBuoc : LapDS_RangBuoc
: NhanVienPDT
: DS_RangBuoc
Hình 26. Biểu đồ cộng tác ca sử dụng lập danh sách các ràng buộc
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: nhân viên phòng
Đào Tạo duyệt danh sách các ràng buộc thông qua giao diện frmDS_RangBuoc.
Đánh dấu các ràng buộc sẽ được áp dụng và điều chỉnh nội dung của ràng
buộc(nếu có thể).
♦ Lớp thực thể DS_RangBuoc lưu thông tin về danh sách các ràng buộc
phải thỏa mãn.
♦ Lớp thực thể DS_Lop-MonHoc-GiaoVien lưu thông tin về danh sách các
giáo viên giảng dạy dạy các môn của mỗi lớp.
♦ Lớp thực thể ThoiKhoaBieu lưu thông tin về thời gian biểu mới được
thiết lập
♦ Lớp giao diện: lớp giao diện frmLapTKB cho phép lựa chọn, hiển thị là thực
hiện thao tác gắp thả.
♦ Lớp điều khiển: lớp điều khiển LapTKB biểu thực hiện việc liên kết các lớp
thực thể để tạo ra thực thể ThoiKhoaBieu và hiện thị ra lớp giao diện
frmLapTKB.
– Biểu đồ cộng tác thực thi ca sử dụng :
3: TaoMoi
2: ThucHien : ThoiKhoaBieu
1: LapTKB
5: LayThongTin
: frmLapTKB : LapTKB
: NhanVienPDT : DS_RangBuoc
4: LayThongTin
Hình 27. Biểu đồ cộng tác ca sử dụng lập thời khóa biểu
♦ Mô tả luồng các sự kiện phân tích diễn giải biểu đồ cộng tác: nhân viên phòng
Đào Tạo chọn các lớp (học sáng hay chiều…) để lập thời khóa biểu. Sau khi
truy suất cơ sở dữ liệu để lấy thông tin về các lớp, các môn học của các lớp, các
giáo viên giảng dạy sẽ dạy các môn học và danh sách các ràng buộc phải tuân
theo, chương trình sẽ tự động sinh ra một thời khóa biểu.
4.3. Thiết kế
4.3.1. Thiết kế lớp
♦ Thuộc tính
Bảng 18. Các thuộc tính thêm lớp con Tie_Teacher
Tên thuộc tính Kiểu dữ liệu Kích cỡ Giải thích
OffDays String 9 (2,3,…) Xâu chứa các ngày giáo viên yêu
cầu được nghỉ.
♦ Phương thức
- getOffDays(): lấy các ngày nghỉ của giáo viên.
- setOffDays(): gán các ngày nghỉ cho giáo viên.
♦ Thuộc tính
Bảng 20. Các thuộc tính thêm lớp con Subject- Class
Tên thuộc tính Kiểu dữ liệu Kích cỡ Giải thích
Teacher Teacher Giáo viên dạy môn học cho một
lớp cụ thể.
Term – Year String 12 Học kỳ và năm học cần lập thời
khóa biểu
♦ Phương thức
- getTeacher(): lấy thông tin giáo viên dạy.
- setTeacher(Teacher:Teacher): gán giáo viên dạy cho môn học.
- setTerm-Year(Term-Year:String): gán học kỳ năm học cho môn học.
♦ Thuộc tính
Bảng 22. Thuộc tính thêm lớp con Tie_Class
Tên thuộc tính Kiểu dữ liệu Kích cỡ Giải thích
OffDay Number Integer Ngày nghỉ trong tuần của lớp
♦ Phương thức
- getOffDay(): lấy ngày nghỉ của lớp.
- setOffDay(OffDay:Integer): gán ngày nghỉ cho lớp.
mở rộng mỗi khi thêm một ràng buộc mới. Do đó trong khóa luận này chọn phương
pháp heuristic xây dựng thuật toán dựa trên các cảm nhận trực giác và kinh nghiệm khi
xếp thời khóa biểu để giải quyết các ràng buộc.
– Số tiết trống giữa các ca dạy trong một ngày của giáo viên không quá 1.
– Giáo viên xin nghỉ vào ngày nào đó trong tuần.
♦ Tại một thời điểm, một lớp chỉ có thể học một môn học và một giáo viên chỉ
có thể dạy một lớp: để tránh xung đột về thời gian học các môn học của một
lớp, ta sử dụng một ma trận để lưu trữ trạng thái về thời gian. Ma trận cho biết
tại một thời điểm (một tiết trong một ngày trong tuần) một lớp đã xếp lịch hay
chưa, nếu xếp rồi thì đó là môn nào.
Mỗi phần tử của ma trận có hai trạng thái: rỗng ( chưa xếp môn học cho lớp)
hay là tên môn học đã xếp. Như vậy có thể dùng một mảng 3 chiều
arr_Trạng_thái_lớp[Số_lớp][6][6] kiểu String để lưu trạng thái của lớp.
Tương tự có thể dùng mảng 3 chiều arr_Trạng_thái_GV[Số_GV][6][12] kiểu
String để lưu trạng thái của giáo viên ( cỡ chiều thứ 3 của mảng bằng 12 là do
đối với giáo viên một ngày có thể đến trường cả 2 buổi sáng chiều).
♦ Một môn học không học quá 2 buổi trong tuần: chia môn học ra thành các ca
học. Một môn học có thể có 1 hay 2 ca trong tuần. Các ca học của các môn khác
nhau sẽ được xếp liền nhau trong ngày.
Bảng 24. Bảng chia môn học các ca học dựa trên số tiết học
Tổng số tiết của môn Số ca Ca 1- Ca 2
1 1 1-0
2 1 2-0
3 1 3-0
4 1 4-0
4 2 2-2
5 2 3-2
6 2 3-3
7 2 4-3
8 2 4-4
♦ Một môn học chỉ học một lần trong tuần: để giải quyết ràng buộc này mỗi
lớp dùng mảng arr_Trạng_thái_ca[Số_ca] kiểu boolean đánh dấu ca học đó đã
được xếp hay chưa. Không xếp những ca đã được đánh dấu và khi xếp xong
một ca chuyển phần tử đánh dấu tương ứng sang trạng thái đã xếp.
♦ Các môn học phải đảm bảo là xếp đủ: sử dụng mảng đánh dấu trạng thái đã
xếp/chưa xếp cho các ca học đối với mỗi lớp có thể biết được môn nào chưa
được xếp. Trường hợp không xếp được đầy đủ các ca học, phải thực hiện thêm
điều chỉnh bằng tay- gắp thả ( trường hợp này rất ít, thử nghiệm chưa dùng tới).
♦ Không có tiết trống giữa các ca học của một lớp trong một ngày: xếp các ca
học liền nhau dựa trên mảng lưu trạng thái lớp.
♦ Giáo viên được xếp sao cho có số ngày đến trường là ít nhất có thể: giải
quyết ràng buộc bằng cách ưu tiên xếp trước cho giáo viên có số ca giảng dạy
trong tuần lớn hơn. Việc ưu tiên này làm cho giáo viên dạy nhiều trong tuần có
lịch tối ưu hơn.
♦ Các ca học cùng một môn ở mỗi lớp không học hai ngày liên tiếp: dựa vào
mảng trạng thái lớp kiểm tra ca định xếp có thỏa mãn không.
♦ Số tiết trống giữa các ca dạy trong một ngày của giáo viên không quá 1:
dựa vào mảng trạng thái giáo viên kiểm tra ca định xếp có thỏa mãn không.
♦ Lớp nghỉ một ngày nào đó trong tuần: khi xếp ca học phải bỏ ngày nghỉ của
lớp.
♦ Giáo viên xin nghỉ dạy vào ngày nào đó trong tuần: khi xếp ca học vào ngày
đó không chọn ca học do giáo viên đó dạy.
♦ Tại một thời điểm duyệt mảng các ca học của lớp đó( đã sắp theo độ ưu tiên là
tổng số tiết mà giáo viên dạy môn đó phải dạy trong tuần), xét một ca học có
thể xếp được hay không ( có thỏa mãn các ràng buộc hay không):
♦ Nếu xếp được ( thỏa mãn): đánh dấu trạng thái lớp, trạng thái giáo viên
đối với khoảng thời gian có ca học vừa xếp rồi tiếp tục tăng chiều thời
gian của thời khóa biểu lớp đó lên xếp tiếp.
♦ Nếu không xếp được ( không thỏa mãn): xét đến ca tiếp theo đến khi tìm
được ca thỏa mãn thì xếp
– Nếu khi xét xong một lớp mà vẫn còn có ca chưa xếp tiến hành xếp lại lớp đó với
một số điều chỉnh :
♦ Mức 1 : xét lại các ca học mà chưa được xếp bỏ bớt các ràng buộc mở rộng .
♦ Mức 2 : xếp lại tất cả các ca học của lớp đó bỏ bớt các ràng buộc mở rộng.
♦ Mức 3: xếp lại sau khi đổi chỗ môn chưa xếp được ( có độ ưu tiên thấp) cho
môn có độ ưu tiên cao ngay trên cho đến khi xếp được.
♦ Số lần xếp lại là giới hạn do có trường hợp không thể xếp được môn học, không
quá số ca học của lớp đó.
4.4.1. Công cụ
Các công cụ được sử dụng trong quá trình xây dựng hệ thống:
♦ Công cụ lập trình: Visual Studio .Net 2003, ngôn ngữ lập trình VB.Net.
♦ Chương trình chạy trên nền .Net Framework 1.1 và hệ điều hành Windows XP
Pro.
♦ Gồm các chức năng con chỉnh sửa danh sách chuyên ngành, lớp học, môn học,
giáo viên vào đầu mỗi kỳ hay năm học.
Hình 31. Giao diện chỉnh sửa danh sách chuyên ngành
Trên form có các nút Thêm, Sửa, Xóa chức năng tương ứng với tên nút.
Tương tự cho các giao diện chỉnh sửa danh sách lớp học, môn học, giáo viên.
Hình 32. Giao diện chỉnh sửa danh sách lớp học
Trên form, bên trái là danh sách các lớp học, di chuyển các hàng trên danh sách
thông tin thời gian học sẽ hiện ra tương ứng với lớp vừa chọn ở bên phải. Trên thanh
phía dưới danh sách lớp là các nút để di chuyển tới các lớp trong danh sách: nút << di
chuyển tới lớp đầu tiên trong danh sách, nút < di chuyển tới lớp liền trước lớp đang
chọn, nút > di chuyển tới lớp liền sau lớp đang chọn, nút >> di chuyển tới lớp ở cuối
danh sách.
Tương tự cho các giao diện chỉnh sửa danh sách môn học và giáo viên.
Hình 33. Giao diện chỉnh sửa danh sách môn học.
Hình 34. Giao diện chỉnh sửa danh sách giáo viên
Theo trình tự thao tác, đầu tiên nhập tên học kỳ và năm học lập thời khóa biểu
từ chức năng con Nhập học kỳ - năm học. Sau đó chọn lớp học, môn học và giáo viên
được phân công cho học kỳ từ các danh sách lớp học, môn học, giáo viên. Cuối cùng
là gán các môn học và giáo viên dạy cho mỗi lớp.
Hình 39. Giao diện chọn giáo viên giảng dạy cho học kỳ
Chọn chức năng Xếp TKB, sau đó chờ đến khi hiện ra thông báo Xếp xong
TKB thì việc xếp thời khóa biểu được hoàn thành.
Hình 43. Giao diện thông báo xếp xong thời khóa biểu
Các chức năng con của menu Xem TKB chỉ hiện ra khi việc xếp thời khóa biểu
đã được hoàn thành. Nhấn vào Thời khóa biểu lớp và Thời khóa biểu GVGD để xem
thời khóa biểu cho lớp và cho giáo viên giảng dạy.
Hình 46. Giao diện xem thời khóa biểu theo lớp
Hình 47. Giao diện xem thời lịch dạy giáo viên
Kết quả về mặt thời gian chạy là khá tốt so với các chương trình sử dụng các
thuật toán vét cạn hay mô phỏng tự nhiên.
♦ Thời khóa biểu lớp: chương trình cho kết quả thời khóa biểu lớp các ca xếp liền
nhau, không có tiết trống ở giữa. Các giờ trống thường là ở cuối buổi học. Ví dụ
thời khóa biểu lớp K49ĐA có số ca học nhiều nhất trong tuần:
♦ Thời khóa biểu giáo viên: chương trình cho kết quả đối với các giáo viên có số
ca dạy lớn số buổi phải đến trường là khá tốt. Ví dụ lịch dạy của giáo viên dạy
số ca nhiều nhất của môn Giáo dục học đại cương và Logic học đại cương:
♦ Cần thử nghiệm trên nhiều ví dụ khác để hoàn thiện hệ thống và đưa vào
ứng dụng thực tế.
♦ Tiếp tục nghiên cứu, nâng cấp chương trình thành một framework hoàn
thiện để mở rộng phạm vi ứng dụng và tăng tính tiện dụng của chương
trình.