Thanks to hdb, RichardK & pme.
Based on ideas from your code I've derived two routines:
but except for the first and last, it extends the random adjustment to rand( $step * 2 ) - $step, which allows for occasional overlaps (out of order points):
sub rndPart1{ ## can overlap my( $start, $end, $count ) = @_; my $step = ( $end - $start ) / $count; $start += $step / 2; map{ my $mid = $start + $step*$_; my $v = $mid + ( ( $_ == 0 || $_ == ( $count - 1 ) ) ? ( rand( $step ) - $step/2 ) : ( rand( $step * 2 ) - $step ) ); sprintf "%5.2f", $v; } 0 .. $count-1; }
Some samples:
That is, for args ( 1, 4, 3 ), the first pick is 1.5 ± 0.5 as normal, but if that pick is (say) 1.1, then instead of the second pick being 2.5 ± 0.5 it becomes 2.5 + (-1.4 .. +0.5); and if that picked (say) 1.2, then the third pick will be 3.5 + (-2.3 .. +0.5 ).
The probability of extreme skewness decreases exponentially. The input parameters here are (1,100,10), and the count is the number of tries before the highest value falls below 90% (80%,70%...):
E:\Chart>rndChart -L=90 3.19 7.43 15.68 19.31 47.80 48.67 50.26 68.37 68.46 82.69 after 2 tr +ies E:\Chart>rndChart -L=80 7.50 16.23 18.26 31.39 50.49 57.02 57.21 66.03 69.93 72.89 after 3 tr +ies E:\Chart>rndChart -L=70 10.10 17.22 17.46 37.29 39.13 58.73 60.07 62.71 65.91 68.60 after 43 t +ries E:\Chart>rndChart -L=60 9.50 18.43 19.91 24.09 47.55 48.76 49.03 53.83 54.86 57.29 after 67 t +ries E:\Chart>rndChart -L=50 4.88 19.23 29.45 39.03 40.90 42.33 43.60 43.81 45.65 49.11 after 3253 + tries E:\Chart>rndChart -L=40 5.10 12.01 14.57 14.75 20.23 21.83 27.22 31.43 31.72 39.10 after 1000 +17 tries E:\Chart>rndChart -L=30 10.16 12.98 15.25 15.67 17.10 17.89 21.85 23.07 28.24 28.28 after 2980 +335 tries E:\Chart>rndChart -L=20 Terminating on signal SIGINT(2)
It currently only does negative skewness. (If anyone can see a way to also produce positive skews with a similarly exponential rareness, I'd love to hear of it?)
The code>:
sub rndPart2{ ## strictly ascending, skew possible my( $start, $end, $count ) = @_; my $step = ( $end - $start ) / $count; my $last = $start; $start += $step / 2; map{ sprintf "%5.2f", $last = $last + ( rand( $_ + $step/2 - $last +) ); } map{ $start + $step*$_ } 0 .. $count-1; }
Some samples:
In reply to Re: Random partitions? (Thanks and solution.)
by BrowserUk
in thread Random partitions?
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |