SUBROUTINE slCMBN ( NSEL, NCAND, LIST, J ) *+ * - - - - - - * C O M B N * - - - - - - * * Generate the next combination, a subset of a specified size chosen * from a specified number of items. * * Given: * NSEL i number of items (subset size) * NCAND i number of candidates (set size) * * Given and returned: * LIST i(NSEL) latest combination, LIST(1)=0 to initialize * * Returned: * J i status: -1 = illegal NSEL or NCAND * 0 = OK * +1 = no more combinations available * * Notes: * * 1) NSEL and NCAND must both be at least 1, and NSEL must be less * than or equal to NCAND. * * 2) This routine returns, in the LIST array, a subset of NSEL integers * chosen from the range 1 to NCAND inclusive, in ascending order. * Before calling the routine for the first time, the caller must set * the first element of the LIST array to zero (any value less than 1 * will do) to cause initialization. * * 2) The first combination to be generated is: * * LIST(1)=1, LIST(2)=2, ..., LIST(NSEL)=NSEL * * This is also the combination returned for the "finished" (J=1) * case. * * The final permutation to be generated is: * * LIST(1)=NCAND, LIST(2)=NCAND-1, ..., LIST(NSEL)=NCAND-NSEL+1 * * 3) If the "finished" (J=1) status is ignored, the routine * continues to deliver combinations, the pattern repeating * every NCAND!/(NSEL!*(NCAND-NSEL)!) calls. * * 4) The algorithm is by R.F.Warren-Smith (private communication). * * P.T.Wallace Starlink 25 August 1999 * * Copyright (C) 1999 Rutherford Appleton Laboratory * * License: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see SLA_CONDITIONS); if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * * Copyright (C) 1995 Association of Universities for Research in Astronomy Inc. *- IMPLICIT NONE INTEGER NSEL,NCAND,LIST(NSEL),J INTEGER I,LISTI,NMAX,M LOGICAL MORE * Validate, and set status. IF (NSEL.LT.1.OR.NCAND.LT.1.OR.NSEL.GT.NCAND) THEN J = -1 GO TO 9999 ELSE J = 0 END IF * Just starting? IF (LIST(1).LT.1) THEN * Yes: return 1,2,3... DO I=1,NSEL LIST(I) = I END DO ELSE * No: find the first selection that we can increment. * Start with the first list item. I = 1 * Loop. MORE = .TRUE. DO WHILE (MORE) * Current list item. LISTI = LIST(I) * Is this the final list item? IF (I.GE.NSEL) THEN * Yes: comparison value is number of candidates plus one. NMAX = NCAND+1 ELSE * No: comparison value is next list item. NMAX = LIST(I+1) END IF * Can the current item be incremented? IF (NMAX-LISTI.GT.1) THEN * Yes: increment it. LIST(I) = LISTI+1 * Reinitialize the preceding items. DO M=1,I-1 LIST(M) = M END DO * Break. MORE = .FALSE. ELSE * Can't increment the current item: is it the final one? IF (I.GE.NSEL) THEN * Yes: set the status. J = 1 * Restart the sequence. DO I=1,NSEL LIST(I) = I END DO * Break. MORE = .FALSE. ELSE * No: next list item. I = I+1 END IF END IF END DO END IF 9999 CONTINUE END