Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need an algorithm to split a series of numbers

After a few busy nights my head isn't working so well, but this needs to be fixed yesterday, so I'm asking the more refreshed community of SO.

I've got a series of numbers. For example:

1, 5, 7, 13, 3, 3, 4, 1, 8, 6, 6, 6

I need to split this series into three parts so the sum of the numbers in all parts is as close as possible. The order of the numbers needs to be maintained, so the first part must consist of the first X numbers, the second - of the next Y numbers, and the third - of whatever is left.

What would be the algorithm to do this?

(Note: the actual problem is to arrange text paragraphs of differing heights into three columns. Paragraphs must maintain order (of course) and they may not be split in half. The columns should be as equal of height as possible.)

like image 285
Vilx- Avatar asked Oct 13 '11 08:10

Vilx-


People also ask

How do you divide a number into different parts?

Approach: There is always a way of splitting the number if X >= N. If the number is being split into exactly 'N' parts then every part will have the value X/N and the remaining X%N part can be distributed among any X%N numbers.

How do you divide a number into equal parts in C#?

Using this example: var amount = x; var maxPerGroup = y; var amountGroups = Ceiling(amount/maxPerGroup);


1 Answers

First, we'll need to define the goal better:

Suppose the partial sums are A1,A2,A3, We are trying to minimize |A-A1|+|A-A2|+|A-A3|. A is the average: A=(A1+A2+A3)/3.

Therefore, we are trying to minimize |A2+A3-2A1|+|A1+A3-2A2|+|A1+A2-2A3|.

Let S denote the sum (which is constant): S=A1+A2+A3, so A3=S-A1-A2.

We're trying to minimize:

|A2+S-A1-A2-2A1|+|A1+S-A1-A2-2A2|+|A1+A2-2S+2A1+2A2|=|S-3A1|+|S-3A2|+|3A1+SA2-2S|

Denoting this function as f, we can do two loops O(n^2) and keep track of the minimum:

Something like:

for (x=1; x<items; x++)
{
    A1= sum(Item[0]..Item[x-1])
    for (y=x; y<items; y++)
    {
        A2= sum(Item[x]..Item[y-1])
        calc f, if new minimum found -keep x,y
    }
}
like image 59
Lior Kogan Avatar answered Oct 21 '22 04:10

Lior Kogan