/****************************************************************** * * * 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 : algo.h Component : simulation Fonctionality : contient les specifications de toutes les classes relatives au codage des colonies, des regles et de la simulation ******************************************************************/ #ifndef __algo_H #define __algo_H #include "graphical.h" #include "config.h" #include "tools.h" class ViewInterface; class Architecture; class RuleArray; class Position; class Rule; class PlanEnvironment; class Environment; class Cell; class RandomGenerator; class Graph; class GraphNode; /* Definition d'un type booleen */ enum Boolean { BFalse, BTrue }; /* Definition d'un type de cellule */ enum typeOfCell { EMPTY, RED, YELLOW, BLUE, UNKNOWN }; /* Definition d'un type de pavage (cubique ou hexagonal) */ enum SimulationType { cubic, hexa }; /* Definition des fitness functions applicables */ enum FitnessType { UsedRulesFraction, GlobalUsedRules, Compacity, Complexity, Coherence, HybridMethod, /* en fait, produit de Compacity*Complexity*Coherence */ HybridMethod2 /* produit Complexity*Coherence */ }; /* Definition des methodes de generation de nouvelles regles */ enum RandomGenerationType { PseudoRandom, ConnexityConstraint, SpacialCorrelation, ProbabilistTemplates }; enum TemplateType { Center, Top, Bottom, Side, TopSide, BottomSide }; /* Definition des differents modes d'apprentissage */ enum learningMode { noLearning, learnWhileSimulate, learnAfterSimulation, learnWhenBad }; /* trois types d'apprentissage: - le premier est facile a comprendre - le second correspond a l'apprentissage en cours de simulation (le parametre d'apprentissage est le nombre d'echecs autorises) - le troisieme correspond a l'apprentissage en fin de simulation (le parametre d'apprentissage est le nombre de regles que l'on peut creer en fin de simulation). C'est le mode utilise pour les algos genetiques. */ /* Definition des differents types de crossover */ enum CrossoverType { SimpleCrossover, /* une seule coupure */ DoubleCrossover, /* deux coupures */ AdvancedCrossover, /* Advanced Pro 2000 crossing-over (Classif.) */ AdvancedCrossover2 /* Advanced Pro 2000 crossing-over n2 (Classif.) */ }; /* Definition des formats de lecture/ecriture */ enum FileFormat { rulFile, thrFile, undefined }; /* classes des regles */ enum RuleClass { classA, classB, unusedClass }; /* Definition de la classe PlanEnvironment Elle correspond a l'environnement d'une cellule sur un plan horizontal. L'environnement d'une cellule est donc code avec trois instances de cette classe (plan superieur, plan median et plan inferieur. Un nombre entier (code) correspond a la configuration du plan. Ceci permet une optimisation de la memoire et du temps d'acces au donnees (tres utile pour savoir rapidement si l'environnement est une forme stimulante, ie si on peut appliquer la regle) */ class PlanEnvironment { public: PlanEnvironment (SimulationType aSimuType); /* constructeur */ ~PlanEnvironment (); /* destructeur */ void set (typeOfCell c00, typeOfCell c10, typeOfCell c20, typeOfCell c01, typeOfCell c11, typeOfCell c21, typeOfCell c02, typeOfCell c12, typeOfCell c22); void set (typeOfCell c0, typeOfCell c1, typeOfCell c2, typeOfCell c3, typeOfCell c4, typeOfCell c5, typeOfCell c6); void set (int i, int j, typeOfCell aCellType); /* pour cubic */ void set (int i, typeOfCell aCellType); /* pour hexa */ typeOfCell get (int i, int j); /* pour cubic */ typeOfCell get (int i); /* pour hexa */ void setCenter (typeOfCell cellToBuild); void emptyCenter (); void print (); /* debug */ void encode (); void decode (); int getCode (); void setCode (int aCode); int notEmptyCells (); double distanceFactor (double coeff1, double coeff2, double coeff3); PlanEnvironment rotate(); protected: typeOfCell cells[3][3]; int code; SimulationType simuType; }; /* Definition de la classe Environment Elle correspond a l'environnement d'une cellule et est composee de trois instances de la classe PlanEvironment, codees sous forme de trois entiers */ class Environment { public: Environment (SimulationType aSimuType); /* constructeur */ ~Environment (); /* destructeur */ void init (Architecture* initArch); void set (int x, int y, int z); void print (); /* debuggage */ int getTopCode (); int getMiddleCode (); int getBottomCode (); int setCode (int topCode, int middleCode, int bottomCode); void decode (); int notEmptyCells (); double distanceFactor (double coeff1, double coeff2, double coeff3); protected: SimulationType simuType; Architecture* arch; PlanEnvironment* top; PlanEnvironment* middle; PlanEnvironment* bottom; }; /* Definition de la classe Cell. Elle correspond à une cellule d'une architecture (le nid en construction). On y code le type de la cellule et le numero de la regle qui a conduit a sa creation */ class Cell { public: Cell(); ~Cell(); typeOfCell value (); int getAppliedRule (); int getCellId (); void set (typeOfCell setValue, int appliedRuleNumber, int aCellId); protected: typeOfCell val; int appliedRule; int cellId; }; /* Definition de la classe ViewParameters elle contient les parametres de la vue pour restaurer a chaque fois une meme vue */ class ViewParameters { public: ViewParameters (); ~ViewParameters (); position org; double zoom; double alpha; int tx; int ty; int zCut; double tetaCut; double phiCut; int isCut; }; /* statistiques d'application des regles */ struct RuleStats { int detRules; int probRules; int prob0_05Rules; int prob0_1Rules; int prob0_2Rules; int prob0_3Rules; int prob0_5Rules; int prob1_0Rules; }; /* Definition de la classe Architecture. Elle correspond au nid en construction et contient, outre les cellules de la construction, differentes variables de construction, telles que l'espace actif et les statistiques d'application des regles */ class Architecture { public: Architecture (int init_size, SimulationType aSimuType); ~Architecture(); typeOfCell getCellWithoutChecking (int x, int y, int z); typeOfCell getCellWithChecking (int x, int y, int z); int getAppliedRuleWithoutChecking (int x, int y, int z); void setCell (int x, int y, int z, typeOfCell cellValue, int appliedRule); void setCellWithNoChecking (int x, int y, int z, typeOfCell cellValue); void clearWithNoChecking (); void print(); int getSize (); void setEnvCode (int x, int y, int z); int getTopEnvCode (int x, int y, int z); int getMiddleEnvCode (int x, int y, int z); int getBottomEnvCode (int x, int y, int z); int simulate (RuleArray* anArray, int anIterationsNumber, int aMaxCells, learningMode typeOfLearning, int learningParam /* allowedFails or toBuidRulesNumber */, double noiseRate); /* retourne le nombre de cellules construites */ int learn (RuleArray* anArray, int numberOfRulesLoLearn, int mustRuleBeApplied); int learnOneRule (RuleArray* anArray, int mustRuleBeApplied); /* apply or not ? */ /* retourne 1 si on a pu apprendre une regle, sinon 0 */ void setStats (InfoBox* anInfoBox); void setViewInterface (ViewInterface* aViewInterface, int showCellsSteps); /* all this methods return 1 if OK, else 0 */ int saveArchitecture (char* aPathName, char* aFileName); int loadArchitecture (char* aPathName, char* aFileName); int savePreview (char* aPathName, char* aFileName, Display* aDisplay); int loadPreview (char* aPathName, char* aFileName, Display* aDisplay, Window* aWindow); void loadPreviewFromArch (Display* aDisplay, Window* aWindow, GC* aGC, unsigned long* aColorPointer, XFontStruct* aFontInfo); /* rules stats */ RuleStats getRuleStats (); long cellsNumber; long ruleOccurs[maxRules]; ViewParameters viewParameters; SimulationType simuType; /* gestion du pixmap de previsualisation */ Pixmap preview; Boolean pixmapInitialized; /* a 1 si initialise, sinon a 0 */ void initializePixmap (Display* aDisplay, Window aWindow, unsigned int aDepth); void setPixmap (Display* aDisplay, Pixmap aPixmap, GC aGC); void freePixmap (Display* aDisplay); /* le graphe associe a l'architecture */ Graph* graph; protected: int size; Cell* cells; int* envCode; int minX, maxX; int minY, maxY; int minZ, maxZ; /* des parametres utiles uniquement pour l'affichage de la fenetre de statistiques */ int showStats; InfoBox* infoBox; int showConstruction; ViewInterface* viewInterface; int showCellsSteps; RuleStats ruleStats; int matchRule (Position aPosition, RuleArray* aRuleArray, double* proba, double noiseRate); /* return the number of rules which matchs, -1 else */ double Architecture::dRuleEnv (int eTop, int eMiddle, int eBottom, int rTop, int rMiddle, int rBottom, int numberOfCellsInRule); /* return the distance between the rule and the current environment */ void applyRule (Position aPosition, Rule aRule, int ruleNumber); void initFirstCell (); void initRandomGenerator (); }; /* Definition de la classe Rule. Elle represente une regle (forme stimulante) applicable */ class Rule { public: Rule (SimulationType aSimuType); ~Rule (); void set (PlanEnvironment top, PlanEnvironment middle, PlanEnvironment bottom, typeOfCell cellToBuild); typeOfCell get (int x, int y, int z); /* pour cubic */ typeOfCell get (int plan, int cellNb); /* pour hexa */ void set (int x, int y, int z, typeOfCell aCellType); /* pour cubic */ void set (int plan, int cellNb, typeOfCell aCellType); /* pour hexa */ void set (Rule aRule); void rotate (); void print (int angle); int getTopCode (int angle); int getMiddleCode (int angle); int getBottomCode (int angle); /* angle: position de la regle */ typeOfCell getCellToBuild (); void setCellToBuild (typeOfCell centerCell); void randomGenerate (double pRedCell, double pYellowCell, RandomGenerationType randomGenerationType); void firstRuleRandomGenerate (); int checkConnectivity (); /* return 1 if connected else 0 */ int getInRuleCellNumber (); int isSamePerRotation (Rule* aRule); /* compare deux regles (en tenant compte des rotations) retourne 1 si pareilles, 0 sinon */ void setRuleClass (RuleClass aRuleClass); RuleClass getRuleClass (); SimulationType simuType; protected: RuleClass ruleClass; int facesNumber; /* 4 for cubic simulation, 6 for hexa simulation */ typeOfCell toBuild; int topCode[6]; int middleCode[6]; int bottomCode[6]; /* la valeur 6 correspond aux différentes rotations possibles, si le type de simulation est cubic, ben les 4 premiers sont suffisants */ }; /* utilisee pour la generation aleatoire de regles du mode "Spacial correlation generation" */ class GenRule : public Rule { public: GenRule (SimulationType aSimuType); ~GenRule (); void updateProba (int x, int y, int z); void setCell (int x, int y, int z, typeOfCell aCellType); /* positionne le type d'un cellule et remet a jour les probabilites des cellules adjascentes */ int probSet (int x, int y, int z, typeOfCell aCellType); /* positionne le type d'une cellule apres avoir effectue un test pour la construction, retourne 1 si la construction s'est faite, sinon 0 */ void setRule (Rule* aRule); protected: double pCell[3][3][3]; /* probabilite de construction d'une cellule */ int adjCells[3][3][3]; /* nombre de cellules adjascentes */ }; /* Definition de la classe TemplateRule utilisee pour la generation aleatoire de regles du mode "Probabilist Templates generation" */ class TemplateRule : public Rule { public: TemplateRule (SimulationType aSimuType, TemplateType aTemplateType, double pRedCell, double pYellowCell); ~TemplateRule (); void instanciate (); void setRule (Rule* aRule); protected: double gamma, betaRed, betaYellow; double pRed, pYellow; double pCellForRed[3][3][3]; double pCellForYellow[3][3][3]; /* probabilite de construction d'une cellule rouge ou jaune*/ void setPRedCell (int x, int y, int z, double aProba); void setPYellowCell (int x, int y, int z, double aProba); void setPRedPlane (int z, double p0, double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8); void setPYellowPlane (int z, double p0, double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8); void print (); /* debug */ void setCenterTemplate (); void setTopTemplate (); void setBottomTemplate (); void setSideTemplate (int anAngle); void setTopSideTemplate (int anAngle); void setBottomSideTemplate (int anAngle); }; /* Definition de la classe RuleArray. C'est l'ensemble des regles qui definissent une colonie */ class RuleArray { public: RuleArray(unsigned int max, SimulationType aSimuType); ~RuleArray(); void clear (); void print (); void debug (); unsigned int getElementsNb (); unsigned int getMaxElements (); SimulationType getSimuType (); void add (Rule aRule); void insert (Rule aRule, unsigned int i); void get (unsigned int i, Rule* aRule); Rule* get (unsigned int i); void del (unsigned int i); int saveInFile (char* aPathName, char* aFileName, double aFitness, char* aName, FileFormat aFileFormat); /* return 1 if OK, else 0 */ int loadFromFile (char* aPathName, char* aFileName, double* aMark,\ char* returnedName); /* return 1 if OK, else 0 */ void setFromOtherRuleArray (RuleArray* aRuleArray); void set (unsigned int i, Rule aRule); void randomGenerate (double pRedCell, double pYellowCell, double average, double variance, RandomGenerationType randomGenerationType); void randomInsert (int insertedRulesNumber, double pRedCell, double pYellowCell, RandomGenerationType randomGenerationType); /* the following functions return 1 when reading or writing is ok, 0 when error occurs, 2 when wrong format */ int readCubicRulData (char* aPathName, char* aFileName); int readCubicThrData (char* aPathName, char* aFileName); int readHexaRulData (char* aPathName, char* aFileName); int readHexaThrData (char* aPathName, char* aFileName); int writeCubicRulData (char* aPathName, char* aFileName, char* aName, double aFitness); int writeCubicThrData (char* aPathName, char* aFileName, char* aName, double aFitness); int writeHexaRulData (char* aPathName, char* aFileName, char* aName, double aFitness); int writeHexaThrData (char* aPathName, char* aFileName, char* aName, double aFitness); int removeFirstTwiceRule (); /* enleve la premiere regle en double trouvee et retourne 1 si pas de regle en double, retourne 0 */ void removeTwiceRules (double pRedCell, double pYellowCell, RandomGenerationType randomGenerationType); /* on enleve les regles en double et on regenere autant de regles qu'il le faut pour qu'il y ait autant de regles qu'avant */ unsigned int nbElements; protected: SimulationType simuType; unsigned int maxElements; Rule* element[maxRules]; }; /* Definition de la classe Position, utilisee lors de la simulation pour generer une serie aleatoire de positions (algo de type monte-carlo) */ class Position { public: int x, y, z; Position (int aSize); void randomPosition (int minX, int maxX, int minY, int maxY, int minZ, int maxZ); private: int size; }; /* Definition du type de generation aleatoire */ enum RandomModeType { PSEUDO, GAUSS, TRIVAL }; /* Definition de la classe RandomGenerator, qui permet de generer des nombres aleatoires selon differentes lois */ class RandomGenerator { public: RandomGenerator (RandomModeType aRandomMode, int aMin, int aMax); /* for a pseudo random distribution */ RandomGenerator (RandomModeType aRandomMode, int aMin, int aMax, double anAverage, double aVariance); /* for a gauss distribution */ RandomGenerator (RandomModeType aRandomMode, double ap1, double ap2, double ap3, int aMin, int aMax); /* for a three values distribution */ ~RandomGenerator (); int getNumber (); protected: int min; int max; RandomModeType randomMode; double average; double variance; double p1, p2, p3; void initGenerator (); }; #endif