3

What is the algorithm that implements CSS's multi-column layout with balanced fill?

Mathematical formulation: given a list of positive numbers (those would be the heights of the items to arrange), distribute them in order into N lists such that the difference between the list with the largest sum and the list with the smallest sum is the minimum of all possible arrangements.

  • By "distribute them in order" you mean that the order remains fixed? – TamaMcGlinn Oct 25 '18 at 14:40
  • @TamaMcGlinn yes, you can't scramble the text :) –  Oct 25 '18 at 14:43
  • What can be the possible limit on the length of the list and N? – Nilesh Oct 25 '18 at 14:45
  • So, convert the list to a cumulative one, then divide the last element by N to obtain IdealColumnSize. return the closest element to elementIndex * IdealColumnSize for elementIndex ranging from 1 to N-1. I.e. for N = 2 this is one element, the closest to the half-value. – TamaMcGlinn Oct 25 '18 at 14:45
  • @nellex why does it matter? Both can be infinite. – TamaMcGlinn Oct 25 '18 at 14:46
  • Please provide an example. Or a link to one. – Jim Mischel Oct 25 '18 at 14:46
  • @JimMischel look at the big table of libraries on http://luapower.com -- items have variable height due to headers and occasional wrapping yet they are almost perfectly distributed across 7 columns. –  Oct 25 '18 at 14:49
  • @TamaMcGlinn I'm not sure but I think it's a global optimization problem because the element that you choose as your cutting point affects the height of all subsequent columns and thus the `max_sum - min_sum` quantity. –  Oct 25 '18 at 14:52
  • This looks to me like a variation of this problem: https://stackoverflow.com/questions/14120729/algorithm-to-split-an-array-into-p-subarrays-of-balanced-sum – Jim Mischel Oct 25 '18 at 14:52
  • @JimMischel thanks, looks like exactly the same problem, differently formulated. –  Oct 25 '18 at 14:55

1 Answers1

1

First convert the list to a cumulative one, then divide the last element by N to obtain IdealColumnSize:

For example:

2, 3, 6, 8, 3, 4, 2

Yields the cumulative list:

2, 5, 11, 19, 22, 26, 28

Say we want to divide it into 3. IdealColumnSize is 9 1/3. Now for indexes 1 to N-1, select the closest element in the cumulative list.

The closest to 9 1/3 is 11, so the first three numbers go in column 1.

The closest to 18 2/3 is 19, so one number goes into column 2.

The remaining items go in the last column.

TamaMcGlinn
  • 2,840
  • 23
  • 34
  • 1
    Very clever, it's like computing the absolute height of each item and the absolute height of each column in an imaginary 1-column layout and comparing them so that the errors don't accumulate –  Oct 25 '18 at 15:37
  • I don't understand why people say that the problem is NP-complete in the other question (https://stackoverflow.com/questions/14120729/algorithm-to-split-an-array-into-p-subarrays-of-balanced-sum). Thoughs? –  Oct 25 '18 at 15:40
  • @capr If you can rearrange the items to be able to find a better arrangement, then you can get better answers. But there are a lot of rearrangements, and no good way to find the absolute best. If you can't rearrange elements, then you only need to think about where to break the existing list. – btilly Oct 25 '18 at 16:01
  • 1
    Consider this: 15,1,10,1,1,1,1. The number of columns is 3. The "divide and take the nearest" would give {15}, {1}, and {10,1,1,1,1}, which obviously does not not give "difference between the list with the largest sum and the list with the smallest sum is the minimum of all possible arrangements" (15-1=14). The {15}, {1,10}, and {1,1,1,1} gives better result (15-4=11). – Mike Kaganski May 17 '21 at 09:25