In article <e2**********************************@w7g2000hsa.g ooglegroups.com>
>The only way I am aware of is to build 'n' for(;;) statements, one
inside the other ... One key issue is that each chromossome member
has different max-elements ...
chromossome[0] may have max_value_for_each_chromossome[0] = 5
(chromossome[0] int will range from 0 to 4)
chromossome[1] may have max_value_for_each_chromossome[1] = 2
(chromossome[1] int will range from 0 to 1)
...
As others have said, it is not entirely clear what you are really
trying to achieve here.
My best guess at what you actually want is what I like to call an
"odometer algorithm".
In an odometer, there are a series of wheels that count up from 0
to 9, and when one wheel clicks from 9 to 0, the "next-one-over"
wheel counts up. We can do this trivially for a fixed number of
digits (say, 3) that count 0-to-9 with:
for (a[0] = 0; a[0] < 10; a[0]++) {
for (a[1] = 0; a[1] < 10; a[1]++) {
for (a[2] = 0; a[2] < 10; a[2]++) {
... now the three digits are in a[0] a[1] a[2] ...
}
}
}
So far, everything is pretty obvious, but what if we want our
"odometer" to read, e.g.:
000, 001, 002,
010, 011, 012,
020, 021, 022,
030, 031, 032,
040, 041, 042,
100, 101, 102,
110, 111, 112,
...
940, 941, 942
That is, the last digit only counts 0..2 and the middle digit only
counts 0..5? Well, again, this is pretty obvious:
for (a[0] = 0; a[0] < 10; a[0]++) {
for (a[1] = 0; a[1] < 5; a[1]++) {
for (a[2] = 0; a[2] < 3; a[2]++) {
... now the three digits are in a[0] a[1] a[2] ...
}
}
}
What if the odometer does not have exactly *three* digits, but
rather some variable number of digits? (Let us call this n and
assume it is no more than MAX_N.)
Here is where we take advantage of the fact that the outermost loop
runs over a[0], the next loop runs over a[1], the next over a[2],
and so on. Then we simply start by zeroing-out the entire odometer
(let me write this as a general-purpose function):
/* we will see what these are for in a moment */
#define NO_OVERFLOW 0
#define OVERFLOW 1
void odo_init(int *odo, int n_digits) {
int i;
for (i = 0; i < n_digits; i++)
odo[i] = 0;
}
and then run a loop that repeats until our odometer "overflows"
(back to all-zeros if it is a traditional car-odometer):
int a[MAX_N];
... find n ...
assert(n <= MAX_N);
odo_init(a);
do {
... work with odometer in a ...
} while (odo_increment(a, n) == NO_OVERFLOW);
Now we need only write the "increment" function. If the odometer
were a traditional car odometer, with all the digits running from
0 to 9 inclusive, this would look like:
/*
* Increment an odometer by "clicking the digits". Return
* OVERFLOW if the odometer overflows, or NO_OVERFLOW if not.
*/
int odo_increment(int *odo, int n_digits) {
int i;
/*
* Click the right-most (least-significant) digit first,
* and stop (and return NO_OVERFLOW) as soon as we can
* increment a digit without having to reset it to 0.
* If we have to reset the digit to 0, do that and continue
* the loop to increment the next-more-significant digit.
*/
for (i = n_digits - 1; i >= 0; i--) {
if (odo[i] < 9) {
odo[i]++;
return NO_OVERFLOW;
}
odo[i] = 0;
}
/* If we got here, we cranked everything all the way to 0 again. */
return OVERFLOW;
}
It should be pretty obvious how to modify odo_increment() to take
a second array of "range for each odometer digit" -- which can of
course vary per "digit" -- instead of just assuming [0..9].
It should be equally obvious how to rearrange the "odometer digits"
if "rightmost-counts-fastest" is not what is desired. The key work
all happens in the odo_increment() function.
(Note that there are other ways to solve this problem. For the
most trivial cases -- an odometer that reads 000 to 999 for instance
-- we can just do:
for (i = 0; i < 1000; i++) {
a[0] = i / 100;
a[1] = (i / 10) % 10;
a[2] = (i / 100) % 10;
... a[] holds the three digits ...
}
and we can usually eliminate the array "a" entirely. But calling
it an "odometer" makes things much clearer, I think.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out)
http://web.torek.net/torek/index.html