As a simplification, I would suggest enfiling the array rather than
converting indices:
({~ 11 ? #) ,arr

The way to go is still deal, though.

Marshall

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Alexander Mikhailov
Sent: Saturday, September 18, 2010 3:23 AM
To: [email protected]
Subject: [Jprogramming] subsequent draws from arrays


Hi,

a few times already I've had a task of modeling several subsequent random
selections from an array. I thought this is a rather common problem, but
couldn't find it in Puzzles of Phrases. I've decided to try it myself; then
the forum will definitely give good suggestions.

So, suppose we have an array of integers of some shape 

shp =. 5 6 7

(the values are unimportant) and we want to randomly extract a few

num =. 11

items from different places in the array. We may generate 11 numbers from 0
to 5*6*7 (not including the last, 210th)

idxs =. ?. num $ */ shp

but then we'll need to make sure we don't have repetitions and add more
numbers until all 11 are unique. Then the indices may be translated into
coordinates in the array by

shp #: idxs

We can try to (re)invent a non-repeating algorithm. Note that if we at first
draw, say, 5th item - and remove it from initial array - its place will be
taken by 6th item, so if second time we again draw 5th item, it's going to
be the 6th element in the original array. So, if we imagine a sequence of
draws -

4 6 5 10

taken in the order from right to left (i.e., first we take - and remove -
10th item from original array, then 5th item of remaining array, then 6th
item of remaining array, then 4th of remaining), the items in the original
array actually take places

4 7 5 10

because when we took 6th item, all items after 5 got their positions
decremented (and all after 10 decremented twice), so item on the 6th place
was actually item from 7th place in the original array.

After each draw the length of array decrements, so if first draw selects
from */ 5 6 7 possible choices, the second one selects from <: */ 5 6 7
choices, the third one - from <: <: */ 5 6 7 etc. To draw 11 times, we
randomly choose numbers from shrinking sets:

   ]idx =. ?. (i. num) + num -~ */ shp
61 155 161 80 184 27 75 79 175 2 16

Now for each number we need to find how many numbers to the right of it are
smaller or equal to this number. It can be found using prefixes and suffixes

   ]dlt =. (}:@(<@{:\)   (>@[ +/@:>: >@])"0 0   <\...@}.) idx
3 6 6 5 6 2 2 2 2 0

Now we're adding this index corrections ("deltas") to the idx array and
obtain final unique indexes in the original array

   idx + dlt
64 161 167 85 190 29 77 81 177 2 16

Now, question to the forum. How this problem should be solved? What better
solutions are there?

Thanks,

Alex



      
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to