Thanks for the help.

let me define the problem in greater detail. I am dealing with four

parameters. Each parameter has a rate associated with it. Rates may

be shared across parameters, or each parameter may have a unique rate,

or some parameters may share some rates. Each unique pattern of rates

across the parameters defines a model.

So, if there are two rates, all four parameters have to take either

state 1 or state 2. However, 1112 is the same as 2221 because it

means the first three parameters have one rate and the fourth

parameter has a second rate.

Right now I use some incredibly redundant code to look at every

possiblity that I can think of and then store only the unique patterns

(see code below for 6 parameter case). However this seems like some

variant of an n choose k sort of problem, and I am interested in

eventually scaling up from four parameters (and four rates) to k

parameters and 1 to k rates, and doing it in a more elegant way.

Thanks for any help!

Michael

(E-Mail Removed)
void EnumerateAllModels (void)

{

int whichCase, i, j, i1, i2, i3, i4, i5, i6, params[6], checked[6],

num, tempParams[6], tempParams2[6];

numModels = 0;

for (i=0; i<6; i++)

numOfNst[i] = 0;

for (whichCase=0; whichCase<=10; whichCase++)

{

if (whichCase == 0)

{

params[0] = 0;

params[1] = 0;

params[2] = 0;

params[3] = 0;

params[4] = 0;

params[5] = 0;

}

else if (whichCase == 1)

{

params[0] = 0;

params[1] = 1;

params[2] = 1;

params[3] = 1;

params[4] = 1;

params[5] = 1;

}

else if (whichCase == 2)

{

params[0] = 0;

params[1] = 0;

params[2] = 1;

params[3] = 1;

params[4] = 1;

params[5] = 1;

}

else if (whichCase == 3)

{

params[0] = 0;

params[1] = 0;

params[2] = 0;

params[3] = 1;

params[4] = 1;

params[5] = 1;

}

else if (whichCase == 4)

{

params[0] = 0;

params[1] = 1;

params[2] = 2;

params[3] = 2;

params[4] = 2;

params[5] = 2;

}

else if (whichCase == 5)

{

params[0] = 0;

params[1] = 1;

params[2] = 1;

params[3] = 2;

params[4] = 2;

params[5] = 2;

}

else if (whichCase == 6)

{

params[0] = 0;

params[1] = 0;

params[2] = 1;

params[3] = 1;

params[4] = 2;

params[5] = 2;

}

else if (whichCase == 7)

{

params[0] = 0;

params[1] = 1;

params[2] = 2;

params[3] = 3;

params[4] = 3;

params[5] = 3;

}

else if (whichCase ==

{

params[0] = 0;

params[1] = 1;

params[2] = 2;

params[3] = 2;

params[4] = 3;

params[5] = 3;

}

else if (whichCase == 9)

{

params[0] = 0;

params[1] = 1;

params[2] = 2;

params[3] = 3;

params[4] = 4;

params[5] = 4;

}

else if (whichCase == 10)

{

params[0] = 0;

params[1] = 1;

params[2] = 2;

params[3] = 3;

params[4] = 4;

params[5] = 5;

}

for (i1=0; i1<6; i1++)

{

for (i2=0; i2<6; i2++)

{

if (i2 == i1)

continue;

for (i3=0; i3<6; i3++)

{

if (i3 == i1 || i3 == i2)

continue;

for (i4=0; i4<6; i4++)

{

if (i4 == i1 || i4 == i2 || i4 == i3)

continue;

for (i5=0; i5<6; i5++)

{

if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4)

continue;

for (i6=0; i6<6; i6++)

{

if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5)

continue;

tempParams[0] = params[i1];

tempParams[1] = params[i2];

tempParams[2] = params[i3];

tempParams[3] = params[i4];

tempParams[4] = params[i5];

tempParams[5] = params[i6];

for (i=0; i<6; i++)

checked[i] = 0;

num = 0;

for (i=0; i<6; i++)

{

if (checked[i] == 1)

continue;

tempParams2[i] = ++num;

for (j=i+1; j<6; j++)

{

if (checked[j] == 0 && tempParams[i] == tempParams[j])

{

tempParams2[j] = num;

checked[j] = 1;

}

}

}

if (HasModelBeenFound(tempParams2) == NO)

{

models[numModels].index = numModels;

for (i=0; i<6; i++)

models[numModels].rateParams[i] = tempParams2[i];

num = 0;

for (i=1; i<=6; i++)

{

for (j=0; j<6; j++)

if (models[numModels].rateParams[j] == i)

{

num++;

break;

}

}

models[numModels].nst = num;

numOfNst[num-1]++;

strcpy (models[numModels].name, "");

if (models[numModels].rateParams[0] == 1 &&

models[numModels].rateParams[1] == 1 &&

models[numModels].rateParams[2] == 1 &&

models[numModels].rateParams[3] == 1 &&

models[numModels].rateParams[4] == 1 &&

models[numModels].rateParams[5] == 1)

strcpy (models[numModels].name, "JC69/F81");

else if (models[numModels].rateParams[0] == 1 &&

models[numModels].rateParams[1] == 2 &&

models[numModels].rateParams[2] == 1 &&

models[numModels].rateParams[3] == 1 &&

models[numModels].rateParams[4] == 2 &&

models[numModels].rateParams[5] == 1)

strcpy (models[numModels].name, "K80/HKY85");

else if (models[numModels].rateParams[0] == 1 &&

models[numModels].rateParams[1] == 2 &&

models[numModels].rateParams[2] == 3 &&

models[numModels].rateParams[3] == 4 &&

models[numModels].rateParams[4] == 5 &&

models[numModels].rateParams[5] == 6)

strcpy (models[numModels].name, "EqualIn/GTR");

else if (models[numModels].rateParams[0] == 1 &&

models[numModels].rateParams[1] == 2 &&

models[numModels].rateParams[2] == 1 &&

models[numModels].rateParams[3] == 1 &&

models[numModels].rateParams[4] == 3 &&

models[numModels].rateParams[5] == 1)

strcpy (models[numModels].name, "TN93");

models[numModels].index = numModels + 1;

numModels++;

}

}

}

}

}

}

}

}

I

>

> This part is a bit more difficult. My first inclination is to define a

> set of equivalence classes on the enumerations, and then store the each

> unique equivalence. This might be straightforward. For example, You

> stated that 1112 is equivalent to 2221. You can classify these datum as

> 31. Another example, is 1222, 3444, etc which are equivalent to 13. Yet

> another example might be 1223, 1331, 3112, etc which are equivalent to

> 121. However, the precise classification is not clear from your

> description.

>

> /david