我的情况
- 我有 N 个矩形
- 矩形都具有相同的形状(例如 2 英寸宽 x 1 英寸高) - 让我们将此尺寸称为 Sw 和 Sh 的宽度和高度
- 我想将这些矩形放置在网格中,使矩形完全位于顶部并彼此相邻 - 就像您在电子表格中看到的一样
- 我需要的是:给定 N、Sw 和 Sh,将这些矩形堆叠成可能的最方形排列的行数 (R) 和列数 (C) 是多少
- 可以理解的是,R & C 可能提供比需要更多的单元格(例如,如果 N=15,Sw=1,Sh=1 则 R=4,C=4 为 15 个矩形产生 16 个“槽” - 这是可以的。
- 如果 Sw=Sh 那么我卑微的数学技能就足够了——当它们的矩形有不同的宽度和高度时——坦率地说,这超出了我的能力。
一些笔记
- 是的,我读过这个问题:堆叠矩形以尽可能少地占用空间,不,它没有帮助。这也不是同一个问题。这个问题是关于可能具有不同大小的矩形,在这个问题中,矩形具有相同的大小
- 是的,我在 wolfram.com 等网站上搜索过,但没有运气
- 我没有很强的数学背景,所以我解决这个问题的方式本身可能会阻止我找到答案 - 我已经尝试过与平铺、剖析、分解相关的相关搜索,但在那里也没有任何成功
一些例子
the * indicates the edges of the rects
the | indicates that a cell is "filled-in"
Notice that not all R*C cells are filled in, but only and exactly N cells
IF N=1, Sw=2, Sh=1 THEN R=1, C=1
********
*||||||*
********
IF N=2, Sw=2, Sh=1 THEN R=2, C=1
********
*||||||*
********
*||||||*
********
IF N=3, Sw=2, Sh=1 THEN R=2, C=2
***************
*||||||* *
***************
*||||||*||||||*
***************
IF N=4, Sw=2, Sh=1 THEN R=2, C=2
***************
*||||||*||||||*
***************
*||||||*||||||*
***************
IF N=5, Sw=2, Sh=1 THEN R=3, C=2
***************
*||||||* *
***************
*||||||*||||||*
***************
*||||||*||||||*
***************
AaronofTomorrow's answer的实现
# Implementation of AaronofTomorrow's answer
# implemented in python 2.6
# reasonable output
# works in constant time
import math
def f( N, Sw, Sh ) :
cols = math.sqrt( float(N) * float(Sh) / float(Sw) )
cols = round(cols)
rows = float(N) / float(cols)
rows = math.ceil(rows)
return (int(cols),int(rows))
受 Will 的回答启发的另一个实现(2008-12-08 更新)——这是我最终使用的
# Another implementation inspired by Will's answer
# implemented in python 2.6
# reasonable output - a bit better in yielding more squarelike grids
# works in time proportional to number of rects
#
# strategy used it to try incrementaly adding a rect.
# if the resulting rect requires more space then two
# possibilities are checked - adding a new row or adding a new col
# the one with the best aspect ratio (1:1) will be chosen
def g( N, Sw, Sh ) :
slope = float(Sh)/float(Sw)
cols = 1
rows = 1
for i in xrange( N ) :
num_to_fit =i+1
allocated_cells= cols* rows
if ( num_to_fit <= allocated_cells ) :
pass # do nothing
else :
hc,wc = float(Sh * rows), float(Sw * (cols+1))
hr,wr = float(Sh * (rows+1)), float(Sw * cols)
thetac = math.atan( hc/wc)
thetar = math.atan( hr/wr)
alpha = math.pi/4.0
difr = abs(alpha-thetar)
difc = abs(alpha-thetac)
if ( difr < difc ) :
rows = rows +1
else:
cols = cols + 1
return (cols,rows)