00001
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <sys/stat.h>
00016 #include <sys/types.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include "cellularAutomata.h"
00020
00021
00022
00023 double* simulate( int** pop, int popSize, int caSize, int nStates, int nIters );
00024 void usage();
00025 int** getRules( char* file , int popSize );
00026 void freedom( int** rules , int popSize , double* fits );
00027 void outputFitnesses( double* fits , int popSize );
00028 int verboseMain( char** argv );
00029
00030
00034 char outFile[256];
00035
00036
00037 int main( int argc , char** argv ){
00038
00039
00040 if( argc != 7 ){
00041 if( argc == 8 && strcmp("-v",argv[7]) == 0 ){
00042 return verboseMain(argv);
00043 }
00044 else{
00045 usage();
00046 }
00047 }
00048
00049
00050
00051 int popSize = atoi( argv[1] );
00052
00053
00054
00055 int caSize = atoi( argv[2] );
00056
00057
00058
00059 int nInitCaStates = atoi( argv[3] );
00060
00061
00062
00063 int nCaIterations = atoi( argv[4] );
00064
00065
00066
00067 int** pop = getRules( argv[5] , popSize );
00068
00069
00070
00071 strcpy( outFile , argv[6] );
00072
00073
00074
00075 double* fitnesses
00076 = simulate( pop , popSize , caSize , nInitCaStates , nCaIterations );
00077
00078
00079
00080 outputFitnesses( fitnesses , popSize );
00081
00082
00083
00084 freedom( pop , popSize , fitnesses );
00085 return 0;
00086 }
00087
00088
00095 int
00096 verboseMain( char** argv ){
00097
00098 printf( "getting population size...\n" );fflush( stdout );
00099 int popSize = atoi( argv[1] );
00100
00101
00102
00103 printf( "getting size of the CA...\n" );fflush( stdout );
00104 int caSize = atoi( argv[2] );
00105
00106
00107
00108 printf( "getting the number of initial CA states...\n" );fflush( stdout );
00109 int nInitCaStates = atoi( argv[3] );
00110
00111
00112
00113 printf( "getting the number of iterations for CA...\n" );fflush( stdout );
00114 int nCaIterations = atoi( argv[4] );
00115
00116
00117
00118 printf( "getting the population...\n" );fflush( stdout );
00119 int** pop = getRules( argv[5] , popSize );
00120
00121
00122
00123 strcpy( outFile , argv[6] );
00124
00125
00126
00127 printf( "simulating...\n" );fflush( stdout );
00128 double* fitnesses
00129 = simulate( pop , popSize , caSize , nInitCaStates , nCaIterations );
00130
00131
00132
00133 outputFitnesses( fitnesses , popSize );
00134
00135
00136
00137 freedom( pop , popSize , fitnesses );
00138 return 0;
00139 }
00140
00141
00149 void
00150 outputFitnesses( double* fits , int popSize ){
00151 FILE* fp;
00152 if( (fp = fopen(outFile,"w")) == NULL ){
00153 perror( "caga.outputFitnesses() couldn't open file" );
00154 exit( -1 );
00155 }
00156
00157 int i;
00158 for( i=0 ; i<popSize ; i++ ){
00159 fprintf( fp , "%f\n" , fits[i] );
00160 }
00161
00162 fclose( fp );
00163 }
00164
00165
00169 void
00170 freedom( int** rules , int popSize , double* fits ){
00171 int i;
00172 for( i=0 ; i<popSize ; i++ ){
00173 free( rules[i] );
00174 }
00175 free( rules );
00176 free( fits );
00177 }
00178
00179
00189 int**
00190 getRules( char* file , int popSize ){
00191
00192 char rule[513];
00193 int** rules = (int**) calloc( popSize , sizeof(int*) );
00194 FILE* fp;
00195
00196 if( (fp=fopen(file,"r")) == NULL ){
00197 perror( "ERROR caga.getRules() couldn't open file" );
00198 exit(-1);
00199 }
00200
00201 int i, j;
00202 for( i=0 ; i<popSize ; i++ ){
00203 rules[i] = (int*) calloc( 512 , sizeof(int) );
00204 if( fgets(rule,513,fp) == NULL ){
00205 perror( "ERROR caga.getRules() error during reading file" );
00206 exit( -1 );
00207 }
00208 for( j=0 ; j<512 ; j++ ){
00209 rules[i][j] = rule[j] == '1';
00210 }
00211 }
00212
00213 fclose( fp );
00214
00215 return rules;
00216 }
00217
00218
00234 double*
00235 simulate( int** pop , int popSize , int caSize , int nStates , int nIters ){
00236
00237 double* fits = (double*) calloc( popSize , sizeof(double) );
00238 void* temp;
00239 CA** cas = randomCAs( nStates , caSize );
00240 CA* nextca = createCA( caSize );
00241 CA* ca = createCA( caSize );
00242 int majority, sum, nCorrect;
00243
00244
00245 int i, p, c;
00246 for( p=0 ; p<popSize ; p++ ){
00247 nCorrect = 0;
00248 for( c=0 ; c<nStates ; c++ ){
00249 cpCA( ca , cas[c] );
00250 majority = 2*aggregate(ca) > ca->size*ca->size ;
00251 for( i=0 ; i<nIters ; i++ ){
00252 if( i < nIters-1 ){
00253 step( ca , nextca , pop[p] );
00254 }
00255 else{
00256
00257 sum = stepWithCount( ca , nextca , pop[p] );
00258 }
00259 temp = ca;
00260 ca = nextca;
00261 nextca = temp;
00262 }
00263 if( ((sum==0) && (majority==0))
00264 || ((sum==ca->size*ca->size) && (majority==1)) ){
00265 ++nCorrect;
00266 }
00267 }
00268 fits[p] = (double) nCorrect / (double) nIters;
00269 }
00270
00271
00272 freeCA( nextca );
00273 freeCA( ca );
00274 for( i=0 ; i<nStates ; i++ ){
00275 freeCA( cas[i] );
00276 }
00277 free( cas );
00278 return fits;
00279 }
00280
00281
00285 void
00286 usage(){
00287 printf( "\
00288 USAGE: calcfits POPSIZE CASIZE INITCASTATES CAITERATIONS POPFILE FITOUT [-v]\n\
00289 Calculates the fitness of the entire population of size POPSIZE, where\n\
00290 POPFILE is a file that contains only the members of the popoulation in order\n\
00291 with no spaces.\n\
00292 The fitness is calculated by using the individuals in the population to try\n\
00293 to classify INITCASTATES cellular automata each square of size CASIZE, all\n\
00294 within CAITERATIONS steps each. The fitnesses are then all written to the\n\
00295 file FITOUT.\n\
00296 The -v option indicates whether or not to be verbose." );
00297 exit(0);
00298 }