Site logoTungTT

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

•
4 phút đọc
•
730 từ

1. Giới thiệu#

Troix 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, OO hoặc II. 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, OO và II thỏa mãn:

  • Lưới được phủ kín bởi XX, OO và II
  • 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, OO và II bằng nhau

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

troix_example

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

  • nRn_R là số hàng của lưới (nRn_R là số chia hết cho 3)
  • nCn_C là số cột của lưới (nCn_C là số chia hết cho 3)
  • 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
  • FIF_I là tập hợp những ô (i,j)(i, j) đã được điền II

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

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

x(i,j)={1neˆˊu oˆ (i,j) được đieˆˋn X0ngược lại x(i, j) = \begin{cases} 1 & \text{nếu ô } (i, j) \text{ được điền } X \\ 0 & \text{ngược lại } \end{cases} y(i,j)={1neˆˊu oˆ (i,j) được đieˆˋn O0ngược lạiy(i, j) = \begin{cases} 1 & \text{nếu ô } (i, j) \text{ được điền } O\\ 0 & \text{ngược lại} \end{cases} z(i,j)={1neˆˊu oˆ (i,j) được đieˆˋn I0ngược lạiz(i, j) = \begin{cases} 1 & \text{nếu ô } (i, j) \text{ được điền } I\\ 0 & \text{ngược lại} \end{cases}

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

  • Các ô đã được điền từ đầu
{x(i,j)=1,∀(i,j)∈FXy(i,j)=1,∀(i,j)∈FOz(i,j)=1,∀(i,j)∈FI\begin{cases} x(i, j) = 1, \forall (i, j) \in F_X \\ y(i, j) = 1, \forall (i, j) \in F_O \\ z(i, j) = 1, \forall (i, j) \in F_I \end{cases}
  • Lưới được phủ kín bởi XX, OO và II
x(i,j)+y(i,j)+z(i,j)=1,∀0≤i<nR,0≤j<nCx(i, j) + y(i, j) + z(i, j) = 1, \\ \forall 0 \leq i < n_R, 0 \leq j < n_C
  • 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)≤2y(i,j)+y(i,j+1)+y(i,j+2)≤2z(i,j)+z(i,j+1)+z(i,j+2)≤2∀0≤i<nR,0≤j<nC−2\begin{cases} x(i, j) + x(i, j + 1) + x(i, j + 2) \leq 2 \\ y(i, j) + y(i, j + 1) + y(i, j + 2) \leq 2 \\ z(i, j) + z(i, j + 1) + z(i, j + 2) \leq 2 \\ \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)≤2y(i,j)+y(i+1,j)+y(i+2,j)≤2z(i,j)+z(i+1,j)+z(i+2,j)≤2∀0≤i<nR−2,0≤j<nC\begin{cases} x(i, j) + x(i + 1, j) + x(i + 2, j) \leq 2 \\ y(i, j) + y(i + 1, j) + y(i + 2, j) \leq 2 \\ z(i, j) + z(i + 1, j) + z(i + 2, j) \leq 2 \\ \end{cases} \\ \forall 0 \leq i < n_R - 2, 0 \leq j < n_C
  • Trên mỗi hàng số lượng XX, OO và II bằng nhau
{∑j=0nC−1x(i,j)=nC3∑j=0nC−1y(i,j)=nC3∑j=0nC−1z(i,j)=nC3∀0≤i<nR\begin{cases} \sum\limits_{j = 0}^{n_C - 1}{x(i, j)} = {n_C \over 3} \\ \sum\limits_{j = 0}^{n_C - 1}{y(i, j)} = {n_C \over 3} \\ \sum\limits_{j = 0}^{n_C - 1}{z(i, j)} = {n_C \over 3} \\ \end{cases} \\ \forall 0 \leq i < n_R
  • Trên mỗi cột số lượng XX, OO và II bằng nhau
{∑i=0nR−1x(i,j)=nR3∑i=0nR−1y(i,j)=nR3∑i=0nR−1z(i,j)=nR3∀0≤j<nC\begin{cases} \sum\limits_{i = 0}^{n_R - 1}{x(i, j)} = {n_R \over 3} \\ \sum\limits_{i = 0}^{n_R - 1}{y(i, j)} = {n_R \over 3} \\ \sum\limits_{i = 0}^{n_R - 1}{z(i, j)} = {n_R \over 3} \\ \end{cases} \\ \forall 0 \leq j < n_C

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#

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

Happy modeling!