1 | #include "slalib.h"
|
---|
2 | #include "slamac.h"
|
---|
3 | void slaCombn ( int nsel, int ncand, int list[], int* j )
|
---|
4 | /*
|
---|
5 | ** - - - - - - - - -
|
---|
6 | ** s l a C o m b n
|
---|
7 | ** - - - - - - - - -
|
---|
8 | **
|
---|
9 | ** Generate the next combination, a subset of a specified size chosen
|
---|
10 | ** from a specified number of items.
|
---|
11 | **
|
---|
12 | ** Given:
|
---|
13 | ** nsel int number of items (subset size)
|
---|
14 | ** ncand int number of candidates (set size)
|
---|
15 | **
|
---|
16 | ** Given and Returned:
|
---|
17 | ** list int[nsel] latest combination, list[0]=0 to initialize
|
---|
18 | **
|
---|
19 | ** Returned:
|
---|
20 | ** *j int status: -1 = illegal nsel or ncand
|
---|
21 | ** 0 = OK
|
---|
22 | ** +1 = no more combinations available
|
---|
23 | **
|
---|
24 | ** Notes:
|
---|
25 | **
|
---|
26 | ** 1) nsel and ncand must both be at least 1, and nsel must be less
|
---|
27 | ** than or equal to ncand.
|
---|
28 | **
|
---|
29 | ** 2) This routine returns, in the list array, a subset of nsel integers
|
---|
30 | ** chosen from the range 1 to ncand inclusive, in ascending order.
|
---|
31 | ** Before calling the routine for the first time, the caller must set
|
---|
32 | ** the first element of the list array to zero (any value less than 1
|
---|
33 | ** will do) to cause initialization.
|
---|
34 | **
|
---|
35 | ** 2) The first combination to be generated is:
|
---|
36 | **
|
---|
37 | ** list[0]=1, list[1]=2, ..., list[nsel-1]=nsel
|
---|
38 | **
|
---|
39 | ** This is also the combination returned for the "finished" (j=1)
|
---|
40 | ** case.
|
---|
41 | **
|
---|
42 | ** The final permutation to be generated is:
|
---|
43 | **
|
---|
44 | ** list[0]=ncand, list[1]=ncand-1, ..., list[nsel-1]=ncand-nsel+1
|
---|
45 | **
|
---|
46 | ** 3) If the "finished" (j=1) status is ignored, the routine
|
---|
47 | ** continues to deliver combinations, the pattern repeating
|
---|
48 | ** every ncand!/(nsel!*(ncand-nsel)!) calls.
|
---|
49 | **
|
---|
50 | ** 4) The algorithm is by R.F.Warren-Smith (private communication).
|
---|
51 | **
|
---|
52 | ** Last revision: 25 August 1999
|
---|
53 | **
|
---|
54 | ** Copyright P.T.Wallace. All rights reserved.
|
---|
55 | */
|
---|
56 | {
|
---|
57 | int i, more, nmax, m;
|
---|
58 |
|
---|
59 |
|
---|
60 | /* Validate, and set status. */
|
---|
61 | if ( nsel < 1 || ncand < 1 || nsel > ncand ) {
|
---|
62 | *j = -1;
|
---|
63 | return;
|
---|
64 | } else {
|
---|
65 | *j = 0;
|
---|
66 | }
|
---|
67 |
|
---|
68 | /* Just starting? */
|
---|
69 | if ( list[0] < 1 ) {
|
---|
70 |
|
---|
71 | /* Yes: return 1,2,3... */
|
---|
72 | for ( i = 0; i < nsel; i++ ) {
|
---|
73 | list[i] = i+1;
|
---|
74 | }
|
---|
75 |
|
---|
76 | } else {
|
---|
77 |
|
---|
78 | /* No: find the first selection that we can increment. */
|
---|
79 |
|
---|
80 | /* Start with the first list item. */
|
---|
81 | i = 0;
|
---|
82 |
|
---|
83 | /* Loop. */
|
---|
84 | more = 1;
|
---|
85 | while ( more ) {
|
---|
86 |
|
---|
87 | /* Is this the final list item? */
|
---|
88 | if ( i == nsel-1 ) {
|
---|
89 |
|
---|
90 | /* Yes: comparison value is number of candidates plus one. */
|
---|
91 | nmax = ncand+1;
|
---|
92 |
|
---|
93 | } else {
|
---|
94 |
|
---|
95 | /* No: comparison value is next list item. */
|
---|
96 | nmax = list[i+1];
|
---|
97 | }
|
---|
98 |
|
---|
99 | /* Can the current item be incremented? */
|
---|
100 | if ( nmax - list[i] > 1 ) {
|
---|
101 |
|
---|
102 | /* Yes: increment it. */
|
---|
103 | list[i]++;
|
---|
104 |
|
---|
105 | /* Reinitialize the preceding items. */
|
---|
106 | for ( m = 0; m < i; m++ ) {
|
---|
107 | list[m] = m+1;
|
---|
108 | }
|
---|
109 |
|
---|
110 | /* Quit the loop. */
|
---|
111 | more = 0;
|
---|
112 |
|
---|
113 | } else {
|
---|
114 |
|
---|
115 | /* Can't increment the current item: is it the final one? */
|
---|
116 | if ( i == nsel-1 ) {
|
---|
117 |
|
---|
118 | /* Yes: set the status. */
|
---|
119 | *j = 1;
|
---|
120 |
|
---|
121 | /* Restart the sequence. */
|
---|
122 | for ( i = 0; i < nsel; i++ ) {
|
---|
123 | list[i] = i+1;
|
---|
124 | }
|
---|
125 |
|
---|
126 | /* Quit the loop. */
|
---|
127 | more = 0;
|
---|
128 |
|
---|
129 | } else {
|
---|
130 |
|
---|
131 | /* No: next list item. */
|
---|
132 | i++;
|
---|
133 | }
|
---|
134 | }
|
---|
135 | }
|
---|
136 | }
|
---|
137 | }
|
---|