Quantcast
Channel: Planet Sage
Viewing all articles
Browse latest Browse all 414

Sébastien Labbé: Tiling a polyomino with polyominoes in SageMath

$
0
0

Suppose that you 3D print many copies of the following 3D hexo-mino at home:

sage:fromsage.combinat.tilingimportPolyomino,TilingSolversage:p=Polyomino([(0,0,0),(0,1,0),(1,0,0),(2,0,0),(2,1,0),(2,1,1)],color='blue')sage:p.show3d()LaunchedhtmlviewerforGraphics3dObject
/Files/2020/polyomino.png

You would like to know if you can tile a larger polyomino or in particular a rectangular box with many copies of it. The TilingSolver module in SageMath is made for that. See also this recent question on ask.sagemath.org.

sage:T=TilingSolver([p],(7,5,3),rotation=True,reflection=False,reusable=True)sage:TTilingsolverof1piecesintoaboxofsize24Rotationallowed:TrueReflectionallowed:FalseReusingpiecesallowed:True

There is no solution when tiling a box of shape 7x5x3 with this polyomino:

sage:T.number_of_solutions()0

But there are 4 solutions when tiling a box of shape 4x3x2 with this polyomino:

sage:T=TilingSolver([p],(4,3,2),rotation=True,reflection=False,reusable=True)sage:T.number_of_solutions()4

We construct the list of solutions:

sage:solutions=[solforsolinT.solve()]

Each solution contains the isometric copies of the polyominoes tiling the box:

sage:solutions[0][Polyomino:[(0,0,0),(0,0,1),(0,1,0),(1,1,0),(2,0,0),(2,1,0)],Color:#ff0000,Polyomino:[(0,1,1),(0,2,0),(0,2,1),(1,1,1),(2,1,1),(2,2,1)],Color:#ff0000,Polyomino:[(1,0,0),(1,0,1),(2,0,1),(3,0,0),(3,0,1),(3,1,0)],Color:#ff0000,Polyomino:[(1,2,0),(1,2,1),(2,2,0),(3,1,1),(3,2,0),(3,2,1)],Color:#ff0000]

It may be easier to visualize the solutions, so we define the following function allowing to draw the solutions with different colors for each piece:

sage:defdraw_solution(solution,size=0.9):....:colors=rainbow(len(solution))....:forpiece,colinzip(solution,colors):....:piece.color(col)....:returnsum((piece.show3d(size=size)forpieceinsolution),Graphics())
sage:G=[draw_solution(sol)forsolinsolutions]sage:G[Graphics3dObject,Graphics3dObject,Graphics3dObject,Graphics3dObject]
sage:G[0]# in Sage, this will open a 3d viewer automatically
/Files/2020/solution0.png
sage:G[1]
/Files/2020/solution1.png
sage:G[2]
/Files/2020/solution2.png
sage:G[3]
/Files/2020/solution3.png

We may save the solutions to a file:

sage:G[0].save('solution0.png',aspect_ratio=1,zoom=1.2)sage:G[1].save('solution1.png',aspect_ratio=1,zoom=1.2)sage:G[2].save('solution2.png',aspect_ratio=1,zoom=1.2)sage:G[3].save('solution3.png',aspect_ratio=1,zoom=1.2)

Question: are all of the 4 solutions isometric to each other?

The tiling problem is solved due to a reduction to the exact cover problem for which dancing links Knuth's algorithm provides all the solutions. One can see the rows of the dancing links matrix as follows:

sage:d=T.dlx_solver()sage:dDancinglinkssolverfor24columnsand56rowssage:d.rows()[[0,1,2,4,5,11],[6,7,8,10,11,17],[12,13,14,16,17,23],...[4,6,7,9,10,11],[10,12,13,15,16,17],[16,18,19,21,22,23]]

The solutions to the dlx solver can be obtained as follows:

sage:it=d.solutions_iterator()sage:next(it)[3,36,19,52]

These are the indices of the rows each corresponding to an isometric copy of the polyomino within the box.

Since SageMath-9.2, the possibility to reduce the problem to a MILP problem or a SAT instance was added to SageMath (see #29338 and #29955):

sage:d.to_milp()(BooleanProgram(noobjective,56variables,24constraints),MIPVariableofdimension1)sage:d.to_sat_solver()CryptoMiniSatsolver:56variables,2348clauses.

Viewing all articles
Browse latest Browse all 414

Trending Articles