Given N, where N is an integer > 0, process the numbers 1-N in random order.
The best I can come up with is:
List = '' /* Generate a list */
Do I = 1 to N /* Of numbers from 1-N */
List = list I /* Add number to list */
End
Do while list <> '' /* Process list */
I = random(1,words(list)) /* Chose random number */
J = word(list,i) /* Get original number */
List = delword(list,I,1) /* Stop it being used again */
... Process item "J" /* Do something with item J */
End
This seems a lot of code for a relatively simple task. It also runs
inefficiently if N is large, because of the constant increasing in the
length of the variable "list" in the first loop.
How would you do it?
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Steve
|
12/11/2007 4:10:33 AM |
|
"Steve Swift" <Steve.J.Swift@gmail.com> wrote in message
news:475f5b84@news.greennet.net...
> Given N, where N is an integer > 0, process the numbers 1-N in random
> order.
>
> The best I can come up with is:
>
> List = '' /* Generate a list */
> Do I = 1 to N /* Of numbers from 1-N */
> List = list I /* Add number to list */
> End
> Do while list <> '' /* Process list */
> I = random(1,words(list)) /* Chose random number */
> J = word(list,i) /* Get original number */
> List = delword(list,I,1) /* Stop it being used again */
> ... Process item "J" /* Do something with item J */
> End
>
> This seems a lot of code for a relatively simple task. It also runs
> inefficiently if N is large, because of the constant increasing in the
> length of the variable "list" in the first loop.
>
> How would you do it?
>
> --
> Steve Swift
> http://www.swiftys.org.uk/swifty.html
> http://www.ringers.org.uk
I did similar a long time ago.... something like this.
/* */
max = 20 /* say */
random. = randomise(max)
::method randomise
use arg max
sequence = 0
random.0 = max
j = 0
do i = 1 to max
number = random(1, max)
if self~testForDups(number, sequence) = 0 then do
i = i-1
iterate
end
else do
sequence = sequence number
j = j+1
random.j = number
end
end
return random.
::method testForDups
use arg number, sequence
do until used = ''
parse var sequence used sequence
if number = used then return 0
end
return number
Phil
----
|
|
0
|
|
|
|
Reply
|
Phil
|
12/11/2007 5:16:28 AM
|
|
In Message-ID:<475f5b84@news.greennet.net>,
Steve Swift <Steve.J.Swift@gmail.com> wrote:
>Given N, where N is an integer > 0, process the numbers 1-N in random order.
<snip>
>How would you do it?
When in doubt, refer to Knuth's Seminumerical Algorithms.
Here's my code based on his shuffling algorith on P. 125:
<code>
max = 30
do i = 1 to max
nums.i = i
end
do i = max to 1 by -1
j = random(1,i)
/* swap nums.j and nums.i */
x = nums.i
nums.i = nums.j
nums.j = x
end
/* now use them */
do i = 1 to max
say right(i,2) ' ' right(nums.i,2)
end
</code>
The built-in RANDOM function requires that the range be no
greater than 100000 (Regina REXX on Windows). I tested with a
table of 100000, and my timing was:
Time to fill table was 4.750
Time to shuffle table was 18.578
With only 30000, timing was:
Time to fill table was 0.360
Time to shuffle table was 1.312
(Needless to say, when testing with large numbers, I didn't
use the SAY loop. I also added instructions to get the timings.)
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/11/2007 5:27:47 AM
|
|
Phil wrote:
> I did similar a long time ago.... something like this.
I've also used a similar mechanism to yours; picking numbers at random,
and ignoring them if I've used them before:
Max = 20
Seen. = 0
Do max
Do until \seen.N
N = random(1,max)
End
Seen.N = 1
Say N
End
The problem with this is the way it slows down as "Max" increases,
hunting for the last numbers.
I can see myself running a few benchmarks!
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Steve
|
12/11/2007 7:16:20 AM
|
|
In Message-ID:<475f5b84@news.greennet.net>,
Steve Swift <Steve.J.Swift@gmail.com> wrote:
>Given N, where N is an integer > 0, process the numbers 1-N in random order.
>
>The best I can come up with is:
<snip>
>How would you do it?
Here's an improvement over my previous code, followed by
timings:
<code>
/*REXX exec */
arg max
if \ datatype(max,"N") then max = 1000
t0 = time('r')
do i = max to 1 by -1
if \ datatype(nums.i,'N') then nums.i = i
j = random(1,i)
if datatype(nums.j,'N') then
do
x = nums.i
nums.i = nums.j
nums.j = x
end
else
do
nums.j = nums.i
nums.i = j
end
end
t1 = time('r')
say 'Time to shuffle table was' format(t1,,3)
do i = 1 to max
x = nums.i
end
t2 = time('r')
say 'Time to use the table was' format(t2,,3)
say 'Total time was' format(t1+t2,,3)
exit 0
</code>
On my system, here are timings:
MAX Yours Mine
1000 .047 .000
5000 1.328 .047
10000 5.547 .188
30000 66.891 1.625
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/11/2007 4:01:23 PM
|
|
| Arthur T. wrote:
|> Steve Swift wrote:
|> Given N, where N is an integer > 0, process the numbers 1-N in random order.
|>
|> The best I can come up with is:
<snip>
|> How would you do it?
| Here's an improvement over my previous code, followed by
| timings:
|
| <code>
| /*REXX exec */
|
| arg max
| if \ datatype(max,"N") then max = 1000
| t0 = time('r')
|
| do i = max to 1 by -1
| if \ datatype(nums.i,'N') then nums.i = i
| j = random(1,i)
| if datatype(nums.j,'N') then
| do
| x = nums.i
| nums.i = nums.j
| nums.j = x
| end
| else
| do
| nums.j = nums.i
| nums.i = j
| end
|
| end
| t1 = time('r')
| say 'Time to shuffle table was' format(t1,,3)
|
| do i = 1 to max
| x = nums.i
| end
| t2 = time('r')
| say 'Time to use the table was' format(t2,,3)
|
| say 'Total time was' format(t1+t2,,3)
|
| exit 0
|
| </code>
|
| On my system, here are timings:
| MAX Yours Mine
| 1000 .047 .000
| 5000 1.328 .047
| 10000 5.547 .188
| 30000 66.891 1.625
I tweaked the code a bit and got about a 10% improvement
in execution speed:
================================================================
/*REXX exec*/ arg max .; if \datatype(max,'N') then max=1000
call time 'R'
nums.=-1
do i=max to 1 by -1
if nums.i<0 then nums.i=i
j=random(1,i)
if nums.j>=0 then parse value nums.i nums.j with nums.j nums.i
else parse value nums.j nums.i with nums.i j
end
t1=time('r')
say 'Time to shuffle table was' format(t1,,3)
do i=1 to max
x=nums.i
end
t2=time('r')
say 'Time to use the table was' format(t2,,3)
say 'Total time was' format(t1+t2,,3)
================================================================
_______________________________________________________Gerard S.
|
|
0
|
|
|
|
Reply
|
Gerard
|
12/11/2007 4:44:55 PM
|
|
In Message-ID:<475ebdc4$1@news.702com.net>,
"Gerard Schildberger" <Gerard46@rrt.net> wrote (and I greatly
snipped):
>I tweaked the code a bit and got about a 10% improvement
>in execution speed:
>
>nums.=-1
Checking a variable for a value is probably much more
efficient than my checking for numeric.
> if nums.j>=0 then parse value nums.i nums.j with nums.j nums.i
> else parse value nums.j nums.i with nums.i j
It's not often I spot a mistake in your code. That 2nd line
should be
else parse value j nums.i with nums.i nums.j
(Spaces left in to highlight the changes.)
And that harkens back to an old thread (here or elsewhere) on
the best way to swap the values of two variables.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/11/2007 5:04:24 PM
|
|
| Arthur T. wrote:
|> Gerard Schildberger wrote: (and I greatly snipped):
|> I tweaked the code a bit and got about a 10% improvement
|> in execution speed:
|>
|> nums.=-1
| Checking a variable for a value is probably much more
| efficient than my checking for numeric.
|> if nums.j>=0 then parse value nums.i nums.j with nums.j nums.i
|> else parse value nums.j nums.i with nums.i j
| It's not often I spot a mistake in your code. That 2nd line
| should be
| else parse value j nums.i with nums.i nums.j
| (Spaces left in to highlight the changes.)
Yuppers, my bad; I was in too much of a hurry to go and eat
breakfast. Eat first, then code. _________________Gerard S.
| And that harkens back to an old thread (here or elsewhere) on
| the best way to swap the values of two variables.
|
|
0
|
|
|
|
Reply
|
Gerard
|
12/11/2007 6:13:42 PM
|
|
In Message-ID:<475ed293$1@news.702com.net>,
"Gerard Schildberger" <Gerard46@rrt.net> wrote:
> I was in too much of a hurry to go and eat
>breakfast. Eat first, then code.
Always good advice. Either of two bad things can happen when
you reverse that order:
1. You think about food instead of code, and you make mistakes.
2. You *don't* think about food. You get immersed in coding.
Several hours later you notice that you're famished. You have
barely the energy to get to the kitchen, at which point you eat
anything which takes zero preparation time.
Er, um, theoretically, that is. Not that I'd know about it,
myself.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/11/2007 7:05:25 PM
|
|
On Dec 11, 4:27 pm, Arthur T. <art...@munged.invalid> wrote:
> In Message-ID:<475f5...@news.greennet.net>,
>
>
>
> Steve Swift <Steve.J.Sw...@gmail.com> wrote:
> >Given N, where N is an integer > 0, process the numbers 1-N in random order.
> <snip>
> >How would you do it?
>
> When in doubt, refer to Knuth's Seminumerical Algorithms.
> Here's my code based on his shuffling algorith on P. 125:
>
> <code>
> max = 30
>
> do i = 1 to max
> nums.i = i
> end
>
> do i = max to 1 by -1
> j = random(1,i)
>
> /* swap nums.j and nums.i */
> x = nums.i
> nums.i = nums.j
> nums.j = x
>
> end
>
> /* now use them */
> do i = 1 to max
> say right(i,2) ' ' right(nums.i,2)
> end
> </code>
>
> The built-in RANDOM function requires that the range be no
> greater than 100000 (Regina REXX on Windows). I tested with a
> table of 100000, and my timing was:
> Time to fill table was 4.750
> Time to shuffle table was 18.578
>
> With only 30000, timing was:
> Time to fill table was 0.360
> Time to shuffle table was 1.312
>
> (Needless to say, when testing with large numbers, I didn't
> use the SAY loop. I also added instructions to get the timings.)
>
> --
> Arthur T. - ar23hur "at" intergate "dot" com
> Looking for a z/OS (IBM mainframe) systems programmer position
That's a gem of an algorithm.
I thought Steve had a good one too, but this is far better of course.
Interesting how Steve had a hunch that there may be a better way...
a minor note: there is no real need for a separate loop to process the
random numbers (the 'now use them' loop), because all that is required
is a random processing of all numbers (so the random number at max may
be processed first, and so on...)
and re your later comment about swapping 2 variables p, q, you may be
aware that REXX provides another good way: q= value("p", q)
Regards
HS
|
|
0
|
|
|
|
Reply
|
hs
|
12/14/2007 11:39:09 AM
|
|
Steve Swift wrote:
> Given N, where N is an integer > 0, process the numbers 1-N in random
> order.
Thanks for all the replies here. I decided to write a benchmark between
Arthur's code and my code. I knew that my code was doomed as "max"
increases; the effect of continually lengthening a variable. However,
there was no value of max where my code won. The extreme case occurred
when I accidentally changed "max" to 10000. My code took 342 seconds
(125 iterations) and Arthur's 11 seconds (125 iterations)
I'm so pleased with the outcome that I'm going to add a new function to
my subroutine library which returns a list of numbers from 1 to max in
random order. The hard part comes last: finding a good name for such a
function. :-)
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Steve
|
12/14/2007 2:21:39 PM
|
|
In <4763df39@news.greennet.net>, on 12/14/2007
at 02:21 PM, Steve Swift <Steve.J.Swift@gmail.com> said:
>I'm so pleased with the outcome that I'm going to add a new function to
>my subroutine library which returns a list of numbers from 1 to max in
>random order. The hard part comes last: finding a good name for such a
>function. :-)
APL has had this function since the beginning as the dyadic use of a ? as
a function. It is referred to as the "deal" function, I suspect because
one application would be in dealing a deck of cards.
-- Dave
-----------------------------------------------------------
dhdurgee<at>verizon<dot>net
-----------------------------------------------------------
|
|
0
|
|
|
|
Reply
|
me
|
12/14/2007 3:12:22 PM
|
|
In
Message-ID:<b060371d-d1db-4f4e-a731-18bd7a01266a@i12g2000prf.googlegroups.com>,
hs <hrmndrsingh@gmail.com> wrote:
>That's a gem of an algorithm.
I steal from the best. It's hard to better Knuth.
>a minor note: there is no real need for a separate loop to process the
>random numbers (the 'now use them' loop), because all that is required
>is a random processing of all numbers (so the random number at max may
>be processed first, and so on...)
Good point. So the timings would actually be better.
>and re your later comment about swapping 2 variables p, q, you may be
>aware that REXX provides another good way: q= value("p", q)
I don't remember that coming up in the thread. I've looked
it up, and I'll have to remember it. If I use it, I'll also want
to comment it, as it's not something I'd normally remember.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/14/2007 3:31:18 PM
|
|
In Message-ID:<4763df39@news.greennet.net>,
Steve Swift <Steve.J.Swift@gmail.com> wrote:
>I'm so pleased with the outcome that I'm going to add a new function to
>my subroutine library which returns a list of numbers from 1 to max in
>random order. The hard part comes last: finding a good name for such a
>function. :-)
How about "shuffle"?
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/14/2007 3:32:30 PM
|
|
My initial offering was limp...
I found long ago that stems and parse are both wonderful but slow.
I dabled with variations on my first go by holding the misses (duplicate
randoms) in an array but to cut to the chase there appears to be no better
way to get there than has already been posted here.
What I did though, is to substitute an array for the stem and eliminate the
parse in the process. Here it is with timings run on IBM Object Rexx 213.
Here are the 2 methods I used:
::method shuffle1 --mine
use arg max
array = .array~new(max)
do i = 1 to max
array[i] = i
end
do i = max to 2 by -1
j=random(1,i)
val1 = array[i]
val2 = array[j]
array[i] = val2
array[j] = val1
end
return array
::method shuffle2 --yours
use arg max
nums. = -1
do i = max to 1 by -1
if nums.i < 0 then nums.i=i
j=random(1,i)
if nums.j >= 0 then parse value nums.i nums.j with nums.j nums.i
else parse value j nums.i with nums.i nums.j
end
nums.0 = max
return nums.
And here are the times which include reading the results:
Max Yours Mine
1000 0.062 0.000
5000 0.188 0.062
10000 0.328 0.078
30000 0.687 0.313
50000 1.156 0.407
100000 2.579 0.641
Phil
----
"Gerard Schildberger" <Gerard46@rrt.net> wrote in message
news:475ebdc4$1@news.702com.net...
>| Arthur T. wrote:
> |> Steve Swift wrote:
> |> Given N, where N is an integer > 0, process the numbers 1-N in random
> order.
> |>
> |> The best I can come up with is:
> <snip>
> |> How would you do it?
>
> | Here's an improvement over my previous code, followed by
> | timings:
> |
> | <code>
> | /*REXX exec */
> |
> | arg max
> | if \ datatype(max,"N") then max = 1000
> | t0 = time('r')
> |
> | do i = max to 1 by -1
> | if \ datatype(nums.i,'N') then nums.i = i
> | j = random(1,i)
> | if datatype(nums.j,'N') then
> | do
> | x = nums.i
> | nums.i = nums.j
> | nums.j = x
> | end
> | else
> | do
> | nums.j = nums.i
> | nums.i = j
> | end
> |
> | end
> | t1 = time('r')
> | say 'Time to shuffle table was' format(t1,,3)
> |
> | do i = 1 to max
> | x = nums.i
> | end
> | t2 = time('r')
> | say 'Time to use the table was' format(t2,,3)
> |
> | say 'Total time was' format(t1+t2,,3)
> |
> | exit 0
> |
> | </code>
> |
> | On my system, here are timings:
> | MAX Yours Mine
> | 1000 .047 .000
> | 5000 1.328 .047
> | 10000 5.547 .188
> | 30000 66.891 1.625
>
>
>
> I tweaked the code a bit and got about a 10% improvement
> in execution speed:
>
> ================================================================
> /*REXX exec*/ arg max .; if \datatype(max,'N') then max=1000
> call time 'R'
> nums.=-1
>
> do i=max to 1 by -1
> if nums.i<0 then nums.i=i
> j=random(1,i)
> if nums.j>=0 then parse value nums.i nums.j with nums.j nums.i
> else parse value nums.j nums.i with nums.i j
> end
>
> t1=time('r')
> say 'Time to shuffle table was' format(t1,,3)
>
> do i=1 to max
> x=nums.i
> end
>
> t2=time('r')
> say 'Time to use the table was' format(t2,,3)
> say 'Total time was' format(t1+t2,,3)
> ================================================================
> _______________________________________________________Gerard S.
>
>
>
>
|
|
0
|
|
|
|
Reply
|
Phil
|
12/18/2007 2:17:44 PM
|
|
I made changes to:
1) Not include the value of index i in the random number search - this will
result in only replacing itself.
2) Stop half way on the assumption that if the top half of the array has
been toggled then the bottom half must also be done.
3) Reduce the reads of the array from 2 to 1
I may have some of this wrong and in any case the changes made little
difference to the timing.
Phil
----
::method shuffle1
use arg max
array = .array~new(max)
do i = 1 to max
array[i] = i
end
do i = max to max/2 by -1
j = random(1,i-1)
vali = array[i]
array[i] = array[j]
array[j] = vali
end
return array
|
|
0
|
|
|
|
Reply
|
Phil
|
12/18/2007 10:48:52 PM
|
|
In Message-ID:<47684e61$0$8430$afc38c87@news.optusnet.com.au>,
"Phil" <obrienpw@optusnet.com.au> wrote:
>I made changes to:
>1) Not include the value of index i in the random number search - this will
>result in only replacing itself.
Making it less random because it's impossible to have a
number in the top half which doesn't move.
>2) Stop half way on the assumption that if the top half of the array has
>been toggled then the bottom half must also be done.
Making it *much* less random by greatly increasing the chance
that a number in the bottom half won't move.
#1 seemed likely on inspection and was confirmed by printing
the tables. I expected some problem with #2 and printing the
output showed the above problem.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/18/2007 11:33:43 PM
|
|
Maybe #2 was not thought through... but why is #1 incorrect?
Is it not possible to be at index 10 and request a random number from 1-10
and end up swapping 10 with 10?
Phil
----
"Arthur T." <arthur@munged.invalid> wrote in message
news:sclgm393hhvu5knqq34gjr22287s9pedaa@4ax.com...
> In Message-ID:<47684e61$0$8430$afc38c87@news.optusnet.com.au>,
> "Phil" <obrienpw@optusnet.com.au> wrote:
>
>>I made changes to:
>>1) Not include the value of index i in the random number search - this
>>will
>>result in only replacing itself.
>
> Making it less random because it's impossible to have a
> number in the top half which doesn't move.
>
>>2) Stop half way on the assumption that if the top half of the array has
>>been toggled then the bottom half must also be done.
>
> Making it *much* less random by greatly increasing the chance
> that a number in the bottom half won't move.
>
> #1 seemed likely on inspection and was confirmed by printing
> the tables. I expected some problem with #2 and printing the
> output showed the above problem.
>
> --
> Arthur T. - ar23hur "at" intergate "dot" com
> Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Phil
|
12/18/2007 11:55:43 PM
|
|
Phil wrote:
> Is it not possible to be at index 10 and request a random number from 1-10
> and end up swapping 10 with 10?
Yes, it is--possible, and correct. The optimization you want is not to
remove i from the search, but just to skip the swap if j=i.
�R
|
|
0
|
|
|
|
Reply
|
Glenn
|
12/19/2007 12:07:17 AM
|
|
In Message-ID:<47685e04$0$5200$afc38c87@news.optusnet.com.au>,
"Phil" <obrienpw@optusnet.com.au> wrote:
>Maybe #2 was not thought through... but why is #1 incorrect?
>
>Is it not possible to be at index 10 and request a random number from 1-10
>and end up swapping 10 with 10?
Yes it should be. However, your change limited it to
swapping with a random number (actually a random location) from
1-9, not 1-10.
Or, are you suggesting that swapping 10 with 10 should never
happen? In that case, as I said, you'll *never* have location 10
have value 10. So, if you had to guess what number was in
location 10, you'd have an 11+% chance of being right instead of
only a 10% chance. Similarly, a game of War between an unshuffled
deck and one shuffled with your #1 would never have a War during
the first run-through.
You could check to see if you're swapping a location with
itself and do nothing. I suspect that it wouldn't speed things up
because you'd do the check many more times than you'd prevent a
"do nothing" swap.
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/19/2007 12:15:54 AM
|
|
Thanks, Glenn and Arthur... I see the light!
Give me this though... there is no need to do the last swap of location 1
with location 1 so I only need to count down to 2.
Times again:
Max Stem Array
1000 0.032 0.000
5000 0.186 0.032
10000 0.359 0.094
30000 0.641 0.281
50000 1.187 0.390
100000 2.626 0.782
Enjoyed the discussion... thanks Steve.
Phil
----
|
|
0
|
|
|
|
Reply
|
Phil
|
12/19/2007 1:13:54 AM
|
|
In Message-ID:<47687057$0$25392$afc38c87@news.optusnet.com.au>,
"Phil" <obrienpw@optusnet.com.au> wrote:
>Thanks, Glenn and Arthur... I see the light!
>
>Give me this though... there is no need to do the last swap of location 1
>with location 1 so I only need to count down to 2.
That sounds right. OTOH, anything dealing with random
numbers is as hard to get right as an encryption algorithm. Since
this algorithm comes from a trusted source (Knuth), I'd tend to
leave it matching his method as close as possible. After all,
it's only once through the loop.
>Times again:
>Max Stem Array
> 1000 0.032 0.000
> 5000 0.186 0.032
> 10000 0.359 0.094
> 30000 0.641 0.281
> 50000 1.187 0.390
>100000 2.626 0.782
Since I'm using a classic REXX rather than oo, I didn't have
the array option. But, this is good info for those that do run
oo, and for me when or if I go oo.
>Enjoyed the discussion... thanks Steve.
As I said, it's very easy to make mistakes with random
numbers. (I forget who said, "Random numbers are too important to
be left to chance.")
--
Arthur T. - ar23hur "at" intergate "dot" com
Looking for a z/OS (IBM mainframe) systems programmer position
|
|
0
|
|
|
|
Reply
|
Arthur
|
12/19/2007 2:44:07 AM
|
|
Glenn Knickerbocker wrote:
> Yes, it is--possible, and correct. The optimization you want is not to
> remove i from the search, but just to skip the swap if j=i.
I end up agonising whether the "if" statement will consume more CPU than
the redundant swap. http://www.swiftys.org.uk/wiz?267
--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
|
|
0
|
|
|
|
Reply
|
Steve
|
12/19/2007 11:40:49 AM
|
|
One approach, if you want 0..n-1 in some pseudorandom order, is to
find the smallest power of two bigger or equal to n (call it m),
initialize x to some seed, and do (sorry, C not REXX)
for (i=0; i<n; ++i) {
do {
y = x = (x + 0xdeadbeef) & (m-1);
y = (y + (y<<5)) & (m-1);
y = y ^ (y>>3);
} while (y >= n);
printf("%d", x);
}
That reports y=0..n-1 in some pseudorandom order then repeats.
Duplicating those two lines with shifts increases the
pseudorandomness, and the optimal shift amounts vary with m. Key to
this working is that those two shift lines are permutations of
0..m-1. Often the right thing to do is not have any shift lines at
all.
This approach doesn't require an array.
|
|
0
|
|
|
|
Reply
|
bob_jenkins
|
12/20/2007 9:25:41 PM
|
|
|
23 Replies
136 Views
(page loaded in 0.206 seconds)
Similiar Articles: Re: assign a unique random integer to each unique id - comp.soft ...My earlier array solution permutes the observation numbers in random order to get ... in the data set and note that the KEY is not used in the process. Let us use a number ... Random number in Fortran 90/95 - comp.lang.fortranWhen I got a seed, then I can call RANDOM_NUMBER in order to get a ... Generate Gaussian Process with a Specified Autocorrelation ... Random number in Fortran 90/95 - comp ... comp.soft-sys.matlab - page 271... Hi all, I have a load of files I'd like to read into MATLAB for processing. ... put numbers 1..100 in random order 3 3 (12/23/2003 8:57:11 PM) Dear all any quick-smart way for ... AR(1) model (autoregressive process) - comp.soft-sys.matlab ...There are a number of aspects you will need to sort ... the AR(p) model from the signal, given the order. ... an autoregressive (AR) model is a type of random process which ... AR coefficients for complex numbers - comp.dsp... for a complex series of numbers, similar to ... table 8.2 in Therrien: Discrete Random Signals and Statistical Signal Processing ... AIC to try and find out the optimal order ... reader writer semaphores - comp.unix.programmerIf a process is killed or dies in a critical section, a ... accumulate in the BerkeleyDB "directory," the number ... >> If OTOH, the kernel grants locks in random order, >> then my ... Process synchronization for implementing a global lock - comp.unix ...In the backend, you must lock ... such an analysis in order to implement ... in your ... generator (seed) for each image, or a synchronization process for ... random number ... Determine number of open files and/or open file locks - comp.sys ...Alexander Skwar -- Actually, typing random strings in ... what is available (itrc.hp.com) is probably in order. ... You have to increase the per-process number of open files in ... Random access to content of archived files without extraction ...... compress in a single pass; it's inportant in order to ... A parameter of the process is how far apart the index ... Pseudo Random Number ... starting tutorial with source code ... autocorrelation command xcorr - comp.soft-sys.matlab... to specifically use the xcorr function but in order ... 1; > > >> samples=fs*window_d; %Number of samples per ... Fourier transform of a random process - comp.dsp process time ... Combinations in a binary matrix - comp.soft-sys.matlab... 1 1; 1 1 1] > > the rows might be in any order. ... generate each row on the fly in a loop as you process it. ... How to generate vector of random numbers in any interval (e.g ... Where is the flaw in my thinking? - comp.compressionMy thought process goes something like ... ... is i.i.d. uniformly >> distributed zero-order ... then used a PRNG to generate a number between 0 ... that have random and ... Drawing series of circles - comp.soft-sys.matlabSo total number of random normal distributed values > is 33 x ... together with the formula for the mean in order to ... each other in gui???? - comp.soft-sys ... ... process ... Image processing ,Image segmentation - comp.soft-sys.matlab ...Hi ..Actlly my intrest in image processing has ... hsv', 'k', 'shuffle'); % pseudo random color labels If so, the number of ... we need to seperate it out ,in order to ... 64 bit integer - comp.lang.c++.moderated... doesn't support a 32 bit integral type, in order to ... 64-bit Random Number Generator - comp.lang.c++.moderated ... ... Can we get 64 bit process' memory info with application ... Random Number GeneratorRandom numbers are sets of digits (i.e., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) arranged in random order. ... A random number generator is a process that ... Randomness - Wikipedia, the free encyclopediaA random process is a sequence of random variables describing a ... Basketball Association uses a weighted lottery to order teams in its draft. Mathematical: Random numbers are ... 7/14/2012 3:07:50 AM
|