Site logoTungTT

Khóa luận tốt nghiệp và những câu chuyện - Phần 4: Vấn đề tràn bộ nhớ và cải thiện mô hình

12 phút đọc
2322 từ

1. Vấn đề tràn bộ nhớ#

Mô hình hoàn chỉnh ở phần trước mô tả đúng bài toán, nhưng với dữ liệu thật của một học kỳ thì mô hình có từ 1.3 đến 1.5 triệu biến và 1.7 đến 2 triệu ràng buộc. Mình đã từng lập trình mô hình này và để cho máy tính giải, treo máy qua đêm, hôm sau ngủ dậy thấy máy tính đã chạy được hơn 8 tiếng sau đó bị dừng vì tràn bộ nhớ và quan trọng nhất là vẫn chưa có một nghiệm chấp nhận nào được tìm thấy.

Phản ứng đầu tiên của mình khi đó là chạy lại 1 lần nữa - kết quả vẫn như vậy. Sau đó mình lục tung đống code xem có bug ở đâu không - không tìm thấy gì cả. Vậy là mình ngồi xem lại mô hình - không thấy gì, mô hình đã mô tả rất đúng bài toán, thậm chí còn được thu gọn vì đã phá tính đối xứng rồi.

Cuối cùng mình nhận ra không có gì sai cả, chỉ là kích cỡ bài toán lớn quá không thể giải quyết chỉ trong 1 lần giải được. Và một cách giải quyết rất tự nhiên thôi, to quá không giải quyết được thì chẻ nhỏ ra và giải từng phần một.

2. Chia bài toán thành hai giai đoạn#

Thay vì giải một mô hình khổng lồ duy nhất, bài toán được tách thành 2 giai đoạn và giải lần lượt.

Mô hình gốcquá lớn, tràn bộ nhớGiai đoạn 1Xếp thời gian cho môn thibiến: x(e, p), t(e', e, n)E_p: ca thi của từng môn thiGiai đoạn 2Xếp phòng cho môn thibiến: y(e, r)Lịch thi hoàn chỉnh

2.1. Số phòng yêu cầu tối thiểu#

Tách giai đoạn dễ khiến giai đoạn 1 xếp thời gian xong nhưng giai đoạn 2 lại không đủ phòng để xếp. Để tránh việc này, định nghĩa số phòng yêu cầu tối thiểu nen_e của môn thi ee là số phòng ít nhất cần có để chắc chắn đủ chỗ cho môn đó.

Ví dụ với 6 phòng thi sức chứa 10,10,20,20,30,3010, 10, 20, 20, 30, 30, môn thi có 6060 sinh viên cần ít nhất 44 phòng (ne=4n_e = 4), vì bất kỳ 4 phòng nào trong 6 phòng trên cũng đủ chỗ. Chỉ cần đảm bảo tại mỗi ca thi, tổng số phòng yêu cầu không vượt quá tổng số phòng thi tối đa MrM_r thì giai đoạn 2 chắc chắn xếp đủ phòng.

2.2. Mô hình xếp thời gian cho môn thi#

Giữ nguyên biến x(e,p)x(e, p), t(e,e,n)t(e', e, n) và hàm mục tiêu ở Phần 3, bỏ hết biến/ràng buộc liên quan đến phòng thi, thêm ràng buộc về số phòng yêu cầu tối thiểu

minimizeαsSeee,eEsn=f(ke)g(e)1γg(e)nt(e,e,n)+βpPleEkeσkeqex(e,p)subject topPx(e,p)=1,eEeEsx(e,p)1,sS,pPx(e,p)=0,eE,pPex(e,p)+qP(p,f(ke))x(e,q)1,sS,eeEs,pPeEnex(e,p)Mr,pPx(e,p)+x(e,p+n)1+t(e,e,n),p,p+nP,sS,eeEs,f(ke)n<g(e)x(e,p){0,1},eE,pPt(e,e,n){0,1},sS,eeEs,f(ke)n<g(e)\begin{aligned} \text{minimize} \quad & \alpha \sum \limits_{s \in S} \sum \limits_{\substack{e \neq e' \\ e, e' \in E_s}} \sum \limits_{n = f(k_e)}^{g(e) - 1} \gamma^{g(e) - n} \cdot t(e', e, n) + \beta \sum \limits_{p \in P_l} \sum \limits_{\substack{e \in E \\ k_e \geq \sigma}} k_e \cdot q_e \cdot x(e, p) \\[0.9em] \text{subject to} \quad & \sum \limits_{p \in P} x(e, p) = 1, \quad \forall e \in E \\[0.6em] & \sum \limits_{e \in E_s} x(e, p) \leq 1, \quad \forall s \in S, p \in P \\[0.6em] & x(e, p) = 0, \quad \forall e \in E, p \in P_e \\[0.6em] & x(e, p) + \sum \limits_{q \in P(p, f(k_e))} x(e', q) \leq 1, \quad \forall s \in S, e \neq e' \in E_s, p \in P \\[0.6em] & \sum \limits_{e \in E} n_e \cdot x(e, p) \leq M_r, \quad \forall p \in P \\[0.6em] & x(e', p) + x(e, p + n) \leq 1 + t(e', e, n), \quad \forall p, p + n \in P, s \in S, e \neq e' \in E_s, f(k_e) \leq n < g(e) \\[0.6em] & x(e, p) \in \{0, 1\}, \quad \forall e \in E, p \in P \\[0.6em] & t(e', e, n) \in \{0, 1\}, \quad \forall s \in S, e \neq e' \in E_s, f(k_e) \leq n < g(e) \end{aligned}

2.3. Mô hình xếp phòng cho môn thi#

Sau khi giải xong giai đoạn 1, với mỗi ca thi pp ta có tập EpE_p các môn thi được xếp vào ca đó. Giai đoạn này chỉ còn cần xếp phòng, với thêm mục tiêu hạn chế tổng số phòng sử dụng (vì nen_e luôn \geq số phòng thật sự cần dùng)

minimizerReEy(e,r)subject toy(e,r)=0,eE,rRerRcry(e,r)qe,eEeEpy(e,r)1,rR,pPy(e,r){0,1},eE,rR\begin{aligned} \text{minimize} \quad & \sum \limits_{r \in R} \sum \limits_{e \in E} y(e, r) \\[0.9em] \text{subject to} \quad & y(e, r) = 0, \quad \forall e \in E, r \in R_e \\[0.6em] & \sum \limits_{r \in R} c_r \cdot y(e, r) \leq q_e, \quad \forall e \in E \\[0.6em] & \sum \limits_{e \in E_p} y(e, r) \leq 1, \quad \forall r \in R, p \in P \\[0.6em] & y(e, r) \in \{0, 1\}, \quad \forall e \in E, r \in R \end{aligned}

2.4. Đánh đổi cho việc chia nhỏ#

Nếu để ý kỹ bạn sẽ thấy việc sử dụng "số phòng yêu cầu tối thiểu" đã khiến mô hình có một lỗ hổng, đó là một số môn sẽ yêu cầu quá nhiều phòng. Hãy xem lại ví dụ với 6 phòng thi sức chứa 10,10,20,20,30,3010, 10, 20, 20, 30, 30, môn thi có 6060 sinh viên. Tất nhiên với 4 phòng thi bất kỳ kiểu gì cũng xếp được môn này nhưng có thể môn này chỉ cần 2 phòng (30, 30) hoặc 3 phòng (10, 20, 30) thôi là đủ rồi.

Mình hoàn toàn nhận thức được điều đó nhưng sau nhiều thử nghiệm với nhiều cách khác nhau mình vẫn chọn làm cách này vì hai lý do sau:

  • Số lượng phòng trong bộ dữ liệu mình làm việc là dư thừa (tức là mình có thể phân chia phòng thoải mái)
  • Mối quan tâm chính của bài toán này tại trường Đại học Khoa học Tự nhiên là các vấn đề về thời gian

Sau khi đã chia nhỏ, giai đoạn 2 giải rất nhanh (dưới 1 giây), nhưng giai đoạn 1 vẫn chạy chậm và nghiệm chưa đủ tốt - đó là lý do cho phần tiếp theo.

3. Cải thiện mô hình bằng tìm kiếm địa phương#

Ý tưởng: giải giai đoạn 1 đến khi có một nghiệm khởi tạo chấp nhận được, sau đó lặp lại một khung chung để cải thiện dần - thu hẹp không gian tìm kiếm quanh nghiệm hiện tại theo một "quy tắc riêng" và giải lại, lặp lại quá trình cho đến khi không tìm được nghiệm tốt hơn.

Nghiệm hiện tại SThu hẹp bài toán quanh S(quy tắc riêng của từng kỹ thuật)Giải lại (Mục 2.2), được nghiệm S'S' tốt hơnS?S ← S', lặp lạikhôngDừng, trả về nghiệm S

3.1. Kỹ thuật thứ nhất - thu hẹp không gian quanh mỗi môn thi#

Với nghiệm hiện tại, môn thi ee đang xếp ở ca thi pp. Xây dựng tập C(e,ρ)C(e, \rho) gồm các ca thi cách pp không quá ρ\rho ca (ρ\rho cho trước) rồi giới hạn mỗi môn thi chỉ được xếp trong tập này. Ví dụ ee ở ca 66, ρ=3\rho = 3 thì C(e,3)={3,...,9}C(e, 3) = \{3, ..., 9\}. Đây chính là "quy tắc riêng" điền vào khung chung ở trên:

Môn thi e đang xếp ở ca thi pC(e, ρ) = các ca thi cách p không quá ρ caGiới hạn: e chỉ được xếp lại trong C(e, ρ)

3.2. Kỹ thuật thứ hai - cố định các môn đã "ổn"#

Môn thi ee được gọi là có thời gian ôn tập tốt nếu mọi sinh viên đăng ký ee đều có thời gian ôn tập môn ee lớn hơn ngưỡng σ\sigma cho trước. "Quy tắc riêng" của kỹ thuật này là một phép phân loại cho từng môn thi:

Với mỗi môn thi eMọi SV đăng ký e đều cóthời gian ôn tập > σ ca?khôngCố định e đúng vị tríca thi hiện tại trong SKhông ràng buộc thêm(e được xếp lại tự do)

3.3. Thuật toán xếp lịch thi hoàn chỉnh#

Giải mô hình xếp thời gian (Mục 2.2)→ nghiệm khởi tạo SCải thiện bằng Kỹ thuật thứ nhất (Mục 3.1)Cải thiện bằng Kỹ thuật thứ hai (Mục 3.2)Giải mô hình xếp phòng (Mục 2.3)→ lịch thi hoàn chỉnh

Toàn bộ các bài toán quy hoạch hỗn hợp nguyên ở từng bước được giải bằng Gurobi 10.0.

4. Kết luận#

Trên đây là thuật toán cốt lõi cho nghiên cứu của bọn mình, tuy nhiên đây mới chỉ là lý thuyết trên giấy và để có thể đem lại kết quả tốt vẫn cần rất nhiều những kỹ thuật khác liên quan đế cấu trúc dữ liệu và lập trình. Nhưng mình sẽ không trình bày ở đây vì đó là phần mà Quý Anh và Quân đảm nhận. Phần sau sẽ là phần cuối của series, mình sẽ trình bày về các kết quả đạt được của dự án này và một chút cảm nhận cá nhân.

Đọc tiếp Phần 5