Allan Bruce wrote:

> I have a program which I need to be able to produce all the possible states

> from a given set of variables. This requires me to have a variable number

> of nested loops, depending on how many derivativest the user specifies.

> What is the best way to do this? I was considering limiting the number of

> derivatives and using if statements but this is quite messy. Am I

> describing my problem clear enough? If not then look below for an example

> problem.

>

> A state in my system holds the current values of my world variables. Each

> variable has a number of derivatives specified by the user, and each

> derivative has a number of possible values specified by the user. For

> example, one simple problem is this:

>

> 3 variables: V, qi, qo

> V has 3 derivatives, and qi/qo both have only 2

> the first derivative of each variable can have 9 possible values, and the

> rest of the derivatives can have 5

>

> For this system there are 9x5x5 possible values for V (=225)

> there are 9x5 possible values for qo (=45)

> there are 9x5 possible values for qi (=45)

>

> therefore there are 225x45x45 possible states in the system (=455625)

>

> Can anybody shed some light as to how I would approach this problem?
Use one loop, plus an array of "index values" that keep

track of where you are. Here's a tiny example that counts

from 0:00 to 2:59, using a different array element for each

of the three digits:

int[] digit = { 0, 0, 0}; // units, tens, sixties

final int[] limit = { 10, 6, 3 };

for (;

{

do_your_thing(digit);

int i;

for (i = 0; i < digit.length; ++i) {

digit[i] += 1;

if (digit[i] < limit[i])

break;

digit[i] = 0;

}

if (i == digit.length)

break; // finished the cycle

}

In your case you'd probably want to use each `digit[i]' as

the index into an array of variable or derivative values,

and the `limit[i]' would be the length of the corresponding

array. This sort of adaptation should be straightforward.

Another approach is to do an ordinary count from zero to

455624 (in your example), and then derive the digits with

division and remainder:

final int[] steps = { 225, 45, 45 };

long limit = 1;

for (int i = 0; i < steps.length; ++i)

limit *= steps[i];

int[] digit = new int[ steps.length ];

for (long index = 0; index < limit; ++index) {

long temp = index;

for (int i = 0; i < steps.length; ++i) {

digit[i] = temp % steps[i];

temp /= steps[i];

}

do_your_thing(digit);

}

What you're really trying to do here is count in a mixed-

radix number system. See D.E. Knuth "The Art of Computer

Programming, Volume II: Seminumerical Algorithms" for fancier

manipulations than these. (When Volume 4 comes out -- some

pre-print proofs are on his Web site -- it'll probably show

some even slicker ways of doing this sort of thing.)

--

http://www.velocityreviews.com/forums/(E-Mail Removed)