Site logoTungTT

Mô hình hóa câu đố Binox

6 phút đọc
1011 từ

1. Giới thiệu#

Binox là một câu đố logic được mô tả như sau, cho một lưới các ô vuông với một số ô đã được điền sẵn XX hoặc OO. Người chơi cần hoàn thiện lưới bằng cách điền vào những ô trống XX hoặc OO thỏa mãn:

  • Lưới được phủ kín bởi XXOO
  • Trên mỗi hàng/cột không tồn tại chuỗi lớn hơn 2 ô liên tiếp được điền giống nhau
  • Trên mỗi hàng/cột số lượng XX bằng số lượng OO
  • Mỗi hàng/cột là duy nhất (Không có 2 hàng nào giống nhau, không có 2 cột nào giống nhau)

Dưới đây là ví dụ cho một câu đố Binox cỡ 6×6 và lời giải

binox_example

2. Mô hình hóa câu đố#

  • nRn_R là số hàng của lưới (nRn_R là một số chẵn)
  • nCn_C là số cột của lưới (nCn_C là một số chẵn)
  • FXF_X là tập hợp những ô (i,j)(i, j) đã được điền XX
  • FOF_O là tập hợp những ô (i,j)(i, j) đã được điền OO

2.1. Biến quyết định#

Với mỗi (i,j)(i, j) trong lưới xây dựng biến x(i,j)x(i, j) thỏa mãn

x(i,j)={1neˆˊoˆ (i,j) được đieˆˋn X 0neˆˊoˆ (i,j) được đieˆˋn O x(i, j) = \begin{cases} 1 & \text{nếu ô } (i, j) \text{ được điền X } \\ 0 & \text{nếu ô } (i, j) \text{ được điền O } \end{cases}

2.2. Các ràng buộc#

  • Các ô đã được điền từ đầu
{x(i,j)=1,(i,j)FXx(i,j)=0,(i,j)FO\begin{cases} x(i, j) = 1, \forall (i, j) \in F_X\\ x(i, j) = 0, \forall (i, j) \in F_O \end{cases}
  • Trên mỗi hàng không tồn tại chuỗi lớn hơn 2 ô liên tiếp được điền giống nhau
{x(i,j)+x(i,j+1)+x(i,j+2)2x(i,j)+x(i,j+1)+x(i,j+2)10i<nR,0j<nC2\begin{cases} x(i, j) + x(i, j + 1) + x(i, j + 2) \leq 2 \\ x(i, j) + x(i, j + 1) + x(i, j + 2) \geq 1 \end{cases} \\ \forall 0 \leq i < n_R, 0 \leq j < n_C - 2
  • Trên mỗi cột không tồn tại chuỗi lớn hơn 2 ô liên tiếp được điền giống nhau
{x(i,j)+x(i+1,j)+x(i+2,j)2x(i,j)+x(i+1,j)+x(i+2,j)10i<nR2,0j<nC\begin{cases} x(i, j) + x(i + 1, j) + x(i + 2, j) \leq 2 \\ x(i, j) + x(i + 1, j) + x(i + 2, j) \geq 1 \end{cases} \\ \forall 0 \leq i < n_R - 2, 0 \leq j < n_C
  • Trên mỗi hàng số lượng XXOO bằng nhau
j=0nC1x(i,j)=nC2,0i<nR\sum\limits_{j = 0}^{n_C - 1}{x(i, j)} = {n_C \over 2}, \\ \forall 0 \leq i < n_R
  • Trên mỗi cột số lượng XXOO bằng nhau
i=0nR1x(i,j)=nR2,0j<nC\sum\limits_{i = 0}^{n_R - 1}{x(i, j)} = {n_R \over 2}, \\ \forall 0 \leq j < n_C
  • Mỗi hàng là duy nhất. Để tuyến tính ràng buộc này ta diễn đạt lại như sau, với 2 hàng i,ji, j bất kỳ, tồn tại ít nhất một vị trí kk sao cho x(i,k)x(j,k)x(i, k) \ne x(j, k) .

    Với 2 hàng iji \ne j bất kỳ, và mỗi cột kk, xây dựng biến trung gian y(i,j,k)y(i, j, k) thỏa mãn

    y(i,j,k)={1neˆˊx(i,k)=x(j,k)0ngược lạiy(i, j, k) = \begin{cases} 1 & \text{nếu } x(i, k) = x(j, k) \\ 0 & \text{ngược lại} \end{cases}

    Sử dụng phương pháp hình học ta có thể biểu diễn được mối quan hệ giữa biến yy và các biến xx như sau

    {y(i,j,k)+x(i,k)+x(j,k)1y(i,j,k)+x(i,k)x(j,k)+1y(i,j,k)+x(j,k)x(i,k)+1x(i,k)+x(j,k)y(i,j,k)+10i,j<nR,ij,0k<nC\begin{cases} y(i, j, k) + x(i, k) + x(j, k) \geq 1 \\ y(i, j, k) + x(i, k) \leq x(j, k) + 1 \\ y(i, j, k) + x(j, k) \leq x(i, k) + 1 \\ x(i, k) + x(j, k) \leq y(i, j, k) + 1 \end{cases} \\ \forall 0 \leq i, j < n_R, i \ne j, 0 \leq k < n_C

    Sử dụng các biến yy ta tuyến tính hóa điều kiện ban đầu như sau

    k=0nC1y(i,j,k)nC1,0i,j<nR,ij\sum\limits_{k = 0}^{n_C - 1}{y(i, j, k)} \leq n_C - 1, \\ \forall 0 \leq i, j < n_R, i \ne j
  • Mỗi cột là duy nhất. Tương tự với điều kiện trên, với 2 cột iji \ne j bất kỳ, và mỗi hàng kk, xây dựng biến trung gian z(i,j,k)z(i, j, k) thỏa mãn

    z(i,j,k)={1neˆˊx(k,i)=x(k,j)0ngược lạiz(i, j, k) = \begin{cases} 1 & \text{nếu } x(k, i) = x(k, j) \\ 0 & \text{ngược lại} \end{cases}

    Biểu diễn zz qua các xx bằng hệ điều kiện

    {z(i,j,k)+x(k,i)+x(k,j)1z(i,j,k)+x(k,i)x(k,j)+1z(i,j,k)+x(k,j)x(k,i)+1x(k,i)+x(k,j)z(i,j,k)+10k<nR,0i,j<nC,ij\begin{cases} z(i, j, k) + x(k, i) + x(k, j) \geq 1 \\ z(i, j, k) + x(k, i) \leq x(k, j) + 1 \\ z(i, j, k) + x(k, j) \leq x(k, i) + 1 \\ x(k, i) + x(k, j) \leq z(i, j, k) + 1 \end{cases} \\ \forall 0 \leq k < n_R, 0 \leq i, j < n_C, i \ne j

    Tuyến tính hóa điều kiện ban đầu như sau

    k=0nR1z(i,j,k)nR1,0i,j<nC,ij\sum\limits_{k = 0}^{n_R - 1}{z(i, j, k)} \leq n_R - 1, \\ \forall 0 \leq i, j < n_C, i \ne j

2.3. Hàm mục tiêu#

Bài toán này không có hàm mục tiêu, bởi vì ta không cần tối thiểu hóa hay tối đa hóa gì cả, việc cần làm chỉ là tìm ra một nghiệm chấp nhận được. Về mặt kỹ thuật, khi lập trình ta có thể để hàm mục tiêu là một hằng số (mình hay chọn số 0).

3. Kết luận#

Điểm nhấn của câu đố này nằm ở điều kiện hàng/cột duy nhất, trên thực tế những điều kiện dạng này thường rất khó mô hình hóa một cách hiệu quả. Thử tưởng tượng chúng ta có số lượng hàng/cột lên đến 1000 khi đó số điều kiện sẽ là một con số rất lớn, trong trường hợp đó ta phải tìm ra những cách khác để giải quyết bài toán một cách hiệu quả.

Tham khảo thêm các câu đố Binox và biến thể tại Krazydad. Code mô hình hóa Binox bằng python có tại Tung-hehe

Happy modeling!