Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: algorithm question

Author: Dann Corbit

Date: 12:26:06 02/27/06

Go up one level in this thread


On February 27, 2006 at 13:36:52, Gerd Isenberg wrote:

>Hi,
>
>while i indulge my current morbus knuth attack, which hits me so one, two times
>a year, i like to ask a question related to the "rotated" De Bruijn generator.
>
>I have a word "d" with a setwise interpretation ( a bitboard) and maximum
>cardinality of N (N bits set, let say 8). I like to enumerate all subsets,
>including the empty set and the original complete set. Looking for a smarter
>algorithm.
>
>What i actually do is to isolate all bits and store them in an array:
>
>Bitboard d = ..., t, bit[N];
>// d is the set i like traverse all subsets
>
>for (int n=0, t=d; t; n++) {
> assert(n<N);
> bit[n] = t & -t; // lsb
> t &= t-1;  // reset lsb
>}
>
>Now i loop over all 2**n (1<<n) possible combinations and synthesize the
>subsets inside an inner loop.
>
>for (int i=0; i < 1<<n; i++) {
>  // and build subset(i) with a loop
>  // combining all saved bits according to the
>  // the bits set in i
>  for (ont j=0, t=0; j < n; j++) {
>    if ( i & (1<<j) ) t |= bit[j];
>  }
>
>  // here t is one subset if d
>  ...
>}
>
>I guess there is a much smarter approach - without storing the isolated bits as
>atomic subsets - and doing a loop to synthesize the subsets.
>Hints and suggestions appreciated.

Here is a Fortran subset algorithm by Nijenhuis and Wilf:

c-----------------------------------------------------------
c Chapter 1: Next subset of an n-set(p19)
c-----------------------------------------------------------
c     Name of Subroutine: NEXSUB
c
c     Algorithm:Generating all of the subsets of the set
c               {1,2,...,n} in an order specified by the
c               gray code
c
c     input:    n=5
c     compiler: f77 nexsub_2.f
c-----------------------------------------------------------
c Use of nexsub
      logical mtc
      dimension in(5)
      n=5
      mtc=.false.
   10 call nexsub(n,in,mtc,ncard,j)
      print 20,(in(i),i=1,n)
   20 format(1x ,5(i2,1x))
      if(mtc) goto 10
      stop
      end

c-----Subroutine begins here--------------------------------
      subroutine nexsub(n,in,mtc,ncard,j)
      logical mtc
      dimension in(n)
      if(mtc)goto 20
      do 11 i=1,n
   11 in(i)=0
      ncard=0
      mtc=.true.
      return
   20 j=1
      if(mod(ncard,2).eq.0)goto 30
   40 j=j+1
      if(in(j-1).eq.0)goto 40
c if(j.gt.n)j=n
   30 in(j)=1-in(j)
      ncard=ncard+2*in(j)-1
      mtc=ncard.ne.in(n)
      return
      end

Crude modification of f2c output of the combination subroutine part (less the
driver):

/* -----Subroutine begins here-------------------------------- */
int nexsub(int * n, int * in, logical * mtc, int *ncard, int * j)
{
    /* System generated locals */
    int         i1;

    /* Local variables */
    static int  i;

    /* Parameter adjustments */
    --in;

    /* Function Body */
    if (*mtc) {
        goto L20;
    }
    i1 = *n;
    for (i = 1; i <= i1; ++i) {
        in[i] = 0;
    }
    *ncard = 0;
    *mtc = TRUE;
    return 0;
L20:
    *j = 1;
    if (*ncard % 2 == 0) {
        goto L30;
    }
L40:
    ++(*j);
    if (in[*j - 1] == 0) {
        goto L40;
    }
/* if(j.gt.n)j=n */
L30:
    in[*j] = 1 - in[*j];
    *ncard = *ncard + (in[*j] << 1) - 1;
    *mtc = *ncard != in[*n];
    return 0;
}

It could easily be made structured.  Also, some of the pass by pointer calls
could easily be made pass by value.  I would also make the static permuation
holder a parameter.




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.