2011-03-02 62 views
4

我有一个不同尺寸的矩形列表。计算表格布局的最佳列数 - 只给出表格宽度和矩形列表

rects = [100x20, 30x10, 10x10, 70x20, 40x30, 50x10]

我试图从这些矩形渲染的表。如果我会列一个固定数,我根本就计算行数和每行和每列的这样的尺寸:

numCols = 4; 

for (i = 0; i < rects.size - 1, i++): 
    rect = rects[i]; 
    col = i % numCols; 
    row = floor(i/numCols); 

    columns[col] = max(columns[col], rect.width); 
    rows[row] = max(rows[row], rect.height); 
end for; 

现在,我想我的表,由最大行宽进行配置。列数取决于最佳行宽的运行时间计算。

通过上面的列表和最高一行设置为140我希望我的表是:

rects = [100x20, 30x10, 70x10, 10x20, 40x30, 10x10] 

100x20, 30x10 
70x10, 10x20 
40x30, 10x10 

cols = [100, 30] 
rows = [20, 20, 30] 

我的第一个接近情况的想法是缓存最大列宽柱的侧向承载力每个可能的数字。最后一个条目的总和为< =最大行宽,然后获胜。

max[1] = [100] 
max[2] = [100, 30] - wins 
max[3] = [100, 40, 70] - 210 > 140 
max[4] = [100, 30, 70, 10] 
max[5] = [100, 30, 70, 10, 40] 
max[6] = [100, 30, 70, 10, 40, 10] 

不幸的是,我需要为每个可能的列号创建一个最大条目。名单可以变得相当大。有人知道一个算法来解决这个优化问题吗?

+0

也许你可以添加一些关于你的算法应该解决的问题的更多细节。你想要优化什么(行数,表格高度)?例如。你的方法给出max [2] = [100,10],而你的例子是[100,30]。你为什么喜欢第一个?在你的例子中,你永远不会改变矩形的顺序。这是一个要求吗?此外,标题中提到“尺寸均匀”,但您从未在描述中提到过这一点。如果我们更了解目标,我想我们可以找到一个(已知的)算法。 – Howard 2011-03-02 18:15:36

+0

最大阵列的“相当大”有多大?这似乎是一个明智的做法,贪婪地采取最宽的矩形,然后从左边开始放在列中(最宽的矩形必须去某处,并且尽可能多地使用它下面的空间)。您不必存储max数组,只是最好的数组,并且对于给定数量的列计算行宽是微不足道的(如果您按照宽度递减的顺序对矩形进行排序,这是一个快速循环,加)。如果我正确地理解了这个问题,我会将其转到答案。 – 2011-03-02 20:13:05

+0

@霍华德,你最好[2] = [100,30]。我已经更新了这个例子。 – 2011-03-02 21:28:37

回答

1

我只能看到优化您的解决方案:

假设:
MaxAllowedWidth - 最大允许所有列的总和宽度

  1. 在寻找可能的解决方案(您的最后一个表)停止尝试当总列宽将超过MaxAllowedWidth时,添加新列。在你的示例中,你应该停止第三步,不要尝试4,5,6列,因为3列已经占用了更多的空间。请注意,在这一步我们只考虑第一行的项目。

  2. 在前面的步骤中以相反的顺序浏览可能的列号。首先适用的解决方案将是最佳的,因为它将具有尽可能少的行数。

  3. 在步骤2中,您应该检查这个列数是否真的适合您的MaxAllowedWidth。在您的示例中,您将从总宽度= 130(100 + 30)开始。然后检查这些列,你应该检查这个特定的列是否应该放大。如果需要放大列,请检查放大的列是否会占用比您离开时更多的空间。如果它会尝试少列的解决方案。此检查将允许您更早退出并跳过无用的迭代/操作。

问题描述不是很清楚,我没有得到你想要的东西,直到我阅读评论。 max row width对我来说没有意义,total columns width听起来更好,IMO。

+0

Spasibo Snowbear!可能的列数可以这样排列:添加最宽的项目直到达到MaxAllowedWidth,可以得到最少的列数。然后采用最宽的项目并添加最低项目直到达到MaxAllowedWidth,可以获得最大列数。给出宽度为1,...,100和MaxAllowedWidth为300的混洗列表,可能的列数范围从4到20,而3(100 + 99 + 98 <300)将适合。 – 2011-03-03 15:43:23

+0

我认为你甚至不需要考虑“最小”列数。因为在这个任务中可能会出现一些列不适合的情况,但是放入**更多列会有帮助。该示例是rects:[1,1,100,1,1,100],其中'maxAllowedWidth = 150'。在这种情况下,2列不适合,因为他们都应该有'100'宽度,但三列将适合,因为两个最大的项目将进入同一列。所以我认为你不必担心最少的列数。 – Snowbear 2011-03-03 15:58:18

+0

如果没有其他可能性令人满意,最小数字是断点。 – 2011-03-03 16:57:53