/****************************************************************** * * * 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 : graph.h Component : fitness evaluation Fonctionality : contains specifications for class Graph and GraphNode ******************************************************************/ #ifndef __graph_H #define __graph_H #include "config.h" #include "algo.h" #include "pattern.h" #include "graphical.h" class Graph; class GraphNode; class Sequences; enum InOutType { Input, Output }; /* cette classe memorise des stats sur des sequences d'enchainement de regles */ class Sequences { public: Sequences (); ~Sequences (); void addData (int aData); int numberOfDatas (); int mini (); int maxi (); double average (); protected: int total; int dataNumber; int miniValue; int maxiValue; double averageValue; }; class GraphNode { public: GraphNode (); ~GraphNode (); void initGraph (Graph* aGraph); void set (int aRuleIndex, int aNodeIndex); int inputEdgesNumber (); int outputEdgesNumber (); int indexOfNeighbour (int aPosCode); /* return -1 when not available */ InOutType directionOfNeighbour (int aPosCode); int indexOfInputNeighbour (int anIndex); /* return -1 when not available */ int indexOfOutputNeighbour (int anIndex); /* return -1 when not available */ GraphNode* inputNeighbour (int anIndex); /* return nil when not available */ GraphNode* outputNeighbour (int anIndex); /* return nil when not available */ void addInputEdge (int posCode, int nodeIndex); void addOutputEdge (int posCode, int nodeIndex); double getPx (); double getPy (); void setPx (double newPx); void setPy (double newPy); int getNodeId (); int getRuleId (); void debug(); typeOfCell cellType; int x, y, z; /* calcul des sequences */ int exploredAtLength; /* explore avec la longueur */ int foundLength; /* longueur trouvee */ int sequencesNumber; int sequencesLength[defaultMaxCells]; void initSequences (); void searchSequences (GraphNode* firstNode, int searchedRuleId, int length); void debugSequences (); /* patterns */ Pattern* pattern; int belongsToPattern; int isPatternInitialized; void initPattern (int aMaxSize); void freePattern (); int searchPattern (GraphNode* firstNode, int length); protected: Graph* graph; int ruleIndex; /* no de la regle, -1 si cellule initiale */ int nodeIndex; /* numero de la cellule, -1 si pas construite encore */ int neighbour[26]; InOutType inOut[26]; /* tous les voisins potentiels de cette cellule */ /* il y en aura 26 si cubic, 20 si hexa */ /* les premiers pour top, puis middle, puis bottom */ /* si l'arete existe -> index du noeud, sinon -1 */ double px, py; /* coordonnees dans le plan (representation du graphe */ int numberOfInputEdges; int numberOfOutputEdges; }; /* en cubic: | TOP MIDDLE BOTTOM | ---------------- | ---------------- | ---------------- | | 00 | 01 | 02 | | | 09 | 10 | 11 | | | 17 | 18 | 19 | | ---------------- | ---------------- | ---------------- | | 03 | 04 | 05 | | | 12 | | 13 | | | 20 | 21 | 22 | | ---------------- | ---------------- | ---------------- | | 06 | 07 | 08 | | | 14 | 15 | 16 | | | 23 | 24 | 25 | | ---------------- | ---------------- | ---------------- | | posCode (start) = 25-posCode (end) */ /* en hexa: | TOP MIDDLE BOTTOM | ____ | ____ | ____ | ____/ 01 \____ | ____/ 07 \____ | ____/ 15 \____ | / 02 \____/ 06 \ | / 08 \____/ 09 \ | / 14 \____/ 16 \ | \____/ 00 \____/ | \____/ \____/ | \____/ 19 \____/ | / 03 \____/ 05 \ | / 10 \____/ 11 \ | / 13 \____/ 17 \ | \____/ 04 \____/ | \____/ 12 \____/ | \____/ 18 \____/ | \____/ | \____/ | \____/ | | posCode (start) = 19-posCode (end) */ class Graph { public: Graph (SimulationType aSimuType, int aMaxCells, int anArchSize); ~Graph (); GraphNode* nodeAtIndex (int aNodeId); void addNode (int aRuleIndex, typeOfCell aCellType, int x, int y, int z); void addEdge (int startNodeId, int endNodeId, int posCode); /* le posCode est ici celui du endNode, celui du startNode etant deduit facilement par les formules ci-dessus */ /* _ _ |_|------>|_| startNode endNode (output) (input) */ int posCodeCubic (int x, int y, int z); /* retourne le posCode associe a (x, y, z) x,y,z appart. (-1, 0, 1) */ int posCodeHexa (int x, int y, int z, int decX); /* en hexa, les cellules environnantes sont differentes selon si x est pair ou impair */ int getNodesNumber (); int getEdgesNumber (); SimulationType getSimuType (); /* matrice de co-occurrences et algo de classification */ void classifyRules (RuleArray* aRuleArray); void displayCooccurenceMatrix (); void displayCooccurenceMatrix (RuleArray* aRuleArray); /* cet affichage tient compte de la classif effectuee */ /* debug du graphe */ void debug(); /* algo de kohonen (visualisation du graphe) */ int getCurrentIt (); int getMaxIt (); double getEpsilon1 (); double getEpsilon2 (); void setMaxIt (int aInt); void setCurrentIt (int aInt); void resetKohonen (); /* reset des variables de kohonen */ void computeKohonenIteration (); /* calcule 1 iteration de kohonen */ void computeKohonen (); /* calcule tout kohonen */ /* calcul des sequences de regles */ /* idee abandonnee en cours de developpement: a priori ne mene pas a grand chose */ void initRulesSequences (); void computeRulesSequences (); /* patterns */ void computePatterns (InfoBox* anInfoBox); /* si infoBox est NULL, pas d'affichage des stats */ void freeAllPatterns (); void computePatternMatching (InfoBox* anInfoBox); /* si infoBox est NULL, pas d'affichage des stats */ int patternsNumber; Pattern** patternList; /* fitness */ double getComplexityFitness (); double getCoherenceFitness (); int isComplexityComputed; int isCoherenceComputed; int arePatternsComputed; int isPatternMatchingDone; protected: SimulationType simuType; /* type cubic/hexa */ GraphNode** node; int archSize; int nodesNumber; int edgesNumber; int maxCells; int pCode[3][3][3]; int p1Code[3][3][3]; int p2Code[3][3][3]; int used[maxRules+1]; int cooccurence[maxRules+1][maxRules+1]; int maxRulesIndex; /* index max de la derniere regle utilisee */ /* les fitness associees au graphe */ double complexityFitness; double coherenceFitness; /* algo de kohonen (visualisation du graphe) */ int currentIteration; int maxIterations; double epsilon1; double epsilon2; double k1, k2; double D; void updateEpsilon1 (); void updateEpsilon2 (); /* epsilon1 = k1.(1-t/maxIterations) (pour les noeuds) epsilon2 = k2.(1-t/maxIterations) (pour les voisins) avec k1 = 0.15 et k2 = 0.3 a maxIteration/3, epsilon2 = k2.e-(d/D) d: distance entre la nlle pos du noeud et le noeud voisin D: distance critique (largeur_plan/10) */ }; #endif