mostvisited has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: partition of an array
by BrowserUk (Patriarch) on Mar 09, 2009 at 06:31 UTC | |
You could try something like this:
It could be coded more efficiently
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
by Limbic~Region (Chancellor) on Mar 09, 2009 at 19:06 UTC | |
I really like this approach, but it is flawed. Consider the input: There are 13 items so we will have one partition of 6 and one of 7. your code produces the following solution: The first partition sums to 7 and the second to -9 with a difference of 16. You could move (not swap) the 6 in the first partion to the second partition and you would end up with: The first partition now sums to 1 and the second to -3 for a difference of 4. I don't know the difficulty in accounting for this situation but the problem is assuming the only balancing operation is swapping. Cheers - L~R | [reply] [d/l] [select] |
by BrowserUk (Patriarch) on Mar 09, 2009 at 19:34 UTC | |
Thanks for the edge case. A couple of possible fixes spring to mind: Things to play with. Thanks. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
by Limbic~Region (Chancellor) on Mar 09, 2009 at 19:55 UTC | |
by Limbic~Region (Chancellor) on Mar 09, 2009 at 20:09 UTC | |
by rir (Vicar) on Apr 22, 2009 at 04:19 UTC | |
Today, it just struck me that you don't have to keep the halves abs( @left - @right) <= 1 as you create them; just make sure there is enough remaining to fill the other half. Be well, rir | [reply] [d/l] [select] |
by BrowserUk (Patriarch) on Apr 23, 2009 at 03:30 UTC | |
Sticking to positive integers certainly seems to make things easier. Maybe I should have applied that same caveat to mine as a defense against Limbic~Region's detective work :) Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
by rir (Vicar) on Apr 23, 2009 at 20:25 UTC | |
|
Re: partition of an array
by ELISHEVA (Prior) on Mar 09, 2009 at 06:24 UTC | |
On the matter of dividing up items so that the difference in sum is minimized, you might be interested in this thread Average Price Algorithm. It discusses averages rather than sums and allows for an arbitrary number of buckets, instead of just 2. However, some of the issues will be the same since an average is just a sum divided by the number of elements. There were several suggestions on that thread ranging choosing the best from a random selection of solutions to various techniques for using deviation from the mean. Using deviations from the mean lets one take advantage of the fact that anything that pushes bucket's sum up so that its average is above the average for all elements, must, if possible, be complemented by something below the average for all elements. If you read through the thread discussing that solution and study the counter examples, you will see that its success is sensitive to relative factorizations, but that issue should be easily resolvable for the special case of two buckets. On the matter of dividing the number of elements into two groups as evenly as possible, you will have to take into account that odd numbers can't be divided evenly by two. There are two ways to deal with this in Perl: one using integers and one using floating point: Option 1: use floating point division and strip away fractional portion using int:
Option 2: Use the mod operator % (see perlop) to determine whether the size of the array is odd or even. $n%2 returns the remainder of division by 2.
Best, beth | [reply] [d/l] [select] |
|
Re: partition of an array
by irah (Pilgrim) on Mar 09, 2009 at 05:16 UTC | |
Sample program as follow
| [reply] [d/l] |
by mostvisited (Initiate) on Mar 09, 2009 at 05:50 UTC | |
| [reply] |
|
Re: partition of an array
by f00li5h (Chaplain) on Mar 09, 2009 at 06:16 UTC | |
sort it and stuff the biggest one into each half...
Output
this puts undefs in if there is an uneven number of elements (as this code shows) @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print; | [reply] [d/l] [select] |
by Corion (Patriarch) on Mar 09, 2009 at 14:08 UTC | |
This approach is suboptimal for the following sample case:
In this example, the greedy approach will fail, producing
while the best solution would be
But due to the homeworky nature of the problem I won't go into this further :) | [reply] [d/l] [select] |
by f00li5h (Chaplain) on Mar 25, 2009 at 06:44 UTC | |
Does not. Output:
You dropped the sort bit! ... some time passes ... Just snagging the biggest one and stuffing it in a sack works pretty well for the knapsack problem... and since this one was only 2 partitions it didn't do too bad ;) @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print; | [reply] [d/l] [select] |
|
Re: partition of an array
by locked_user sundialsvc4 (Abbot) on Mar 09, 2009 at 14:01 UTC | |
I am not directly acquainted with this problem, but it appears to me that the constraint, “such that |i-j| is 0 or 1,” is merely a formal way of saying, “in half.” Off the top of my head, I think that I can assert that there is only one point in any list where such a constraint would be true in a list with an even number of elements, and only two such points with an odd number. Therefore, “how is the ‘minimize’ constraint to be satisfied?” It would seem obvious to me that you must alter the order of the elements of the list in some way... a task that could be equally described in terms of “two separate lists.” With such a definition, one might solve the problem by sorting the master-list, then distributing the numbers taken from both the head and the tail of that sorted master-list into the two buckets. But, again referring to my previous post, I would first “study the literature” to find where someone else has effectively solved the problem for you already. “Heck, it's got to be in CPAN somewhere...” | |
by ikegami (Patriarch) on Mar 09, 2009 at 19:20 UTC | |
Even without ordering, that's not true.
| [reply] [d/l] |
|
Re: partition of an array
by targetsmart (Curate) on Mar 09, 2009 at 05:03 UTC | |
Vivek -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet. | [reply] |
by mostvisited (Initiate) on Mar 09, 2009 at 05:11 UTC | |
| [reply] |
|
Re: partition of an array
by locked_user sundialsvc4 (Abbot) on Mar 09, 2009 at 13:53 UTC | |
Can a really great book really be published by Springer-Verlag? Yes! ... if you can find it anymore. How To Solve It, by Zbignie Michalewicz. A recent re-publication (co-authored by David B. Fogel) is more readily available, ISBN 978-3540224945. This is a particularly-readable example of a concentrated book of heuristics. (Not just “algorithms,” and there is a difference.) It shows you how to approach many practical problems whose solutions are not immediately obvious. | |
by rir (Vicar) on Mar 17, 2009 at 12:54 UTC | |
I'm way behind on the state of ebooks; I'm off to DjVu.org to investigate djvu readers.
Be well, | [reply] |
|
Re: partition of an array
by rir (Vicar) on Mar 17, 2009 at 02:20 UTC | |
It doesn't seem that anyone has provided a correct solution. I believe this is one.
Be well,
Read more... (5 kB) | [reply] [d/l] |