/****************************************************************** * * * Nest version 2 - 3D Wasp Nest Simulator * * Copyright (C) 1997 Sylvain GUERIN * * LIASC, ENST Bretagne & Santa Fe Institute * * * ****************************************************************** E-mail: Sylvain.Guerin@enst-bretagne.fr or: Sylvain Guerin 13 rue des Monts Lorgeaux, 51460 L'EPINE, FRANCE ****************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ****************************************************************** Name : simu.c Component : simulation Fonctionality : contains methods for object Simulation ******************************************************************/ #include "simu.h" #include "algo.h" #include "graph.h" #include #include #include "ViewInt.h" /* ---------------------------------------------------- */ Simulation::Simulation (unsigned int aNumIndex, unsigned int maxRuleArray, SimulationType aSimuType) { simuType = aSimuType; simulationRuleArray = new RuleArray(maxRuleArray, simuType); numIndex = aNumIndex; isLoaded = BFalse; isSaved = BFalse; isSimulated = BFalse; isDisplayed = BFalse; isEdited = BFalse; isCompressed = BFalse; archSize = 0; mark = (double)0; archSize = 0; isPreviewed = BFalse; displayAndWindowSet = BFalse; } Simulation::~Simulation () { delete simulationRuleArray; if (isSimulated) { delete simulationArchitecture; } } int Simulation::load (char* aPathName, char* aFileName, Boolean loadPreview) { int res; double aMark; char readName[256]; char archFileName[256]; char previewFileName[256]; char fname[256]; FILE *pf; unsigned int readSize; char temp[256]; int lenght; FileFormat format; char buffer[256]; /* free of current simulation architecture */ if (isSimulated) { delete simulationArchitecture; isSimulated = BFalse; } lenght = strlen (aFileName); if ( (aFileName[lenght-5] == '.') && (aFileName[lenght-4] == 'z') && (aFileName[lenght-3] == 'h') && (aFileName[lenght-2] == 'u') && (aFileName[lenght-1] == 'f')) { /* ok, compressed file */ isCompressed = BTrue; aFileName[lenght-5] = '\0'; } else if (isCompressed == BTrue) { isCompressed = BTrue; /* je m'interroge personnellement sur cette ligne */ } else { isCompressed = BFalse; } lenght = strlen (aFileName); if ( (aFileName[lenght-4] == '.') && (aFileName[lenght-3] == 'r') && (aFileName[lenght-2] == 'u') && (aFileName[lenght-1] == 'l')) { // printf ("Format: .rul\n"); format = rulFile; } else if ( (aFileName[lenght-4] == '.') && (aFileName[lenght-3] == 't') && (aFileName[lenght-2] == 'h') && (aFileName[lenght-1] == 'r')) { // printf ("Format: .thr\n"); format = thrFile; } else { printf ("Format: undefined\n"); format = undefined; } if (isCompressed) { /* Procedure de decompression */ decompression (aPathName, aFileName, format); } strcpy (archFileName, "."); strcat (archFileName, aFileName); strcat (archFileName, ".arc"); strcpy (previewFileName, "."); strcat (previewFileName, aFileName); strcat (previewFileName, ".xpm"); if (isCompressed) { if (format == rulFile) { res = simulationRuleArray->loadFromFile (aPathName, tempRulFile (aFileName, buffer), &aMark, readName); } else { res = simulationRuleArray->loadFromFile (aPathName, tempThrFile (aFileName, buffer), &aMark, readName); } } else { res = simulationRuleArray->loadFromFile (aPathName, aFileName, &aMark, readName); } if (res == 1) { /* si les regles sont bien chargees */ mark = aMark; isLoaded = BTrue; isSaved = BTrue; strcpy (pathName, aPathName); strcpy (fileName, aFileName); ruleNumber = simulationRuleArray->getElementsNb (); strcpy (name, readName); /* maintenant, on s'occupe de charger l'eventuelle architecture si le flag loadPreview est a TRUE */ if (loadPreview == BFalse) { } else { strcpy (fname, aPathName); if (isCompressed) strcat (fname, tempArchFile (aFileName, buffer)); else { strcat (fname, "."); strcat (fname, aFileName); strcat (fname, ".arc"); } pf = fopen(fname,"r"); if (pf == NULL) { /* pas d'architecture, pas grave */ } else { fgets (temp, 256, pf); /* lecture du parametre archSize */ sscanf (temp, "architecture size = %d", &readSize); fclose (pf); // printf ("arch size: %d [%s]\n", readSize, temp); if ((readSize>1) && (readSize<256)) { archSize = readSize; if (isSimulated) { /* si c'est simule (c'est debile, mais bon...) */ delete simulationArchitecture; simulationArchitecture = new Architecture(readSize, simuType); simulationArchitecture->loadArchitecture (aPathName, archFileName); } else { /* sinon ca ne l'est pas */ isSimulated = BTrue; simulationArchitecture = new Architecture(readSize, simuType); if (isCompressed) { simulationArchitecture ->loadArchitecture (aPathName, tempArchFile (aFileName, buffer)); } else { simulationArchitecture->loadArchitecture (aPathName, archFileName); } } } else { printf ("ERROR: size of read architecture is not valid (%d)\n", readSize); } classifyRules (); /* on re-classifie les regles */ } /* maintenant, on s'occupe de charger l'eventuelle previsualisation */ /* attention: si pas d'architecture, pas de previsualisation non plus */ if (isSimulated) { strcpy (fname, aPathName); if (isCompressed) { strcat (fname, tempPreviewFile (aFileName, buffer)); } else { strcat (fname, "."); strcat (fname, aFileName); strcat (fname, ".xpm"); } pf = fopen(fname,"r"); if (pf == NULL) { /* pas de fichier de previsualisation, pas grave, on va reconstruire l'image a partir de l'architecture */ simulationArchitecture->loadPreviewFromArch (previewDisplay, previewWindow, previewGC, colorPointer, previewFontInfo); isPreviewed = BTrue; } else { fclose (pf); if (isCompressed) { if (simulationArchitecture->loadPreview (aPathName, tempPreviewFile (aFileName, buffer), previewDisplay, previewWindow) == 0) { printf ("ERROR: unable to read preview file (%s)\n", tempPreviewFile (aFileName, buffer)); } else { /* tout va bien */ isPreviewed = BTrue; } } else { if (simulationArchitecture->loadPreview (aPathName, previewFileName, previewDisplay, previewWindow) == 0) { printf ("ERROR: unable to read preview file (%s)\n", previewFileName); } else { /* tout va bien */ isPreviewed = BTrue; } } } /* if (pf == NULL) */ } /* if (isSimulated) */ else { } } if (isCompressed) { removeTempFiles (aPathName, aFileName, format); } return 1; /* ok, retour normal */ } else { if (isCompressed) { removeTempFiles (aPathName, aFileName, format); } return 0; /* ca s'est pas bien passe */ } } int Simulation::save (FileFormat aFileFormat, ArchMustBeSavedType aArchMustBeSavedValue, PreviewMustBeSavedType aPreviewMustBeSavedValue, MustBeCompressedType aMustBeCompressedType) { int res; /* USELESS int i; */ char archFileName[256]; char previewFileName[256]; FileFormat newFileFormat; if (aMustBeCompressedType == 1) { isCompressed = BTrue; } else { isCompressed = BFalse; } strcpy (archFileName, "."); strcat (archFileName, fileName); strcat (archFileName, ".arc"); strcpy (previewFileName, "."); strcat (previewFileName, fileName); strcat (previewFileName, ".xpm"); /* avant de sauver le fichier en question, il est peut-etre necessaire de changer le suffixe du nom de fichier, ce que l'on se propose de faire sur le champ */ newFileFormat = checkFileFormat (); if (newFileFormat == undefined) { setFileNameToRightFormat (aFileFormat); } /* et on le sauve... */ res = simulationRuleArray->saveInFile (pathName, fileName, mark, name, newFileFormat); if (aMustBeCompressedType == 1) { CompressAlgorithm algorithm; algorithm.compress (pathName, fileName); } /* sauvegarde de l'architecture (s'il le faut) */ if ((isSimulated) && (aArchMustBeSavedValue == archMustBeSaved)) { if (simulationArchitecture->saveArchitecture (pathName, archFileName) == 0) { printf ("Error: unable to save architecture file\n"); } else { if (aMustBeCompressedType == 1) { CompressAlgorithm algorithm; algorithm.compress (pathName, archFileName); } } } /* sauvegarde de la previsualisation (s'il le faut) */ if ((isPreviewed) && (aPreviewMustBeSavedValue == previewMustBeSaved)) { if (displayAndWindowSet == BFalse) { printf ("ERROR: unable to save preview: display not initialized\n"); } else { if (simulationArchitecture->savePreview (pathName, previewFileName, previewDisplay) == 0) { printf ("Error: unable to save preview file\n"); } else { if (aMustBeCompressedType == 1) { CompressAlgorithm algorithm; algorithm.compress (pathName, previewFileName); } } } } isSaved = BTrue; return res; } void Simulation::simulate (int aSize, int anIterationsNumber, int aMaxCells, FitnessType fitnessType, learningMode typeOfLearning, int learningParam, int mustBeEvaluated, double noiseRate) { archSize = aSize; if (isSimulated) { delete simulationArchitecture; simulationArchitecture = new Architecture(archSize, simuType); } else { isSimulated = BTrue; simulationArchitecture = new Architecture(archSize, simuType); } simulationArchitecture->simulate (simulationRuleArray, anIterationsNumber, aMaxCells, typeOfLearning, learningParam, noiseRate); if (mustBeEvaluated) { mark = evaluate (fitnessType); } else { mark = -1.0; } setSimuResults (); isSaved = BFalse; classifyRules (); } int Simulation::learn (int numberOfRulesLoLearn, int mustRuleBeApplied) { if (!isSimulated) { printf ("ERROR: unable to learn on unsimulated architecture\n"); return -1; } else { return simulationArchitecture->learn (simulationRuleArray, numberOfRulesLoLearn, mustRuleBeApplied); } } void Simulation::setSimuResults () { int i; cellsNumber = simulationArchitecture->cellsNumber; for (i=0; iruleOccurs[i]; } } void Simulation::simulateShowsStats (int aSize, int anIterationsNumber, int aMaxCells, FitnessType fitnessType, learningMode typeOfLearning, int learningParam, int mustBeEvaluated, double noiseRate, InfoBox* anInfoBox, ViewInterface* aViewInterface, int showCellsSteps) { archSize = aSize; if (isSimulated) { delete simulationArchitecture; simulationArchitecture = new Architecture(archSize, simuType); } else { isSimulated = BTrue; simulationArchitecture = new Architecture(archSize, simuType); } simulationArchitecture->setStats (anInfoBox); if (aViewInterface != NULL) { simulationArchitecture->setViewInterface (aViewInterface, showCellsSteps); aViewInterface->setArchitecture (simulationArchitecture); } simulationArchitecture->simulate (simulationRuleArray, anIterationsNumber, aMaxCells, typeOfLearning, learningParam, noiseRate); if (mustBeEvaluated) { mark = evaluate (fitnessType); } else { mark = -1.0; } isSaved = BFalse; classifyRules (); } void Simulation::arrayUpdate (ArrayWindow* simulationsArray) { char temp[20]; simulationsArray->addData (numIndex, 0, (int)numIndex); simulationsArray->addData (numIndex, 1, name); if (simuType == cubic) { simulationsArray->addData (numIndex, 2, "Cubic"); } else { simulationsArray->addData (numIndex, 2, "Hexa"); } simulationsArray->addData (numIndex, 3, (int)ruleNumber); if (isSimulated) { simulationsArray->addData (numIndex, 4, "yes"); } else { simulationsArray->addData (numIndex, 4, "no"); } simulationsArray->addData (numIndex, 5, (int)archSize); if (mark != -1.0) { sprintf (temp, "%f", mark); simulationsArray->addData (numIndex, 6, temp); } else { simulationsArray->addData (numIndex, 6, "unknown"); } simulationsArray->addData (numIndex, 7, fileName); } void Simulation::setFromOtherSimulation (Simulation* aSimulation) { int i; simulationRuleArray->setFromOtherRuleArray (aSimulation->simulationRuleArray); numIndex = aSimulation->numIndex; strcpy (name, aSimulation->name); strcpy (pathName, aSimulation->pathName); strcpy (fileName, aSimulation->fileName); isLoaded = aSimulation->isLoaded ; isSimulated = aSimulation->isSimulated ; isDisplayed = aSimulation->isDisplayed ; isEdited = aSimulation->isEdited ; isSaved = aSimulation->isSaved ; isPreviewed = aSimulation->isPreviewed; isCompressed = aSimulation->isCompressed; archSize = aSimulation->archSize ; ruleNumber = aSimulation->ruleNumber ; mark = aSimulation->mark ; simuType = aSimulation->simuType ; strcpy (host, aSimulation->host); hostNb = aSimulation->hostNb ; for (i=0; iruleOccurs[i]; } cellsNumber = aSimulation->cellsNumber; } void Simulation::randomGenerate (double pRedCell, double pYellowCell, double averageRuleNumber, double varianceRuleNumber, RandomGenerationType randomGenerationType) { simulationRuleArray->randomGenerate (pRedCell, pYellowCell, averageRuleNumber, varianceRuleNumber, randomGenerationType); ruleNumber = simulationRuleArray->nbElements; } void Simulation::crossOver (Simulation* aSimulation, CrossoverType crossoverType) { unsigned int i; int c, delta; Rule rule1 (simuType), rule2 (simuType); long swap; int min, cut, cut1, cut2; RuleArray* ruleArray1; RuleArray* ruleArray2; int firstColonieClassNb[3]; int secondColonieClassNb[3]; int ruleOccurs1[maxRules]; int ruleOccurs2[maxRules]; int index1, index2; /* Dans toute cette partie du cross-over, il n'y a pas lieu de s'inquieter des regles en double, elle seront effacees dans la mutation */ /* printf ("Applying crossover (type="); if (crossoverType == SimpleCrossover) printf ("SimpleCrossover)\n"); else if (crossoverType == DoubleCrossover) printf ("DoubleCrossover)\n"); else if (crossoverType == AdvancedCrossover) printf ("AdvancedCrossover)\n"); else if (crossoverType == AdvancedCrossover2) printf ("AdvancedCrossover2)\n"); simulationRuleArray->debug (); aSimulation->simulationRuleArray->debug (); */ /***************************** * SimpleCrossover * *****************************/ if (crossoverType == SimpleCrossover) { min = ruleNumber; if ((int)aSimulation->ruleNumber < min) { min = aSimulation->ruleNumber; } if (min > 1) { RandomGenerator randomGenerator (PSEUDO, 1, min-1); cut = randomGenerator.getNumber (); } else { //printf ("Warning: crossing-over for 2 one-rule'colonies\n"); return; } cellsNumber = 0; aSimulation->cellsNumber = 0; if (ruleNumber < aSimulation->ruleNumber) { for (i=cut; iget (i, &rule1); aSimulation->simulationRuleArray->get (i, &rule2); simulationRuleArray->set (i, rule2); aSimulation->simulationRuleArray->set (i, rule1); swap = ruleOccurs[i]; ruleOccurs[i] = aSimulation->ruleOccurs[i]; aSimulation->ruleOccurs[i] = swap; /* rules occurences are updated */ } delta = (int)aSimulation->ruleNumber-(int)ruleNumber; for (i=ruleNumber; iruleNumber; i++) { aSimulation->simulationRuleArray->get (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[i] = aSimulation->ruleOccurs[i]; aSimulation->ruleOccurs[i] = 0; } ruleNumber = simulationRuleArray->nbElements; aSimulation->simulationRuleArray->nbElements = aSimulation->simulationRuleArray->nbElements - delta; aSimulation->ruleNumber = aSimulation->ruleNumber - delta; } else { /* aSimulation->ruleNumber <= ruleNumber */ for (i=cut; iruleNumber; i++) { simulationRuleArray->get (i, &rule1); aSimulation->simulationRuleArray->get (i, &rule2); simulationRuleArray->set (i, rule2); aSimulation->simulationRuleArray->set (i, rule1); swap = ruleOccurs[i]; ruleOccurs[i] = aSimulation->ruleOccurs[i]; aSimulation->ruleOccurs[i] = swap; /* rules occurences are updated */ } delta = (int)ruleNumber-(int)aSimulation->ruleNumber; for (i=aSimulation->ruleNumber; iget (i, &rule1); aSimulation->simulationRuleArray->add (rule1); aSimulation->ruleOccurs[i] = ruleOccurs[i]; ruleOccurs[i] = 0; } aSimulation->ruleNumber = aSimulation->simulationRuleArray->nbElements; simulationRuleArray->nbElements = simulationRuleArray->nbElements-delta; ruleNumber = aSimulation->ruleNumber-delta; } } /***************************** * DoubleCrossover * *****************************/ else if (crossoverType == DoubleCrossover) { min = ruleNumber; if ((int)aSimulation->ruleNumber < min) { min = aSimulation->ruleNumber; } if (min > 1) { RandomGenerator randomGenerator (PSEUDO, 1, min-1); cut1 = randomGenerator.getNumber (); cut2 = randomGenerator.getNumber (); if (cut1>cut2) { cut = cut1; cut1 = cut2; cut2 = cut; } } else { //printf ("Warning: crossing-over for 2 one-rule'colonies\n"); return; } cellsNumber = 0; aSimulation->cellsNumber = 0; for (i=cut1; (int)iget (i, &rule1); aSimulation->simulationRuleArray->get (i, &rule2); simulationRuleArray->set (i, rule2); aSimulation->simulationRuleArray->set (i, rule1); swap = ruleOccurs[i]; ruleOccurs[i] = aSimulation->ruleOccurs[i]; aSimulation->ruleOccurs[i] = swap; /* rules occurences are updated */ } } else { /* alors on est dans un cas typique d'advanced crossover */ /* en premier lieu, on construit, deux sets de regles, ou les regles sont triees par classes: 1. classe A 2. classe B 3. classe unused */ ruleArray1 = new RuleArray (simulationRuleArray->getMaxElements (), simulationRuleArray->getSimuType ()); ruleArray2 = new RuleArray (aSimulation->simulationRuleArray->getMaxElements (), aSimulation->simulationRuleArray->getSimuType ()); ruleArray1->clear (); ruleArray2->clear (); index1 = 0; index2 = 0; for (c=0; c<3; c++) { firstColonieClassNb[c] = 0; secondColonieClassNb[c] = 0; for (i=0; inbElements; i++) { simulationRuleArray->get (i, &rule1); if (rule1.getRuleClass () == (RuleClass)c) { firstColonieClassNb[c]++; ruleArray1->add (rule1); ruleOccurs1[index1] = ruleOccurs[i]; index1++; } } for (i=0; isimulationRuleArray->nbElements; i++) { aSimulation->simulationRuleArray->get (i, &rule2); if (rule2.getRuleClass () == (RuleClass)c) { secondColonieClassNb[c]++; ruleArray2->add (rule2); ruleOccurs2[index2] = ruleOccurs[i]; index2++; } } } /* for (c=0; c<3; c++) printf ("First colonie / classe %d: %d rules\n", c, firstColonieClassNb[c]); ruleArray1->debug (); for (c=0; c<3; c++) printf ("Second colonie / classe %d: %d rules\n", c, secondColonieClassNb[c]); ruleArray2->debug (); */ /***************************** * AdvancedCrossover * *****************************/ if (crossoverType == AdvancedCrossover) { /* Voila ce qu'on fait: colonie 1: | A | B | Unused | colonie 2: | A' | B' | Unused' | colonie 1: | A | B' | Unused | colonie 2: | A' | B | Unused' | si le nombre de regles depasse le maximum, alors on ne fait rien */ /* pour la premiere colonie: */ if (firstColonieClassNb[0] +secondColonieClassNb[1] +firstColonieClassNb[2] < maxRules) { index1 = 0; simulationRuleArray->clear (); /* A */ for (i=0; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs1[i]; index1++; } /* B' */ for (i=secondColonieClassNb[0]; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs2[i]; index1++; } /* Unused */ for (i=firstColonieClassNb[0]+firstColonieClassNb[1]; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs1[i]; index1++; } ruleNumber = simulationRuleArray->nbElements; } else { // printf ("Warning: maxRules reached for crossing-over. Continue anyway (colony unchanged).\n"); } /* pour la deuxieme colonie: */ if (secondColonieClassNb[0] +firstColonieClassNb[1] +secondColonieClassNb[2] < maxRules) { index2 = 0; aSimulation->simulationRuleArray->clear (); /* A' */ for (i=0; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs2[i]; index2++; } /* B */ for (i=firstColonieClassNb[0]; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs1[i]; index2++; } /* Unused' */ for (i=secondColonieClassNb[0]+secondColonieClassNb[1]; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs2[i]; index2++; } aSimulation->ruleNumber = aSimulation->simulationRuleArray->nbElements; } else { // printf ("Warning: maxRules reached for crossing-over. Continue anyway (colony unchanged).\n"); } } /***************************** * AdvancedCrossover2 * *****************************/ else if (crossoverType == AdvancedCrossover2) { /* Voila ce qu'on fait: colonie 1: | A | B | Unused | colonie 2: | A' | B' | Unused' | colonie 1: | A | A' | B | B' |Unused''| colonie 2: | A' | A | B' | B |Unused'''| si card(A)+card(A')+card(B)+card(B') > tailles de colonies, on ne fait rien sinon, on fait comme si dessus, et on complete les colonies pour qu'elles fassent la meme taille qu'avant, en ajoutant des regles non utilisees (Unused'' est inclus dans Unused et Unused''' est inclus dans Unused') */ /* pour la premiere colonie: */ if (firstColonieClassNb[0] +firstColonieClassNb[1] +secondColonieClassNb[0] +secondColonieClassNb[1] < (int)simulationRuleArray->nbElements) { index1 = 0; simulationRuleArray->clear (); /* A et B */ for (i=0; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs1[i]; index1++; } /* A' et B' */ for (i=0; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs2[i]; index1++; } /* et on finit par les regles non utilisees */ for (i=firstColonieClassNb[0]+firstColonieClassNb[1]; (int)iget (i, &rule1); simulationRuleArray->add (rule1); ruleOccurs[index1] = ruleOccurs1[i]; index1++; } ruleNumber = simulationRuleArray->nbElements; } else { // printf ("Warning: maxRules reached for crossing-over. Continue anyway (colony unchanged).\n"); } /* pour la deuxieme colonie: */ if (firstColonieClassNb[0] +firstColonieClassNb[1] +secondColonieClassNb[0] +secondColonieClassNb[1] < (int)aSimulation->simulationRuleArray->nbElements) { index2 = 0; aSimulation->simulationRuleArray->clear (); /* A et B */ for (i=0; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs1[i]; index2++; } /* A' et B' */ for (i=0; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs2[i]; index2++; } /* et on finit par les regles non utilisees */ for (i=secondColonieClassNb[0]+secondColonieClassNb[1]; (int)iget (i, &rule2); aSimulation->simulationRuleArray->add (rule2); aSimulation->ruleOccurs[index2] = ruleOccurs2[i]; index2++; } aSimulation->ruleNumber = aSimulation->simulationRuleArray->nbElements; } else { // printf ("Warning: maxRules reached for crossing-over. Continue anyway (colony unchanged).\n"); } } delete ruleArray1; delete ruleArray2; } /* simulationRuleArray->debug (); aSimulation->simulationRuleArray->debug (); printf ("End.\n\n"); */ } double Simulation::evaluate (FitnessType fitnessType) { int i; int n; double returnedFitness; /************************************ * UsedRulesFraction * ************************************/ if (fitnessType == UsedRulesFraction) { n=0; for (i=0; i<(int)simulationRuleArray->getElementsNb (); i++) { if (simulationArchitecture->ruleOccurs[i] > 0) { n++; } } return (double)((double)(n) /(double)(simulationRuleArray->getElementsNb ())); } /************************************ * GlobalUsedRules * ************************************/ else if (fitnessType == GlobalUsedRules) { n=0; for (i=0; i<(int)simulationRuleArray->getElementsNb (); i++) { if (simulationArchitecture->ruleOccurs[i] > 0) { n++; } } return (double)((double)(n) /(double)(maxRules)); } /************************************ * Compacity * ************************************/ else if (fitnessType == Compacity) { double fitness; Rule aRule (simuType); fitness = 0.0; for (i=0; i<(int)simulationRuleArray->getElementsNb (); i++) { simulationRuleArray->get (i, &aRule); fitness = fitness + ( simulationArchitecture->ruleOccurs[i] * (double)(aRule.getInRuleCellNumber ())/26.0 ); } return (4 * fitness / (double)(simulationArchitecture->cellsNumber)); /* on multiplie la fitness par 4 pour avoir une fitness assez grande tout de meme */ } /************************************ * Complexity * ************************************/ else if (fitnessType == Complexity) { return simulationArchitecture->graph->getComplexityFitness (); } /************************************ * Coherence * ************************************/ else if (fitnessType == Coherence) { return simulationArchitecture->graph->getCoherenceFitness (); } /************************************ * HybridMethod * ************************************/ else if (fitnessType == HybridMethod) { returnedFitness = 1.4 * evaluate (Compacity) * evaluate (Complexity) * pow ((evaluate(Coherence)), 1.0/3.0); /* autre possibilite: rajouter *evaluate (GlobalUsedRules), mais ca entraine un biais important et indesirable */ /* on multiplie par 1.4 pour avoir des fitness plus importantes: NOTE: ca change rien, mais c'est plus esthetique. En fait, ceci pose plus generalement le probleme de l'utilite de l'esthetique, c'est-a-dire de la place de l'art dans la societe. Les artistes sont-ils "utiles", dans la mesure ou ils ne produisent rien qui soit vital a la survie de leur congenaires ? Leur production ameliore cependant la qualite de vie des membres de la societe, mais la question se pose plutot dans l'impossibilite de quantifier l'utilite de leur travail (leur(s) oeuvre(s)). L'art n'est pas quantifiable. Maintenant, on peut se poser la question de savoir ou est l'art dans cette pauvre methode qui calcule la fitness d'un machin avec des cubes. Apres tout, l'informatique ne s'apparente -t-elle par avec l'art dans la mesure ou elle est issue d'un elan creatif ? Question ouverte... */ if (returnedFitness >= 0) { return returnedFitness; } else { /* je vois pas pourquoi, mais c'est arrive dans le passe */ return 0.0; } } /************************************ * HybridMethod2 * ************************************/ else if (fitnessType == HybridMethod2) { return evaluate (Complexity)*evaluate (Coherence); } /************************************ * NOT IMPLEMENTED * ************************************/ else { printf ("Error: evaluation type not implemented\n"); } return 0.0; } void Simulation::classifyRules () { simulationArchitecture->graph->classifyRules (simulationRuleArray); } int Simulation::saveAsResult (char* aPathName, char* aFileName) { /* on veut sauver dans un fichier .xxxx.res.zhuf les trucs suivants: - la note obtenue - le nombre de cellules crees - les occurences de chaque regle [maxRules] */ /* ce fichier est compresse, notons-le */ char fname[256]; /* USELESS char temp[256]; */ int aFile; int i; CompressAlgorithm algorithm; RuleClass writtenRuleClass; strcpy (fname, aPathName); strcat (fname, "."); strcat (fname, aFileName); remove (fname); /* si le fichier existe, on le vire */ if ((aFile = creat (fname, S_IRUSR|S_IWUSR)) == -1) { return 0; } else { write (aFile, (void *)&mark, sizeof(double)); write (aFile, (void *)&cellsNumber, sizeof (long)); for (i=0; igetElementsNb(); i++) { writtenRuleClass = (simulationRuleArray->get(i))->getRuleClass (); write (aFile, (void *)&(writtenRuleClass), sizeof (RuleClass)); } close (aFile); /* compression */ strcpy (fname, "."); strcat (fname, aFileName); algorithm.compress (aPathName, fname); return 1; } } int Simulation::loadResult (char* aPathName, char* aFileName) { char fname[256]; /* USELESS char temp[256]; */ char compressedFile[256]; char decompressedFile[256]; int aFile; int i; CompressAlgorithm algorithm; RuleClass readRuleClass; /* decompression */ strcpy (compressedFile, "."); strcat (compressedFile, aFileName); strcat (compressedFile, ".zhuf"); strcpy (decompressedFile, "tmp."); strcat (decompressedFile, aFileName); algorithm.decompress (aPathName, compressedFile, decompressedFile); strcpy (fname, aPathName); strcat (fname, decompressedFile); if ((aFile = open (fname, O_RDONLY)) == -1) { /* ca marche pas, on vire le fichier decompresse et on quitte */ remove (fname); return 0; } else { read (aFile, (void *)&mark, sizeof(double)); read (aFile, (void *)&cellsNumber, sizeof (long)); for (i=0; igetElementsNb(); i++) { read (aFile, (void *)&(readRuleClass), sizeof (RuleClass)); simulationRuleArray->get(i)->setRuleClass (readRuleClass); } close (aFile); remove (fname); return 1; } } int Simulation::mutation (double pRedCell, double pYellowCell, double pUsed, double pUnused, RandomGenerationType randomGenerationType) { int i, choice; RandomGenerator randomGenerator (PSEUDO, 0, 9999); Rule randomRule (simuType); int nbMutations; nbMutations = 0; for (i=0; i<(int)ruleNumber; i++) { // printf ("rule %d : %d occurences\n", i, ruleOccurs[i]); if (ruleOccurs[i] == 0) { // printf ("Apply mutation for unused rule (%f): ", pUnused); choice = randomGenerator.getNumber (); if ((double)(choice)/10000.0 < pUnused) { /* apply mutation */ randomRule.randomGenerate (pRedCell, pYellowCell,randomGenerationType); simulationRuleArray->set (i, randomRule); nbMutations++; //printf ("APPLY mutation\n"); } else { //printf ("NO mutation\n"); } } else { //printf ("Apply mutation for used rule (%f): ", pUsed); choice = randomGenerator.getNumber (); if ((double)(choice)/10000.0 < pUsed) { /* apply mutation */ randomRule.randomGenerate (pRedCell, pYellowCell,randomGenerationType); simulationRuleArray->set (i, randomRule); nbMutations++; //printf ("APPLY mutation\n"); } else { //printf ("NO mutation\n"); } } } simulationRuleArray->removeTwiceRules (pRedCell,pYellowCell, randomGenerationType); ruleNumber = simulationRuleArray->nbElements; return nbMutations; } int Simulation::swap (double pSwap) { int i, swapNumber; int ruleIndex1, ruleIndex2; Rule aRule1 (simuType), aRule2 (simuType); RandomGenerator randomGenerator (GAUSS, 0, ruleNumber, pSwap*(double)ruleNumber, pSwap*(double)ruleNumber/3); RandomGenerator randomGenerator2 (PSEUDO, 0, ruleNumber-1); swapNumber = randomGenerator.getNumber (); for (i=0; iget (ruleIndex1, &aRule1); simulationRuleArray->get (ruleIndex2, &aRule2); simulationRuleArray->set (ruleIndex1, aRule2); simulationRuleArray->set (ruleIndex2, aRule1); } return swapNumber; } void Simulation::setDisplayAndWindow (Display* aDisplay, Visual* aVisual, GC* aGC, Window* aWindow, unsigned long* aColorPointer, XFontStruct* aFontInfo) { previewDisplay = aDisplay; previewVisual = aVisual; previewGC = aGC; previewWindow = aWindow; displayAndWindowSet = BTrue; colorPointer = aColorPointer; previewFontInfo = aFontInfo; } /* cherche le format du fichier */ FileFormat Simulation::checkFileFormat () { int lenght; lenght = strlen (fileName); if ( (fileName[lenght-4] == '.') && (fileName[lenght-3] == 'r') && (fileName[lenght-2] == 'u') && (fileName[lenght-1] == 'l')) { /* .rul file detecte */ return rulFile; } else if ( (fileName[lenght-4] == '.') && (fileName[lenght-3] == 't') && (fileName[lenght-2] == 'h') && (fileName[lenght-1] == 'r')) { /* .rul file detecte */ return thrFile; } else { return undefined; } } /* positionne le nom du fichier en fonction du format */ void Simulation::setFileNameToRightFormat (FileFormat aFileFormat) { int lenght; int pt, i; lenght = strlen (fileName); if (aFileFormat == rulFile) { if ( (fileName[lenght-3] == 'r') && (fileName[lenght-2] == 'u') && (fileName[lenght-1] == 'l')) { /* .rul file detecte, rien a faire donc */ } else { /* on va mettre le suffixe .rul de force: - si pas de suffixe, on l'ajoute au nom - si un suffixe, on le remplace */ pt = -1; for (i=0; i<(int)strlen (fileName); i++) { if (fileName[i] == '.') { pt = i; } } if (pt == -1) { strcat (fileName, ".rul"); } else { fileName[pt+1] = 'r'; fileName[pt+2] = 'u'; fileName[pt+3] = 'l'; fileName[pt+4] = '\0'; } } } else if (aFileFormat == thrFile) { if ( (fileName[lenght-3] == 't') && (fileName[lenght-2] == 'h') && (fileName[lenght-1] == 'r')) { /* .thr file detecte, rien a faire donc */ } else { /* on va mettre le suffixe .thr de force: - si pas de suffixe, on l'ajoute au nom - si un suffixe, on le remplace */ pt = -1; for (i=0; i<(int)strlen (fileName); i++) { if (fileName[i] == '.') { pt = i; } } if (pt == -1) { strcat (fileName, ".thr"); } else { fileName[pt+1] = 't'; fileName[pt+2] = 'h'; fileName[pt+3] = 'r'; fileName[pt+4] = '\0'; } } } } /* void Simulation::compression (char* aPathName, char* aFileName) { */ /* a virer a-priori */ /* CompressAlgorithm algorithm; char archFileName[256]; char previewFileName[256]; printf ("Procedure de compression\n"); strcpy (archFileName, "."); strcat (archFileName, aFileName); strcat (archFileName, ".arc"); strcpy (previewFileName, "."); strcat (previewFileName, aFileName); strcat (previewFileName, ".xpm"); algorithm.compress (aPathName, aFileName); algorithm.compress (aPathName, archFileName); algorithm.compress (aPathName, previewFileName); */ /* } */ void Simulation::decompression (char* aPathName, char* aFileName, FileFormat format) { CompressAlgorithm algorithm1, algorithm2, algorithm3; char fileName[256]; char archFileName[256]; char previewFileName[256]; /* USELESS int lenght; */ char temp[256]; // printf ("Procedure de decompression\n"); strcpy (fileName, aFileName); strcpy (archFileName, "."); strcat (archFileName, aFileName); strcat (archFileName, ".arc"); strcpy (previewFileName, "."); strcat (previewFileName, aFileName); strcat (previewFileName, ".xpm"); strcat (fileName, ".zhuf"); strcat (archFileName, ".zhuf"); strcat (previewFileName, ".zhuf"); if (format == rulFile) { algorithm1.decompress (aPathName, fileName, tempRulFile (aFileName, temp)); } else { algorithm1.decompress (aPathName, fileName, tempThrFile (aFileName, temp)); } algorithm2.decompress (aPathName, archFileName, tempArchFile (aFileName, temp)); algorithm3.decompress (aPathName, previewFileName, tempPreviewFile (aFileName, temp)); } void Simulation::removeTempFiles (char* aPathName, char* aFileName, FileFormat format) { char fname[256]; char temp[256]; /* delete rules file */ strcpy (fname, aPathName); if (format == rulFile) { strcat (fname, tempRulFile (aFileName, temp)); } else { strcat (fname, tempThrFile (aFileName, temp)); } remove (fname); /* delete arch file */ strcpy (fname, aPathName); strcat (fname, tempArchFile (aFileName, temp)); remove (fname); /* delete preview file */ strcpy (fname, aPathName); strcat (fname, tempPreviewFile (aFileName, temp)); remove (fname); } char* Simulation::tempRulFile (char* aFileName, char* tempFile) { strcpy (tempFile, "tmp."); strcat (tempFile, aFileName); return tempFile; } char* Simulation::tempThrFile (char* aFileName, char* tempFile) { strcpy (tempFile, "tmp."); strcat (tempFile, aFileName); return tempFile; } char* Simulation::tempArchFile (char* aFileName, char* tempFile) { strcpy (tempFile, "tmp."); strcat (tempFile, aFileName); strcat (tempFile, ".arc"); return tempFile; } char* Simulation::tempPreviewFile (char* aFileName, char* tempFile) { strcpy (tempFile, "tmp."); strcat (tempFile, aFileName); strcat (tempFile, ".xpm"); return tempFile; }