/* zeta-orbits.c ** ** Frank Sottile 18 March 1998 ** ** This file finds all irreducible, full-support permutations in the ** symmetric group, up to the equivalence generated by cyclic shift, ** taking inverse, and conjugaton by the longest element. ** ** It first finds representatives of this equivalence relation, but ** does not check for reducibility. In this first part, it steps through ** the symmetric group of order n in lexicographic order, beginning with the ** least derangement. Then, if a permutation zeta satisfies ** 1) zeta is a derangement, (fixpoint) ** 2) k := #{ a | a 315324768332 ** */ #include #include #include #define n 7 /* The index of the symmetric group */ #define PermSize n+2 /* length of the permutation data */ #define Numks 1+n/2 /* number of possible k's */ #define Nranks 2+n*n/4-n /* range of ranks */ int nextperm(int pi[PermSize]); /* finds the lexocographically next permutation, and returns the last ascent. */ int fixpoint(int pi[PermSize]); /* checks for derangement. */ int kbig(int pi[PermSize]); /* checks if k> n/2. */ int length(int pi[PermSize]); /* computes the length of zeta. */ int make_orbit(int zeta[PermSize], int orbit[2*n+1][n+1]); /* Creates the equivalence orbit */ int Pfrequency(int frequency[Numks][Nranks]); /* Prints out a table of frequencies */ int make_cycle(int pi[PermSize], int cycle[1+n+n/2]); /* parses a permutation into cycles */ int Pcycle(int pi[PermSize], int cycle[1+n+n/2]); /* Prints a permutation in cycle notation */ int check_irred(int cycle[1+n+n/2]); /* checks if irreducible */ int zeta[PermSize]; main() { int i,ii, j,jj, asc, k, l, Ntest, in_there; int orbit[2*n+1][n+1], cycle[1+n+n/2], pi[PermSize], perms[Numks][Nranks][60][n+1], frequency[Numks][Nranks], final_count[Numks][Nranks]; /* Initialize frequency */ for ( k=1; k <= n/2; ++k) for ( l=0; l <= Nranks-1; ++l){ frequency[k][l]=0; final_count[k][l]=0; } /* Initialize the permutation */ zeta[n]=n; for ( i=1; i <= n/2; ++i) { zeta[2*i-1]=2*i; zeta[2*i]=2*i-1; } asc=1; while(asc>0){ if ( fixpoint(zeta) && kbig(zeta) && length(zeta)){ make_orbit(zeta,orbit); k=zeta[0]; l=zeta[n+1]+1-n; Ntest=frequency[k][l]; in_there=0; if(Ntest>0){ jj=Ntest-1; while( !in_there && (jj< 2*n*Ntest)){ ii= (jj%(Ntest)) +1; j = 1+ jj/Ntest; in_there = (perms[k][l][ii][1]==orbit[j][1]); i=2; while (in_there&& i<=n){ in_there = in_there && (perms[k][l][ii][i]==orbit[j][i]); ++i; } ++jj; } if (2*zeta[0]==n){ for (i=1; i<=n; ++i) pi[zeta[i]]=i; make_orbit(pi,orbit); k=zeta[0]; l=zeta[n+1]+1-n; Ntest=frequency[k][l]; jj=0; while( !in_there && (jj< 2*n*Ntest)){ ii= (jj%(Ntest)) +1; j = 1+ jj/Ntest; in_there = (perms[k][l][ii][1]==orbit[j][1]); i=2; while (in_there&& i<=n){ in_there = in_there && (perms[k][l][ii][i]==orbit[j][i]); ++i; } ++jj; } } } if (!in_there) { frequency[k][l]=frequency[k][l]+1; for ( i=1; i <= n; ++i) perms[k][l][frequency[k][l]][i]=zeta[i]; } } asc=nextperm(zeta); /* if (asc==1) { Pfrequency(frequency); printf(" asc=1 zeta="); for (i=1; i<=n; ++i) printf("%d",zeta[i]); printf("\n"); }*/ } /* Print frequency table*/ Pfrequency(frequency); for (k=1; k<=n/2; ++k){ for (l=0; l<=Nranks-1; ++l){ for (ii=1; ii<=frequency[k][l]; ++ii){ for (i=1; i<=n; ++i) zeta[i]=perms[k][l][ii][i]; make_cycle(zeta,cycle); if ((cycle[0]==1) || (check_irred(cycle))) final_count[k][l]=final_count[k][l]+1; } } } /* Print final frequency table*/ Pfrequency(final_count); printf(" %d\n",clock()); } /*check_irred ** checks if the permutation is irreducible */ int check_irred(int cycle[1+n+n/2]) { int a, b, btest, i,ii, j, jj, crossing, place, Nmove, not_done; int Blocks[1+n+n/2], temp[1+n+n/2]; not_done=1; for (i=0; i<= n+n/2; ++i) Blocks[i]=cycle[i]; btest=2; place=Blocks[n+1]; while (not_done){ crossing=0; /* Checks to see if the first and btest-th block are crossing */ for (i=1; i < Blocks[n+1]; ++i){ for (j=i+1; j<=Blocks[n+1]; ++j){ a=(Blocks[i]+Blocks[j]- abs(Blocks[i]-Blocks[j])); b=(Blocks[i]+Blocks[j]+ abs(Blocks[i]-Blocks[j])); for (ii=place+1; ii2){ Nmove=0; for (j=2; jpi[b]){ rank = rank -1; if (pi[a]>pi[b]){ rank = rank + 1; } } } if ( a>pi[a] ) { if ( bpi[b] && pi[a]= n-1); } /*kbig(k,zeta) ** This checks to see if k<=n/2*/ int kbig(int pi[PermSize]) { int i,k; k=0; for ( i=1; i <= n; ++i) if ( i 0 ) { temp = pi[asc]; for ( i = asc+1; i <= n; ++i){ if ( pi[i] > temp ) bigger = i; } pi[asc]=pi[bigger]; pi[bigger]=temp; for ( i=1; i <= (n-asc)/2; ++i){ temp=pi[asc+i]; pi[asc+i]=pi[n+1-i]; pi[n+1-i]=temp; } } return asc; }