2011-03-02 58 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