1

One has a rectangular-prism 3 dimensional space, e.g. {xmin, xmax}, {ymin, ymax}, {zmin, zmax}. The goal is to use a pre-defined "grid" of at most N cubes to maximally tile the 3 dimensional space. It will use no more than N cubes, if N cannot evenly be tiled into the space. Note cubes are located at the cube centerpoints (i.e. it is a grid), not the cube edges.

For example, in the simple case of N=30, and {0,3}, {0,3}, {0,3}. The correct answer is to use cubes of side length 1, in which case 27 cubes will be used in 3 rows of 3 columns of 3 stacks.

In the more difficult case of N=1000, and {0, 100}, {0, 0}, {0, 50}, obviously the y-dimension uses only 1 row of cubes (it can not use any more), so the z and x dimensions must use the 1000 cubes arranged at a ratio of 2:1. 100/L * 50/L = 1000. So, side length is probably around 2.2361, because 22 x 1 x 45 = 990 is the closest we're going to get to 1000 (alternatively, we've minimized the expanse that we could not cover with our cube centers). Of course the sides must be an integer number of the cubes.


I'm trying to work out a system of equations to solve this, but I have a weird feeling that this is a satisfaction (minimization) problem and thus there needs to be some iteration... Here is an attempt at the system of equations anyway:

L, xe, ye, ze ∊ Positive Reals
N, x, y, z ∊ Natural Numbers
x*y*z ≤ N
(x-1)*L ≤ xe
(y-1)*L ≤ ye
(z-1)*L ≤ ze
x,y,z ≥ 1
L = min(i) { (xe*ye*ze) - ((x-1)*i*(y-1)*i*(z-1)*i) }

I made it so that it is x-1, y-1 etc., to mean that they can go outside the width by exactly and at most 1 cube size. I can't decide whether it is correct to do this in all dimensions, or specify that it must go outside in at most one dimension (the smallest?).

Cimbali
  • 11,012
  • 1
  • 39
  • 68
rveale
  • 66
  • 1
  • 10
  • This should probably be on math stack exchange, where incidentally you can typeset latex. – Mad Physicist Mar 04 '16 at 17:03
  • i think the minimum values need to start from 1 instead of 0 –  Mar 04 '16 at 19:28
  • Are you trying to get the maximum number of cubes or the minimum amount of non-tiled space? – Cimbali Mar 05 '16 at 01:34
  • For example in a 2D space of size 3 by 5 with N=4, would you want four 1.5x1.5 tiles (hence loosing a surface of 6) or would you want two 2.5x2.5 tiles (loosing a surface of 2.5, but less tiles)? – Cimbali Mar 05 '16 at 22:02
  • Sounds interesting. But the question is confused or at least confusing. Your title talks about "unit" cubes, which by definition have side length 1. Then you talk about a side length of more than one. You should illustrate by considering the 2d version and providing at least one picture to show what you mean. – Gene Mar 06 '16 at 21:26
  • I'm voting to close this question as off-topic because it is about mathematics. – High Performance Mark Mar 09 '16 at 06:51
  • 1
    Hm, probably more relevant at math stack exchange but people ask "algorithm" problems that are actually math all the time... – rveale Mar 10 '16 at 11:59

1 Answers1

1

General idea

The intuition here is that the amount of cubes in each direction is going to be proportional to the size of the space in that direction, because cubes are regular. Another hint to this is that the solution to the problem "how many cubes in each direction" does only depend on the ratios between sizes, not on their actual values: if you multiply each dimension by the same dilating factor, your solution will still be the same.

Simplifying the problem

Suppose your space is of size dx, dy, dz, all non-zero, and you want to use up to N cubes.

Let us express our constraints as:

find Nx, Ny, Nz, L such that
- Nx * Ny * Nz ≤ N
- Nx * L ≤ dx
- Ny * L ≤ dy
- Nz * L ≤ dz
Minimizing the "lost volume": (dx * dy * dz - L^3 * Nx * Ny * Nz)

You may want to maximize Nx * Ny * Nz instead. Note also that minimizing the volume that isn't tiled is equivalent to maximizing L^3 * Nx * Ny * Nz.

A final observation is that if your solution is optimal in any way (cube number or tiled volume), at least one of the dimensions will have the equality N@ * L == d@, otherwise we may increase L.

Let us suppose without loss of generality that dx is this dimension and let us divide all lengths by dx, thus with a@ = d@ / dx for @ being y and z (and ax = 1 if needed). Then we may rewrite the problem:

find Nx, Ny, Nz, L such that
- Nx * Ny * Nz ≤ N
- Nx = dx / L
- Ny / Nx ≤ ay
- Nz / Nx ≤ az
Maximizing the cubes' volume: dx^3 * (Ny / Nx) * (Nz / Nx)

Hence your problem is how to get ratios of numbers of cubes on each side as close as possible to the ratios of the sizes, while maintaining Nx * Ny * Nz ≤ N -- the same way you instinctively approached your N = 1000 case.

Algorithm suggestion: You could, for example, iteratively increase Nx and set N@ = floor(a@ * Nx) for @ in {y,z} while Nx * Ny * Nz ≤ N, keeping the best solution.

Optimal solutions

Note that in the case that your ratios ay and az are rational, as in your examples, an exact solution to the minimization might be found rather easily.

Let us write a@ = n@ / m@ for @ in {y,z}, then we can find an exact solution with by setting
Nx = lcm(my, mz) - the least common multiple of the denominators. Note that in the case where dx, dy, dz are all integer, this means Nx = dx / gcd(dx, dy, dz).

Thus if Nx^3 * ax * ay = lcm(my, mz) ^3 * ny * nz / (my * mz) ≤ N, this solution also fits the constraint on N. To write it out in full:

Nx = lcm(my, mz)
L  = dx / Nx
Ny = Nx * ay
Nz = Nx * az

In your examples, for the 3D case, you have ay = az = 1 and a solution with Nx = Ny = Nz = 1, and for the 2D case we have only dimensions x, z with az = 1/2, this you have a solution with Nx = 2 and Nz = 1

Now you can add more cubes because you have a lot of slack in the Nx * Ny * Nz ≤ N constraint. In particular, you can multiply each coordinate by floor(cbrt(N / (Nx * Ny * Nz))) which is floor(cbrt(30 / 1)) = 3 in your first case, and floor(sqrt(1000 / 2)) = 22 in your 2D case.

Summing up results to your examples:

space={3,3,3} N=30 : Nx=3, Ny=3, Nz=3, L=1
space={100, 50} N=1000 : Nx=44, Nz=22, L=2.72727272...

Heuristic(s)

If we can't find an exact answer, we can make an educated guess. In order to not iterate over Nx values, or just to have a sensible initial guess.

Note that the bigger the denominator, the smaller the intervals between two fractions with this same denominator. This doesn't mean that given a real number your want to approximate, the precision of your approximation is proportional to the size of the denominator, but that the average precision when approximating a lot of real numbers would be better (hence, that you've got a better probability in the single case).

We are trying to maximize (Ny / Nx) * (Nz / Nx), thus from our constraints on ay and az we get (N@ + 1) / Nx ≥ a@, hence N@ ≥ a@ * Nx - 1. Now, Nx * Ny * Nz ≤ N thus a bound on Nx is:
Nx * (Nx * ay - 1) * (Nx * az - 1) ≤ N

But I'm too lazy to solve that so let's even simplify some more: N@ ≥ a@ * Nx - 1 ≥ a@ * Nx
Thus:Nx * (Nx * ay) * (Nx * az) ≤ N

So you may try as a first guess:

Nx = floor(crbt(N / (ay * az)))
L  = dx / Nx
Ny = floor(Nx * ay)
Nz = floor(Nx * az)

or (exactly the same thing, without the a@):

Nx = floor(crbt(N * dx * dx / (dy * dz)))
L  = dx / Nx
Ny = floor(dy / L)
Nz = floor(dz / L)

If you want to make sure you have the optimal value, you might want to try to see if the simplifications restrained Nx too much, so increment it until Nx * Ny * Nz ≥ N and keep the best configuration.

Similarly, different values of Nx might allow to get Nx * ay and Nx * az closer to their integer part, thus wasting less space. You could decrement Nx until it is small. Note that you can skip any value that divides a value of Nx that you already tried.

Choice of "filled dimension" x

Remains the choice of which direction will be x -- instinctively I would say take the dimension in which your space is the biggest but this is again only a heuristic, and if you want the optimal answer you will have to try all directions.

On exact solutions though, where side size ratios are rational, picking any side as x will do since all dimensions will be filled.

Cimbali
  • 11,012
  • 1
  • 39
  • 68
  • Hi Cimbali, thank you for the thought out response, I'll work through it. I think the least/greatest common multiple intuition will turn out to be the correct one. Also, you're right, it's not clear what the goal is. If it is to minimize the lost volume, we might use many fewer cubes. If we want to maximize N, it might be most efficient to "cheat" and "miss" a lot of the space to ensure all the cubes are used. – rveale Mar 08 '16 at 06:02