Do you have a test-code to check the "quality" of a solution?
But sorting according to a weighting function gives similar results like shown by you.
DB<171> %h=( A => 4, B => 2, C => 3, D => 1 ) => ("A", 4, "B", 2, "C", 3, "D", 1) DB<172> $sum=0; $sum+=$_ for values %h; => "" DB<173> @list=map { my ($k,$v)=($_,$h{$_}); my $int=$sum/$v; map { + [ $k => $int*($_-.5)] } 1..$v } keys %h => ( ["A", "1.25"], ["A", "3.75"], ["A", "6.25"], ["A", "8.75"], ["D", 5], ["C", "1.66666666666667"], ["C", 5], ["C", "8.33333333333333"], ["B", "2.5"], ["B", "7.5"], ) DB<174> map {$_->[0]} sort { $a->[1] <=> $b->[1] or $a->[0] cmp $b-> +[0]} @list => ("A", "C", "B", "A", "C", "D", "A", "B", "C", "A")
Changing the weighting function would also allow to repeat the pattern in a way that joined sequences are still equally distributed ( that is A doesn't neighbor A )
An iterator-version shouldn't be too difficult.
Cheers Rolf
( addicted to the Perl Programming Language)
code simplified
well after second thought it's quite easy to find input where this approach fails ... never mind! :(
In reply to Re: Bag uniform distribution algorithms
by LanX
in thread Bag uniform distribution algorithms
by davido
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |