MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Combinatorical efficiency

  • To: mathgroup at smc.vnet.net
  • Subject: [mg40471] Re: [mg40457] Re: [mg40433] Combinatorical efficiency
  • From: Rob Pratt <rpratt at email.unc.edu>
  • Date: Mon, 7 Apr 2003 04:54:07 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

On Sun, 6 Apr 2003, Rob Pratt wrote:

> On Sat, 5 Apr 2003, Gareth J. Russell wrote:
>
> > Hi,
> >
> > I am looking for an efficient (read fast) way to generate the set of all
> > combinations of na elements drawn with replacement from a set of nr
> > distinct elements. The number of these, of course is
> >
> > In[53]:=
> > numcombs[na_,nr_]:=((nr+1)+na-1)!/(na!*((nr+1)-1)!)
> >
> > In[106]:=
> > numcombs[3,4]
> >
> > Out[106]=
> > 35
> >
> > Just for illustration, here's a super-inefficient example that generates
> > all subsets of the right size, then pares them down to just the unique
> > combinations. I'm assuming that the set of elements is {0,1,2,...,nr-1},
> > and using the KSubsets function from the Combinatorica package.
> >
> > In[111]:=
> > tcombs[na_,nr_]:=KSubsets[Flatten[Table[Range[0,nr],{na}]],na]
> >
> > In[112]:=
> > temp1=tcombs[3,4];
> > temp2=Union[Map[Sort[#]&,temp1]]
> > Length[temp2]
> >
> > Out[113]=
> > {{0,0,0},{0,0,1},{0,0,2},{0,0,3},{0,0,4},{0,1,1},{0,1,2},{0,1,3},{
> >   0,1,4},{0,2,2},{0,2,3},{0,2,4},{0,3,3},{0,3,4},{0,4,4},{1,1,1},{
> >   1,1,2},{1,1,3},{1,1,4},{1,2,2},{1,2,3},{1,2,4},{1,3,3},{1,3,4},{
> >   1,4,4},{2,2,2},{2,2,3},{2,2,4},{2,3,3},{2,3,4},{2,4,4},{3,3,3},{
> >   3,3,4},{3,4,4},{4,4,4}}
> >
> > Out[114]=
> > 35
> >
> > This gets highly unwieldy as na and nr increase. Any suggestions?
> >
> > Thanks in advance,
> >
> > Gareth Russell
> > Columbia University
>
>
> You seem to have confused nr and nr + 1.

And I seem to have confused na and nr.

> The correct formula should be
> numcombs[na_,nr_]:=(nr+na-1)!/(na!*(nr-1)!)

Correct.

> which is just Binomial[nr + na - 1, nr].

Incorrect.  It's Binomial[nr + na - 1, na].

> (Among nr + na - 1 slots for nr dots and na - 1 dividers, choose where
> the nr dots go.)  For your example, take na = 3 and nr = 5 (your five
> distinct elements are {0, 1, 2, 3, 4}), yielding Binomial[7, 3] = 35.

Let me instead call the parameters n and k.  We want to choose k elements,
with repetition, from among n elements.  The resulting unordered k-tuples
are called multisets, and the number of k-multisets of an n-set is
sometimes called "n multichoose k" to generalize the phrase "n choose k"
used for k-subsets of an n-set.  To count the k-multisets of an n-set,
imagine a row of k dots and n - 1 dividers.  The number of dots preceding
the first divider is the number of 1's in the multiset.  For i = 2 to n - 1,
the number of dots between dividers i - 1 and i is the number of i's in
the k-multiset.  The number of dots after the last divider is the number
of n's in the multiset.  For example, with n = 5 and k = 7,

. . | . | . . . | | .  represents  {1, 1, 2, 3, 3, 3, 5}.

This correspondence gives a bijection between k-multisets of an n-set and
permutations of k dots and n - 1 dividers.  There are

(k + n - 1)! / (k! (n - 1)!) = Binomial[n + k - 1, k]

such permutations.  Now take k = na and n = nr.  The code below is still
correct for na = 3 and nr = 5, where your base set is {0, 1, 2, 3, 4}.

> Here's a more efficient way of getting the 35 triples:
>
> Flatten[Table[{x1,x2,x3},{x1,0,4},{x2,x1,4},{x3,x2,4}],2]


Rob Pratt
Department of Operations Research
The University of North Carolina at Chapel Hill

rpratt at email.unc.edu

http://www.unc.edu/~rpratt/



  • Prev by Date: Controlling order of evaluation - SelectionEvaluate
  • Next by Date: Re: Need a nice way to do this
  • Previous by thread: Re: Re: Combinatorical efficiency
  • Next by thread: Re: Re: Combinatorical efficiency