[Numpy-discussion] Extracting all the possible combinations of a grid
Charles R Harris
charlesr.harris@gmail....
Fri Sep 21 19:40:52 CDT 2007
On 9/21/07, Gael Varoquaux <gael.varoquaux@normalesup.org> wrote:
>
> On Fri, Sep 21, 2007 at 02:58:43PM -0600, Charles R Harris wrote:
> > I found generators a good approach to this sort of thing:
>
> > for (i,j,k) in triplets(n) :
>
> That's what we where doing so far, but in the code itself. The result was
> unbearably slow.
> I think for our purposes we should build a precalculated table of these
> nuplets, and then do array calculations on them.
>
> I was just wondering what the good way to build this table was. And I
> immediately thought of using tricks on arrays without realizing the speed
> at which the combination diverged.
>
> In the worst case, a set of nested for loops in a weave.inline wrapped C
> code populating an array of (n**d/n!, d) size would do the trick and be
> real fast. Something like (implemented in C, rather than Python):
>
> index = 0
> for i in xrange(n):
> for j in xrange(i):
> for k in xrange(j):
> index += 1
> out_array(index, 0) = i
> out_array(index, 1) = j
> out_array(index, 2) = k
>
> This would scale pretty well IMHO.
Try
def triplet(n) :
out = []
for i in xrange(2,n) :
for j in xrange(1,i) :
for k in xrange(0,j) :
out.append((i,j,k))
return out
It's the first algorithm in Knuth, mentioned in passing.
In [7]: time a = triplet(100)
CPU times: user 0.14 s, sys: 0.01 s, total: 0.14 s
Wall time: 0.15
Which isn't too bad for 161700 combinations. However, I still prefer the
generator form if you want to save memory for large n.
In [2]: def triplet(n) :
...: for i in xrange(2,n) :
...: for j in xrange(1,i) :
...: for k in xrange(1,j) :
...: yield i,j,k
...:
It's a bit slower for making lists, however.
In [24]: time for i,j,k in triplet(100) : a.append((i,j,k))
CPU times: user 0.24 s, sys: 0.01 s, total: 0.25 s
Wall time: 0.25
The more general algorithm L isn't too bad either
In [29]: def combination(n,t) :
....: c = arange(t + 2)
....: c[-1] = 0
....: c[-2] = n
....: while 1 :
....: yield c[:t]
....: j = 0
....: while c[j] + 1 == c[j+1] :
....: c[j] = j
....: j += 1
....: if j >= t :
....: return
....: c[j] += 1
In [30]: for i in combination(5,3) : print i
....:
[0 1 2]
[0 1 3]
[0 2 3]
[1 2 3]
[0 1 4]
[0 2 4]
[1 2 4]
[0 3 4]
[1 3 4]
[2 3 4]
In [31]: time for i in combination(100,3) : pass
CPU times: user 0.58 s, sys: 0.02 s, total: 0.60 s
Wall time: 0.60
Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20070921/d7da87f7/attachment.html
More information about the Numpy-discussion
mailing list