Skip to content

[Model] SquareTiling #820

@isPANN

Description

@isPANN

Motivation

SQUARE-TILING (P250) from Garey & Johnson, A8 GP13. A classical NP-complete problem in the family of Wang tiling problems. Given a set of colored square tiles (Wang tiles) and a grid size N, the question is whether the tiles can be placed on an N x N grid such that adjacent tiles have matching edge colors. This problem bridges combinatorial graph problems and geometric/constraint satisfaction problems. It is the target of a reduction from Directed Hamiltonian Path (R194), and its infinite variant (tiling the entire plane) is famously undecidable (Berger, 1966).

Definition

Name: SquareTiling
Canonical name: Square Tiling; also: Bounded Wang Tiling, Wang Domino Problem (bounded variant), Finite Tiling
Reference: Garey & Johnson, Computers and Intractability, A8 GP13

Mathematical definition:

INSTANCE: Set C of "colors," collection T ⊆ C^4 of "tiles" (where <a,b,c,d> denotes a tile whose top, right, bottom, and left sides are colored a, b, c, and d, respectively), and a positive integer N ≤ |C|.
QUESTION: Is there a tiling of an N x N square using the tiles in T, i.e., an assignment of a tile f(i,j) in T to each ordered pair i, j, 1 ≤ i ≤ N, 1 ≤ j ≤ N, such that (1) if f(i,j) = <a,b,c,d> and f(i+1,j) = <a',b',c',d'>, then a = c' (top of lower tile matches bottom of upper tile), and (2) if f(i,j) = <a,b,c,d> and f(i,j+1) = <a',b',c',d'>, then b = d' (right of left tile matches left of right tile)?

Note: Tiles may be reused (each tile type can appear at multiple grid positions). Tiles may NOT be rotated or reflected.

Variables

  • Count: N^2 (one variable per grid cell)
  • Per-variable domain: {0, 1, ..., |T|-1} -- the index of the tile type placed at cell (i, j)
  • Meaning: variable t_{i,j} in {0, ..., |T|-1} assigns a tile type to grid cell (i, j). The configuration is valid if for all adjacent cell pairs, the shared edge colors match: top/bottom between vertically adjacent cells, left/right between horizontally adjacent cells.

Schema (data type)

Type name: SquareTiling
Variants: none

Field Type Description
num_colors usize Number of colors
tiles Vec<(usize, usize, usize, usize)> Collection of tile types; each (top, right, bottom, left) is a tuple of color indices
grid_size usize The integer N specifying an N x N tiling grid

Notes:

  • This is a feasibility (decision) problem: Value = Or.
  • Key getter methods: num_colors() (= |C|), num_tiles() (= |T|), grid_size() (= N).
  • Tiles are NOT rotatable -- <a,b,c,d> is distinct from <b,c,d,a>.
  • The same tile type may be placed at multiple grid positions.

Complexity

  • Decision complexity: NP-complete (Garey, Johnson, and Papadimitriou, 1977; transformation from Directed Hamiltonian Path).
  • Best known exact algorithm: O(|T|^{N^2}) via brute-force enumeration of all tile assignments, with constraint propagation pruning in practice. No sub-exponential exact algorithm is known.
  • Concrete complexity expression: "num_tiles^(grid_size^2)" (for declare_variants!)
  • Special cases: When N is given in unary, the problem is NP-complete. When N is given in binary (as log N bits), the problem becomes NEXP-complete. For fixed tile sets, the bounded tiling problem can sometimes be solved in polynomial time depending on the tile structure.
  • Infinite variant: Determining whether a given tile set can tile the entire plane (Z × Z) is undecidable (Berger, 1966). The periodic tiling variant (period < N) is also NP-complete.
  • References:
    • M. R. Garey, D. S. Johnson, C. H. Papadimitriou (1977). Unpublished results. NP-completeness of bounded tiling via reduction from Directed Hamiltonian Path.
    • R. Berger (1966). "The Undecidability of the Domino Problem." Memoirs of the AMS, No. 66. American Mathematical Society, Providence, RI.
    • H. Wang (1961). "Proving theorems by pattern recognition II." Bell System Technical Journal, 40(1), pp. 1-41. Original formulation of Wang tiles.

Specialization

  • This is a special case of: Constraint Satisfaction Problem (CSP) -- each grid cell is a variable, the tile set defines unary constraints, and color-matching defines binary constraints between adjacent cells.
  • Known special cases: 1 x N tiling (reduces to path finding in a directed graph of tile adjacencies, solvable in polynomial time). Tiling with a single tile type is trivially decidable.
  • Generalizations: Tiling arbitrary regions (not just squares), tiling with hexagonal tiles, tiling the infinite plane (undecidable).

Extra Remark

Full book text:

INSTANCE: Set C of "colors," collection T ⊆ C4 of "tiles" (where <a,b,c,d> denotes a tile whose top, right, bottom, and left sides are colored a,b,c, and d, respectively), and a positive integer N ≤ |C|.
QUESTION: Is there a tiling of an N×N square using the tiles in T, i.e., an assignment of a tile A(i,j) ∈ T to each ordered pair i,j, 1 ≤ i ≤ N, 1 ≤ j ≤ N, such that (1) if f(i,j) = <a,b,c,d> and f(i+1,j) = <a',b',c',d'>, then a = c', and (2) if f(i,j) = <a,b,c,d> and f(i,j+1) = <a',b',c',d'>, then b = d'?

Reference: [Garey, Johnson, and Papadimitriou, 1977]. Transformation from DIRECTED HAMILTONIAN PATH.
Comment: Variant in which we ask if T can be used to tile the entire plane (Z×Z) "periodically" with period less than N is also NP-complete. In general, the problem of whether a set of tiles can be used to tile the plane is undecidable [Berger, 1966], as is the problem of whether a set of tiles can be used to tile the plane periodically.

How to solve

  • It can be solved by (existing) bruteforce. (Enumerate all |T|^{N^2} tile assignments; check color-matching constraints for all adjacent pairs.)
  • It can be solved by reducing to integer programming. (Binary variables x_{i,j,t} = 1 if tile type t is placed at cell (i,j). Constraints: exactly one tile per cell, and for each adjacent pair, the shared edge colors must match. Companion rule issue to be filed separately.)
  • Other: Backtracking with arc consistency / constraint propagation.

Example Instance

Input:
Colors: C = {0, 1, 2} (3 colors)
Tiles (top, right, bottom, left):

  • t0 = <0, 1, 2, 0>
  • t1 = <0, 0, 2, 1>
  • t2 = <2, 1, 0, 0>
  • t3 = <2, 0, 0, 1>

Grid size: N = 2 (2 × 2 grid)

Valid tiling:

| (1,1)=t0 | (1,2)=t1 |
| (2,1)=t2 | (2,2)=t3 |

Check constraints:

  • Horizontal (1,1)-(1,2): right of t0 = 1, left of t1 = 1. ✓
  • Horizontal (2,1)-(2,2): right of t2 = 1, left of t3 = 1. ✓
  • Vertical (1,1)-(2,1): bottom of t0 = 2, top of t2 = 2. ✓
  • Vertical (1,2)-(2,2): bottom of t1 = 2, top of t3 = 2. ✓

Answer: YES — a valid 2 × 2 tiling exists. There are 16 valid tilings in total out of 256 possible assignments.

Note: The tile set is designed so that row 1 tiles (t0, t1) have top=0 and bottom=2, while row 2 tiles (t2, t3) have top=2 and bottom=0, ensuring vertical compatibility. Horizontal compatibility is ensured by the right/left color pairs: tiles with right=1 must neighbor tiles with left=1, and tiles with right=0 must neighbor tiles with left=0.

Negative example:
Keep only tiles t0 = <0, 1, 2, 0> and t2 = <2, 1, 0, 0> from the positive example.

Both tiles have right = 1 but left = 0. For horizontal adjacency, the right side of one tile must match the left side of its neighbor. Since right = 1 ≠ 0 = left for both tiles, no two tiles can be placed side by side. Exhaustive search over all 2^4 = 16 possible assignments confirms no valid 2 × 2 tiling exists. Answer: NO.

Python validation script
from itertools import product

def check_tiling(tiles, n):
    count = 0
    for assignment in product(range(len(tiles)), repeat=n*n):
        grid = [[assignment[i*n+j] for j in range(n)] for i in range(n)]
        valid = True
        for i in range(n):
            for j in range(n):
                t = tiles[grid[i][j]]
                if j+1 < n:
                    t_right = tiles[grid[i][j+1]]
                    if t[1] != t_right[3]: valid = False; break
                if i+1 < n:
                    t_below = tiles[grid[i+1][j]]
                    if t[2] != t_below[0]: valid = False; break
            if not valid: break
        if valid: count += 1
    return count

# Positive: 4 tiles, N=2
tiles_pos = [(0,1,2,0), (0,0,2,1), (2,1,0,0), (2,0,0,1)]
assert check_tiling(tiles_pos, 2) == 16
print("Positive: 16 valid tilings (correct)")

# Negative: only t0 and t2
tiles_neg = [(0,1,2,0), (2,1,0,0)]
assert check_tiling(tiles_neg, 2) == 0
print("Negative: 0 valid tilings (correct)")

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoodAn issue passed all checks.modelA model problem to be implemented.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions