Changeset 196
- Timestamp:
- 03/25/14 03:22:37 (12 years ago)
- Location:
- cpp
- Files:
-
- 1 added
- 2 deleted
- 4 edited
- 6 moved
-
README.txt (modified) (2 diffs)
-
_old/f4/f4_orientmat.cpp (deleted)
-
_old/f4/f4_orientmat.h (deleted)
-
common/stl-util.cpp (modified) (1 diff)
-
frams/Makefile-GDK-files (modified) (2 diffs)
-
frams/genetics/f4 (added)
-
frams/genetics/f4/conv_f4.cpp (moved) (moved from cpp/_old/f4/conv_f4.cpp) (8 diffs)
-
frams/genetics/f4/conv_f4.h (moved) (moved from cpp/_old/f4/conv_f4.h) (1 diff)
-
frams/genetics/f4/f4_general.cpp (moved) (moved from cpp/_old/f4/f4_general.cpp) (20 diffs)
-
frams/genetics/f4/f4_general.h (moved) (moved from cpp/_old/f4/f4_general.h) (6 diffs)
-
frams/genetics/f4/oper_f4.cpp (moved) (moved from cpp/_old/f4/geno_f4.cpp) (12 diffs)
-
frams/genetics/f4/oper_f4.h (moved) (moved from cpp/_old/f4/geno_f4.h) (2 diffs)
-
frams/genetics/gen-config-GDK.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cpp/README.txt
r194 r196 11 11 ___________________________ Source directories __________________________ 12 12 13 +- common - general compatibility layer &utilities13 +- common - general compatibility layer, utilities 14 14 +- frams - framsticks modules 15 15 +- _demos - GDK test applications … … 18 18 +- genetics - genetic operators and converters between formats 19 19 +- f1 - ...for genetic format f1 (recurrent encoding) 20 +- f9 - ...for genetic format f9 (3D turtle) 21 +- fF - ...for genetic format fF (Foraminifera) 20 +- f4 - ...for genetic format f4 (developmental encoding) 21 +- f9 - ...for genetic format f9 (3D turtle encoding) 22 +- fF - ...for genetic format fF (Foraminifera encoding) 22 23 +- fT - ...for genetic format fT (educational: ATGC sequences) 23 24 +- model - parts, joints, neurons, connections -
cpp/common/stl-util.cpp
r180 r196 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 1 5 #include "stl-util.h" 2 6 #include <stdarg.h> -
cpp/frams/Makefile-GDK-files
r194 r196 4 4 ALL_DIRS={common,frams,frams/canvas,frams/config,frams/errmgr,frams/genetics,frams/genetics/f0,frams/genetics/f1,frams/genetics/f2,frams/genetics/f3,frams/genetics/f4,frams/genetics/f5,frams/genetics/f6,frams/genetics/f7,frams/genetics/f8,frams/genetics/f9,frams/genetics/fF,frams/genetics/fT,frams/model,frams/neuro,frams/neuro/impl,frams/param,frams/test,frams/util,frams/vm/classes,frams/virtfile,frams/_demos,frams/model/geometry,frams/_demos/geometry} 5 5 6 GENMANF4=frams/genetics/f4/oper_f4.o 6 7 GENMANF9=frams/genetics/f9/oper_f9.o 7 8 GENMANFF=frams/genetics/fF/oper_fF.o … … 9 10 10 11 CONVF1=frams/genetics/f1/conv_f1.o 12 CONVF4=frams/genetics/f4/conv_f4.o frams/genetics/f4/f4_general.o 11 13 CONVF9=frams/genetics/f9/conv_f9.o 12 14 CONVFF=frams/genetics/fF/conv_fF.o frams/genetics/fF/fF_genotype.o frams/genetics/fF/fF_chamber3d.o 13 15 14 GENOCONV_GDK_OBJS=frams/genetics/defgenoconv.o $(CONVF1) $(CONVF 9) $(CONVFF)15 GENMAN_GDK_OBJS=$(GENMAN_COMMON_OBJS) $(GENMANF 9) $(GENMANFF) $(GENMANFT)16 GENOCONV_GDK_OBJS=frams/genetics/defgenoconv.o $(CONVF1) $(CONVF4) $(CONVF9) $(CONVFF) 17 GENMAN_GDK_OBJS=$(GENMAN_COMMON_OBJS) $(GENMANF4) $(GENMANF9) $(GENMANFF) $(GENMANFT) 16 18 17 19 GENMAN_COMMON_OBJS=frams/genetics/genman.o frams/param/mutableparam.o frams/param/mutparamlist.o frams/neuro/geneticneuroparam.o frams/neuro/neurolibparam.o frams/vm/classes/genoobj.o frams/model/autoname.o -
cpp/frams/genetics/f4/conv_f4.cpp
r193 r196 1 /** 2 * conv_f4.cpp - f4 genotype functions. 3 * 4 * f4genotype - f4 format genotype conversions for Framsticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * Copyright (C) 2001-2003 Maciej Komosinski 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 // Copyright (C) since 2001 Maciej Komosinski 24 7 25 8 #include "conv_f4.h" 26 #include "framsg.h"27 #include " geno_fx.h" //for GENOPER_OK constant9 #include <common/framsg.h> 10 #include "../oper_fx.h" //for GENOPER_OK constant 28 11 29 12 #ifdef DMALLOC … … 32 15 33 16 34 GenoConv_F40::GenoConv_F40() 35 { 36 name = "f4 converter"; 37 in_format = '4'; 38 out_format = '0'; 39 mapsupport = 1; 40 info = "Developmental encoding"; 41 } 42 43 44 SString GenoConv_F40::convert(SString &in, MultiMap * map) 45 { 46 int res; 47 f4_Model * model = new f4_Model(); 48 res = model->buildFromF4(in); 49 if (GENOPER_OK != res) return SString(); // oops 50 if (NULL != map) 51 // generate to-f0 conversion map 52 model->getCurrentToF0Map(*map); 53 SString out = model->getF0Geno().getGene(); 54 delete model; 55 return out; 17 GenoConv_f40::GenoConv_f40() 18 { 19 name = "Developmental encoding"; 20 in_format = '4'; 21 out_format = '0'; 22 mapsupport = 1; 23 } 24 25 26 SString GenoConv_f40::convert(SString &in, MultiMap * map) 27 { 28 int res; 29 f4_Model * model = new f4_Model(); 30 res = model->buildFromF4(in); 31 if (GENOPER_OK != res) return SString(); // oops 32 if (NULL != map) 33 // generate to-f0 conversion map 34 model->getCurrentToF0Map(*map); 35 SString out = model->getF0Geno().getGene(); 36 delete model; 37 return out; 56 38 } 57 39 … … 59 41 GenoConv_F41_TestOnly::GenoConv_F41_TestOnly() 60 42 { 61 name = "test-only approximate f4 -> f0converter";62 in_format= '4';63 out_format = '1';64 mapsupport = 0;65 info = "This is for testing. Do not use in production! (adam)";43 name = "test-only approximate f4 -> f1 converter"; 44 in_format = '4'; 45 out_format = '1'; 46 mapsupport = 0; 47 info = "This is for testing. Do not use in production! (adam)"; 66 48 } 67 49 … … 69 51 SString GenoConv_F41_TestOnly::convert(SString &in, MultiMap * map) 70 52 { 71 int res;72 f4_Model * model = new f4_Model();73 res = model->buildFromF4(in);74 if (GENOPER_OK != res) return SString(); // oops75 SString out;76 model->toF1Geno(out);77 delete model;78 return out;53 int res; 54 f4_Model * model = new f4_Model(); 55 res = model->buildFromF4(in); 56 if (GENOPER_OK != res) return SString(); // oops 57 SString out; 58 model->toF1Geno(out); 59 delete model; 60 return out; 79 61 } 80 62 … … 82 64 f4_Model::f4_Model() : Model() 83 65 { 84 cells = NULL;66 cells = NULL; 85 67 } 86 68 87 69 f4_Model::~f4_Model() 88 70 { 89 if (cells) delete cells;71 if (cells) delete cells; 90 72 } 91 73 92 74 int f4_Model::buildFromF4(SString &geno) 93 75 { 94 int i;95 96 error = GENOPER_OK;97 errorpos = -1;98 99 // build cells, and simulate100 if (cells) delete cells;101 cells = new f4_Cells(geno, 0);102 if (GENOPER_OK != cells->geterror())103 {104 error = cells->geterror();105 errorpos = cells->geterrorpos();106 //delete cells;107 return error;108 }109 110 cells->simulate();111 if (GENOPER_OK != cells->geterror())112 {113 error = cells->geterror();114 errorpos = cells->geterrorpos();115 return error;116 }117 118 // reset recursive traverse flags119 for(i=0; i<cells->nc; i++)120 cells->C[i]->recProcessedFlag = 0;121 122 open(); // begin model build123 124 // process every cell125 int res;126 for(i=0; i<cells->nc; i++)127 {128 res = buildModelRec(cells->C[i]);129 if (res)130 {131 FramMessage("f4_Model", "buildModelRec", "Error in building Model", 2);132 error = res;133 break;134 }135 }136 137 res = close();138 if (0 == res) // invalid139 error = -10;140 141 return error;76 int i; 77 78 error = GENOPER_OK; 79 errorpos = -1; 80 81 // build cells, and simulate 82 if (cells) delete cells; 83 cells = new f4_Cells(geno, 0); 84 if (GENOPER_OK != cells->geterror()) 85 { 86 error = cells->geterror(); 87 errorpos = cells->geterrorpos(); 88 //delete cells; 89 return error; 90 } 91 92 cells->simulate(); 93 if (GENOPER_OK != cells->geterror()) 94 { 95 error = cells->geterror(); 96 errorpos = cells->geterrorpos(); 97 return error; 98 } 99 100 // reset recursive traverse flags 101 for (i = 0; i < cells->nc; i++) 102 cells->C[i]->recProcessedFlag = 0; 103 104 open(); // begin model build 105 106 // process every cell 107 int res; 108 for (i = 0; i < cells->nc; i++) 109 { 110 res = buildModelRec(cells->C[i]); 111 if (res) 112 { 113 FramMessage("f4_Model", "buildModelRec", "Error in building Model", 2); 114 error = res; 115 break; 116 } 117 } 118 119 res = close(); 120 if (0 == res) // invalid 121 error = -10; 122 123 return error; 142 124 } 143 125 … … 145 127 f4_Cell * f4_Model::getStick(f4_Cell * C) 146 128 { 147 if (T_STICK4 == C->type) return C;148 if (NULL != C->dadlink)149 return getStick(C->dadlink);150 // we have no more dadlinks, find any stick151 for (int i=0; i<cells->nc; i++)152 if (cells->C[i]->type == T_STICK4)153 return cells->C[i];154 // none!155 FramMessage("f4_Model", "getStick", "Not a single stick", 2);156 return NULL;129 if (T_STICK4 == C->type) return C; 130 if (NULL != C->dadlink) 131 return getStick(C->dadlink); 132 // we have no more dadlinks, find any stick 133 for (int i = 0; i < cells->nc; i++) 134 if (cells->C[i]->type == T_STICK4) 135 return cells->C[i]; 136 // none! 137 FramMessage("f4_Model", "getStick", "Not a single stick", 2); 138 return NULL; 157 139 } 158 140 … … 161 143 int f4_Model::buildModelRec(f4_Cell * C) 162 144 { 163 int partidx; 164 int j, res; 165 MultiRange range; 166 167 if (C->recProcessedFlag) 168 // already processed 169 return 0; 170 171 // mark it processed 172 C->recProcessedFlag = 1; 173 174 // make sure parent is a stick 175 if (NULL != C->dadlink) 176 if (C->dadlink->type != T_STICK4) 177 { 178 C->dadlink = getStick(C->dadlink); 179 } 180 181 // make sure its parent is processed first 182 if (NULL != C->dadlink) 183 { 184 res = buildModelRec(C->dadlink); 185 if (res) return res; 186 } 187 188 char tmpLine[100]; 189 190 range = C->genoRange; 191 if (C->type == T_STICK4) 192 { 193 int jj_p1_refno; // save for later 194 // first end is connected to dad, or new 195 if (C->dadlink == NULL) 196 { 197 // new part object for firstend 198 // coordinates are left to be computed by Model 199 sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g", 200 /*1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim 201 //C->firstend.x, C->firstend.y, C->firstend.z 202 ); 203 partidx = singleStepBuild(tmpLine, &range ); 204 if (partidx < 0) return -1; 205 jj_p1_refno = partidx; 206 } else { 207 // adjust mass/vol of first endpoint 208 jj_p1_refno = C->dadlink->p2_refno; 209 Part * p1 = getPart(jj_p1_refno); 210 p1->mass += 1.0; 211 // p1->volume += 1.0/C->P.mass; 212 } 213 // new part object for lastend 214 sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g", 215 //C->lastend.x, C->lastend.y, C->lastend.z 216 /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim 217 ); 218 partidx = singleStepBuild(tmpLine, &range ); 219 if (partidx < 0) return -2; 220 C->p2_refno = partidx; 221 222 // new joint object 223 // check that the part references are valid 224 int jj_p2_refno = C->p2_refno; 225 if ((jj_p1_refno < 0) || (jj_p1_refno >= getPartCount())) return -11; 226 if ((jj_p2_refno < 0) || (jj_p2_refno >= getPartCount())) return -12; 227 sprintf(tmpLine, "j:p1=%ld,p2=%ld,dx=%g,dy=0,dz=0,rx=%g,ry=0,rz=%g"\ 228 ",stam=%g", 229 jj_p1_refno, jj_p2_refno, 230 // relative position -- always (len, 0, 0), along the stick 231 // this is optional! 232 C->P.len, 233 // relative rotation 234 C->xrot, C->zrot, 235 //C->P.ruch, // rotstif 236 C->P.odpor 237 ); 238 partidx = singleStepBuild(tmpLine, &range ); 239 if (partidx < 0) return -13; 240 C->joint_refno = partidx; 241 } 242 243 if (C->type == T_NEURON4) ///<this case was updated by MacKo 244 { 245 // new neuron object 246 // it is linked to a part (not a joint!) 247 int p_refno = C->dadlink->p2_refno; 248 if ((p_refno < 0) || (p_refno >= getPartCount())) return -21; 249 // joint_refno is currently not used 250 sprintf(tmpLine, "n:p=%ld,d=\"N:in=%g,fo=%g,si=%g\"", 251 p_refno, 252 C->inertia, C->force, C->sigmo); 253 partidx = singleStepBuild(tmpLine, &range ); 254 if (partidx < 0) return -22; 255 C->neuro_refno = partidx; 256 int n_refno = C->neuro_refno; 257 258 if (C->ctrl) 259 { 260 if (1 == C->ctrl) 261 sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.ruch); 262 else 263 sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"",C->dadlink->joint_refno, C->P.ruch, C->mz); 264 partidx = singleStepBuild(tmpLine, &range ); 265 if (partidx < 0) return -32; 266 sprintf(tmpLine, "c:%d,%d",partidx,n_refno); 267 if (singleStepBuild(tmpLine, &range )<0) return -33; 268 } 269 270 for (j=0; j<C->nolink; j++) 271 { 272 if (NULL != C->links[j]->from) 273 buildModelRec(C->links[j]->from); 274 275 tmpLine[0]=0; 276 if (1 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"*\"",p_refno); 277 if (2 == C->links[j]->t) sprintf(tmpLine, "n:j=%d,d=\"G\"", C->dadlink->joint_refno); 278 if (3 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"T\"",p_refno); 279 if (4 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"S\"",p_refno); 280 int from=-1; 281 if (tmpLine[0]) //input from receptor 282 { 283 from=singleStepBuild(tmpLine, &range ); 284 if (from<0) return -34; 285 } /*could be 'else'...*/ 286 if (NULL != C->links[j]->from) // input from another neuron 287 from=C->links[j]->from->neuro_refno; 288 if (from>=0) 289 { 290 sprintf(tmpLine, "c:%d,%d,%g", n_refno,from,C->links[j]->w); 291 if (singleStepBuild(tmpLine, &range ) < 0) return -35; 292 } 293 } 294 } 295 return 0; 145 int partidx; 146 int j, res; 147 MultiRange range; 148 149 if (C->recProcessedFlag) 150 // already processed 151 return 0; 152 153 // mark it processed 154 C->recProcessedFlag = 1; 155 156 // make sure parent is a stick 157 if (NULL != C->dadlink) 158 if (C->dadlink->type != T_STICK4) 159 { 160 C->dadlink = getStick(C->dadlink); 161 } 162 163 // make sure its parent is processed first 164 if (NULL != C->dadlink) 165 { 166 res = buildModelRec(C->dadlink); 167 if (res) return res; 168 } 169 170 char tmpLine[100]; 171 172 range = C->genoRange; 173 if (C->type == T_STICK4) 174 { 175 int jj_p1_refno; // save for later 176 // first end is connected to dad, or new 177 if (C->dadlink == NULL) 178 { 179 // new part object for firstend 180 // coordinates are left to be computed by Model 181 sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g", 182 /*1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim 183 //C->firstend.x, C->firstend.y, C->firstend.z 184 ); 185 partidx = singleStepBuild(tmpLine, &range); 186 if (partidx < 0) return -1; 187 jj_p1_refno = partidx; 188 } 189 else { 190 // adjust mass/vol of first endpoint 191 jj_p1_refno = C->dadlink->p2_refno; 192 Part * p1 = getPart(jj_p1_refno); 193 p1->mass += 1.0; 194 // p1->volume += 1.0/C->P.mass; 195 } 196 // new part object for lastend 197 sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g", 198 //C->lastend.x, C->lastend.y, C->lastend.z 199 /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim 200 ); 201 partidx = singleStepBuild(tmpLine, &range); 202 if (partidx < 0) return -2; 203 C->p2_refno = partidx; 204 205 // new joint object 206 // check that the part references are valid 207 int jj_p2_refno = C->p2_refno; 208 if ((jj_p1_refno < 0) || (jj_p1_refno >= getPartCount())) return -11; 209 if ((jj_p2_refno < 0) || (jj_p2_refno >= getPartCount())) return -12; 210 sprintf(tmpLine, "j:p1=%ld,p2=%ld,dx=%g,dy=0,dz=0,rx=%g,ry=0,rz=%g"\ 211 ",stam=%g", 212 jj_p1_refno, jj_p2_refno, 213 // relative position -- always (len, 0, 0), along the stick 214 // this is optional! 215 C->P.len, 216 // relative rotation 217 C->xrot, C->zrot, 218 //C->P.ruch, // rotstif 219 C->P.odpor 220 ); 221 partidx = singleStepBuild(tmpLine, &range); 222 if (partidx < 0) return -13; 223 C->joint_refno = partidx; 224 } 225 226 if (C->type == T_NEURON4) ///<this case was updated by MacKo 227 { 228 // new neuron object 229 // it is linked to a part (not a joint!) 230 int p_refno = C->dadlink->p2_refno; 231 if ((p_refno < 0) || (p_refno >= getPartCount())) return -21; 232 // joint_refno is currently not used 233 sprintf(tmpLine, "n:p=%ld,d=\"N:in=%g,fo=%g,si=%g\"", 234 p_refno, 235 C->inertia, C->force, C->sigmo); 236 partidx = singleStepBuild(tmpLine, &range); 237 if (partidx < 0) return -22; 238 C->neuro_refno = partidx; 239 int n_refno = C->neuro_refno; 240 241 if (C->ctrl) 242 { 243 if (1 == C->ctrl) 244 sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.ruch); 245 else 246 sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P.ruch, C->mz); 247 partidx = singleStepBuild(tmpLine, &range); 248 if (partidx < 0) return -32; 249 sprintf(tmpLine, "c:%d,%d", partidx, n_refno); 250 if (singleStepBuild(tmpLine, &range) < 0) return -33; 251 } 252 253 for (j = 0; j < C->nolink; j++) 254 { 255 if (NULL != C->links[j]->from) 256 buildModelRec(C->links[j]->from); 257 258 tmpLine[0] = 0; 259 if (1 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"*\"", p_refno); 260 if (2 == C->links[j]->t) sprintf(tmpLine, "n:j=%d,d=\"G\"", C->dadlink->joint_refno); 261 if (3 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"T\"", p_refno); 262 if (4 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"S\"", p_refno); 263 int from = -1; 264 if (tmpLine[0]) //input from receptor 265 { 266 from = singleStepBuild(tmpLine, &range); 267 if (from < 0) return -34; 268 } /*could be 'else'...*/ 269 if (NULL != C->links[j]->from) // input from another neuron 270 from = C->links[j]->from->neuro_refno; 271 if (from >= 0) 272 { 273 sprintf(tmpLine, "c:%d,%d,%g", n_refno, from, C->links[j]->w); 274 if (singleStepBuild(tmpLine, &range) < 0) return -35; 275 } 276 } 277 } 278 return 0; 296 279 } 297 280 … … 299 282 void f4_Model::toF1Geno(SString &out) 300 283 { 301 cells->toF1Geno(out); 302 } 303 304 284 cells->toF1Geno(out); 285 } -
cpp/frams/genetics/f4/conv_f4.h
r193 r196 1 /** 2 * conv_f4.h - f4 conversion functions. 3 * 4 * f4genotype - f4 format genotype conversions for FramSticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * Copyright (C) 2001-2003 Maciej Komosinski 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 // Copyright (C) since 2001 Maciej Komosinski 24 7 25 8 #ifndef _CONV_F4_H_ 26 9 #define _CONV_F4_H_ 27 10 28 #include "model.h"29 #include "modelparts.h"30 #include "genoconv.h"11 #include <frams/model/model.h> 12 #include <frams/model/modelparts.h> 13 #include <frams/genetics/genoconv.h> 31 14 #include "f4_general.h" 32 15 33 16 34 17 // The f4->f0 converter 35 class GenoConv_ F40: public GenoConverter18 class GenoConv_f40 : public GenoConverter 36 19 { 37 public:38 GenoConv_F40();39 SString convert(SString &in, MultiMap * map);20 public: 21 GenoConv_f40(); 22 SString convert(SString &in, MultiMap * map); 40 23 }; 41 24 42 25 43 26 // a test-only f4->f1 converter, approximates only 44 class GenoConv_F41_TestOnly : public GenoConverter27 class GenoConv_F41_TestOnly : public GenoConverter 45 28 { 46 public:47 GenoConv_F41_TestOnly();48 SString convert(SString &in, MultiMap * map);29 public: 30 GenoConv_F41_TestOnly(); 31 SString convert(SString &in, MultiMap * map); 49 32 }; 50 33 51 34 52 35 // A Model descendant, which support build from an f4 genotype. 53 class f4_Model : public Model36 class f4_Model : public Model 54 37 { 55 public:56 f4_Model();57 ~f4_Model();58 int buildFromF4(SString &geno);59 void toF1Geno(SString &out); // output to f1 format, approximation60 private:61 f4_Cells * cells;62 int buildModelRec(f4_Cell * ndad);63 /**64 * Get a cell which is a stick, by traversing dadlinks.65 */66 f4_Cell * getStick(f4_Cell * C);67 int error;68 int errorpos;38 public: 39 f4_Model(); 40 ~f4_Model(); 41 int buildFromF4(SString &geno); 42 void toF1Geno(SString &out); // output to f1 format, approximation 43 private: 44 f4_Cells * cells; 45 int buildModelRec(f4_Cell * ndad); 46 /** 47 * Get a cell which is a stick, by traversing dadlinks. 48 */ 49 f4_Cell * getStick(f4_Cell * C); 50 int error; 51 int errorpos; 69 52 }; 70 53 71 54 72 55 #endif 73 -
cpp/frams/genetics/f4/f4_general.cpp
r193 r196 1 /* 2 * f4_general.cpp - f4 genotype functions. 3 * 4 * f4genotype - f4 format genotype conversions for FramSticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 // Copyright (C) since 2001 Maciej Komosinski 23 7 24 8 #include "f4_general.h" 25 #include "nonstd.h"26 #include "framsg.h"27 #include "model.h"// for min and max attributes28 #include " geno_fx.h" //for GENOPER_ constants9 #include <common/nonstd_stl.h> 10 #include <common/framsg.h> 11 #include <frams/model/model.h> // for min and max attributes 12 #include "../oper_fx.h" //for GENOPER_ constants 29 13 #include <stdio.h> 30 #include < math.h>14 #include <common/nonstd_math.h> 31 15 32 16 #ifdef DMALLOC … … 37 21 f4_Props::f4_Props() 38 22 { 39 len= 1.0;40 curv= 0.0;41 mass = 1.0; 42 friction = 0.4;43 ruch= 0.25; // bio44 assim= 0.25; // bio45 odpor= 0.25; // bio46 ingest= 0.25; // bio47 twist= 0.0;48 energ= 1.0;49 normalizeBiol4();23 len = 1.0; 24 curv = 0.0; 25 mass = 1.0; 26 friction = 0.4; 27 ruch = 0.25; // bio 28 assim = 0.25; // bio 29 odpor = 0.25; // bio 30 ingest = 0.25; // bio 31 twist = 0.0; 32 energ = 1.0; 33 normalizeBiol4(); 50 34 } 51 35 52 36 void f4_Props::normalizeBiol4() 53 37 { 54 // must sum to 1 55 double sum = ruch + assim + odpor + ingest; 56 if (0 == sum) 57 { 58 ruch = assim = odpor = ingest = 0.25; 59 } else { 60 ruch /= sum; 61 assim /= sum; 62 odpor /= sum; 63 ingest /= sum; 64 } 38 // must sum to 1 39 double sum = ruch + assim + odpor + ingest; 40 if (0 == sum) 41 { 42 ruch = assim = odpor = ingest = 0.25; 43 } 44 else { 45 ruch /= sum; 46 assim /= sum; 47 odpor /= sum; 48 ingest /= sum; 49 } 65 50 } 66 51 67 52 void f4_Props::executeModifier(char modif) 68 53 { 69 switch (modif)70 {71 case 'L': len += (2.5 - len) * 0.3;72 len = min(len, Model::getMaxJoint().d.x); break;73 case 'l': len += (0.3 - len) * 0.3;74 len = max(len, Model::getMinJoint().d.x); break;75 case 'C': curv += (2.0 - curv) * 0.25; break;76 case 'c': curv += (-2.0 - curv) * 0.25; break;77 case 'Q': twist += (1.58 - twist) * 0.3; break;78 case 'q': twist += (-1.58 - twist) * 0.3; break;79 case 'A': assim += (1 - assim) * 0.8; normalizeBiol4(); break;80 case 'a': assim -= assim * 0.4; normalizeBiol4(); break;81 case 'I': ingest += (1 - ingest) * 0.8; normalizeBiol4(); break;82 case 'i': ingest -= ingest * 0.4; normalizeBiol4(); break;83 case 'S': odpor += (1 - odpor) * 0.8; normalizeBiol4(); break;84 case 's': odpor -= odpor * 0.4; normalizeBiol4(); break;85 case 'M': ruch += (1 - ruch) * 0.8; normalizeBiol4(); break;86 case 'm': ruch -= ruch * 0.4; normalizeBiol4(); break;87 case 'F': friction += (4 - friction) * 0.2; break;88 case 'f': friction -= friction * 0.2; break;89 case 'W': mass += (2.0 - mass) * 0.3; break;90 case 'w': mass += (0.5 - mass) * 0.3; break;91 case 'E': energ += (10.0 - energ) * 0.1; break;92 case 'e': energ -= energ * 0.1; break;93 }54 switch (modif) 55 { 56 case 'L': len += (2.5 - len) * 0.3; 57 len = min(len, Model::getMaxJoint().d.x); break; 58 case 'l': len += (0.3 - len) * 0.3; 59 len = max(len, Model::getMinJoint().d.x); break; 60 case 'C': curv += (2.0 - curv) * 0.25; break; 61 case 'c': curv += (-2.0 - curv) * 0.25; break; 62 case 'Q': twist += (1.58 - twist) * 0.3; break; 63 case 'q': twist += (-1.58 - twist) * 0.3; break; 64 case 'A': assim += (1 - assim) * 0.8; normalizeBiol4(); break; 65 case 'a': assim -= assim * 0.4; normalizeBiol4(); break; 66 case 'I': ingest += (1 - ingest) * 0.8; normalizeBiol4(); break; 67 case 'i': ingest -= ingest * 0.4; normalizeBiol4(); break; 68 case 'S': odpor += (1 - odpor) * 0.8; normalizeBiol4(); break; 69 case 's': odpor -= odpor * 0.4; normalizeBiol4(); break; 70 case 'M': ruch += (1 - ruch) * 0.8; normalizeBiol4(); break; 71 case 'm': ruch -= ruch * 0.4; normalizeBiol4(); break; 72 case 'F': friction += (4 - friction) * 0.2; break; 73 case 'f': friction -= friction * 0.2; break; 74 case 'W': mass += (2.0 - mass) * 0.3; break; 75 case 'w': mass += (0.5 - mass) * 0.3; break; 76 case 'E': energ += (10.0 - energ) * 0.1; break; 77 case 'e': energ -= energ * 0.1; break; 78 } 94 79 } 95 80 96 81 void f4_Props::adjust() 97 82 { 98 len = 0.5*len + 0.5*stdProps.len;99 curv = 0.66 * curv;100 twist = 0.66 * twist;83 len = 0.5*len + 0.5*stdProps.len; 84 curv = 0.66 * curv; 85 twist = 0.66 * twist; 101 86 } 102 87 … … 105 90 106 91 void rolling_dec(double * v) { 107 *v -= 0.7853; // 0.7853981 45 degrees92 *v -= 0.7853; // 0.7853981 45 degrees 108 93 } 109 94 void rolling_inc(double * v) { 110 *v += 0.7853; // 0.7853981 45 degrees95 *v += 0.7853; // 0.7853981 45 degrees 111 96 } 112 97 … … 114 99 int scanrec(const char * s, unsigned int slen, char stopchar) 115 100 { 116 unsigned int i = 0;117 //DB( printf(" scan('%s', '%c')\n", s, stopchar); )118 while (1)119 {120 if (i >= slen) // ran out the string, should never happen with correct string121 return 1;122 if (stopchar == s[i]) // bumped into stopchar123 return i;124 if (i < slen-1) 125 { // s[i] is not the last char126 if (s[i] == '(') 127 {128 i += 2+scanrec(s+i+1, slen-i-1, ')');129 continue;130 }131 if (s[i] == '<') 132 {133 i += 2+scanrec(s+i+1, slen-i-1, '>');134 continue;135 }136 if (s[i] == '#') 137 {138 i += 2+scanrec(s+i+1, slen-i-1, '>');139 continue;140 }141 }142 // s[i] a non-special character143 i++;144 }145 return i;101 unsigned int i = 0; 102 //DB( printf(" scan('%s', '%c')\n", s, stopchar); ) 103 while (1) 104 { 105 if (i >= slen) // ran out the string, should never happen with correct string 106 return 1; 107 if (stopchar == s[i]) // bumped into stopchar 108 return i; 109 if (i < slen - 1) 110 { // s[i] is not the last char 111 if (s[i] == '(') 112 { 113 i += 2 + scanrec(s + i + 1, slen - i - 1, ')'); 114 continue; 115 } 116 if (s[i] == '<') 117 { 118 i += 2 + scanrec(s + i + 1, slen - i - 1, '>'); 119 continue; 120 } 121 if (s[i] == '#') 122 { 123 i += 2 + scanrec(s + i + 1, slen - i - 1, '>'); 124 continue; 125 } 126 } 127 // s[i] a non-special character 128 i++; 129 } 130 return i; 146 131 } 147 132 148 133 149 134 f4_Cell::f4_Cell(int nname, 150 f4_Cell * ndad, int nangle, f4_Props newP)151 { 152 name= nname;153 type= T_UNDIFF4;154 dadlink = ndad;155 org= NULL;156 genot= NULL;157 gcur= NULL;158 active= 1;159 repeat.null();160 //genoRange.clear(); -- implicit161 162 anglepos= nangle;163 commacount = 0;164 childcount = 0;165 P= newP;166 rolling= 0;167 xrot= 0;168 zrot= 0;169 //OM = Orient_1;170 ctrl= 0;171 state= 0;172 inertia = 0.8;173 force= 0.04;174 sigmo= 2;175 nolink = 0;176 177 // adjust firstend and OM if there is a stick dad178 if (ndad != NULL)179 {180 // make sure it is a stick (and not a stick f4_Cell!)181 if (T_STICK4 == ndad->type)182 {183 //firstend = ndad->lastend;184 //OM = ndad->OM;185 ndad->childcount++;186 }187 if (T_NEURON4 == ndad->type)188 {189 state= ndad->state;190 inertia = ndad->inertia;191 force= ndad->force;192 sigmo= ndad->sigmo;193 }194 }195 // adjust lastend196 //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));197 mz = 1;135 f4_Cell * ndad, int nangle, f4_Props newP) 136 { 137 name = nname; 138 type = T_UNDIFF4; 139 dadlink = ndad; 140 org = NULL; 141 genot = NULL; 142 gcur = NULL; 143 active = 1; 144 repeat.null(); 145 //genoRange.clear(); -- implicit 146 147 anglepos = nangle; 148 commacount = 0; 149 childcount = 0; 150 P = newP; 151 rolling = 0; 152 xrot = 0; 153 zrot = 0; 154 //OM = Orient_1; 155 ctrl = 0; 156 state = 0; 157 inertia = 0.8; 158 force = 0.04; 159 sigmo = 2; 160 nolink = 0; 161 162 // adjust firstend and OM if there is a stick dad 163 if (ndad != NULL) 164 { 165 // make sure it is a stick (and not a stick f4_Cell!) 166 if (T_STICK4 == ndad->type) 167 { 168 //firstend = ndad->lastend; 169 //OM = ndad->OM; 170 ndad->childcount++; 171 } 172 if (T_NEURON4 == ndad->type) 173 { 174 state = ndad->state; 175 inertia = ndad->inertia; 176 force = ndad->force; 177 sigmo = ndad->sigmo; 178 } 179 } 180 // adjust lastend 181 //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len)); 182 mz = 1; 198 183 } 199 184 200 185 201 186 f4_Cell::f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur, 202 f4_Cell * ndad, int nangle, f4_Props newP)203 { 204 name= nname;205 type= T_UNDIFF4;206 dadlink = ndad;207 org= nO;208 genot= ngeno;209 gcur= ngcur;210 active = 1;211 repeat.null();212 //genoRange.clear(); -- implicit213 // preserve geno range of parent cell214 if (NULL != ndad)215 genoRange.add( ndad->genoRange);216 217 anglepos= nangle;218 commacount = 0;219 childcount = 0;220 P= newP;221 rolling= 0;222 xrot= 0;223 zrot= 0;224 //OM = Orient_1;225 ctrl= 0;226 state= 0;227 inertia = 0.8;228 force= 0.04;229 sigmo= 2;230 nolink = 0;231 232 // adjust firstend and OM if there is a stick dad233 if (ndad != NULL)234 {235 // make sure it is a stick (and not a stick f4_Cell!)236 if (T_STICK4 == ndad->type) {237 //firstend = ndad->lastend;238 //OM = ndad->OM;239 ndad->childcount++;240 }241 if (T_NEURON4 == ndad->type) 242 {243 state= ndad->state;244 inertia = ndad->inertia;245 force= ndad->force;246 sigmo= ndad->sigmo;247 }248 }249 // adjust lastend250 //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));251 mz = 1;187 f4_Cell * ndad, int nangle, f4_Props newP) 188 { 189 name = nname; 190 type = T_UNDIFF4; 191 dadlink = ndad; 192 org = nO; 193 genot = ngeno; 194 gcur = ngcur; 195 active = 1; 196 repeat.null(); 197 //genoRange.clear(); -- implicit 198 // preserve geno range of parent cell 199 if (NULL != ndad) 200 genoRange.add(ndad->genoRange); 201 202 anglepos = nangle; 203 commacount = 0; 204 childcount = 0; 205 P = newP; 206 rolling = 0; 207 xrot = 0; 208 zrot = 0; 209 //OM = Orient_1; 210 ctrl = 0; 211 state = 0; 212 inertia = 0.8; 213 force = 0.04; 214 sigmo = 2; 215 nolink = 0; 216 217 // adjust firstend and OM if there is a stick dad 218 if (ndad != NULL) 219 { 220 // make sure it is a stick (and not a stick f4_Cell!) 221 if (T_STICK4 == ndad->type) { 222 //firstend = ndad->lastend; 223 //OM = ndad->OM; 224 ndad->childcount++; 225 } 226 if (T_NEURON4 == ndad->type) 227 { 228 state = ndad->state; 229 inertia = ndad->inertia; 230 force = ndad->force; 231 sigmo = ndad->sigmo; 232 } 233 } 234 // adjust lastend 235 //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len)); 236 mz = 1; 252 237 } 253 238 … … 255 240 f4_Cell::~f4_Cell() 256 241 { 257 // remove links258 if (nolink)259 {260 int i;261 for (i=nolink-1; i>=0; i--)262 delete links[i];263 nolink=0;264 }242 // remove links 243 if (nolink) 244 { 245 int i; 246 for (i = nolink - 1; i >= 0; i--) 247 delete links[i]; 248 nolink = 0; 249 } 265 250 } 266 251 267 252 268 253 /* return codes: 269 >1 error at pos270 0 halt development for a cycle271 -1 development finished OK272 */254 >1 error at pos 255 0 halt development for a cycle 256 -1 development finished OK 257 */ 273 258 int f4_Cell::onestep() 274 259 { 275 int i, j, k, relfrom, t; 276 double w; 277 f4_Cell * tmp; 278 f4_Cell * tneu; 279 if (gcur == NULL) 280 { 281 active = 0; 282 return 0; // stop 283 } 284 while ( NULL != gcur ) 285 { 286 //DB( printf(" %d (%d) executing '%c' %d\n", name, type, gcur->name, gcur->pos); ) 287 // currently this is the last one processed 288 // the current genotype code is processed 289 genoRange.add( gcur->pos ); 290 switch (gcur->name) 291 { 292 case '<': 293 // cell division! 294 //DB( printf(" div! %d\n", name); ) 295 296 // error: sticks cannot divide 297 if (T_STICK4 == type) { 298 // cannot fix 299 org->setError(gcur->pos); 300 return 1; // stop 301 } 302 303 // undiff divides 304 if (T_UNDIFF4 == type) { 305 // commacount is set only when daughter turns into X 306 // daughter cell 307 // adjust new len 308 f4_Props newP = P; 309 newP.adjust(); 310 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, 311 this, commacount, newP); 312 tmp->repeat = repeat; 313 repeat.null(); 314 org->addCell( tmp ); 315 } 316 // a neuron divides: create a new, duplicate links 317 if (T_NEURON4 == type) { 318 // daughter cell 319 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, 320 // has the same dadlink 321 this->dadlink, commacount, P); 322 tmp->repeat = repeat; 323 repeat.null(); 324 // it is a neuron from start 325 tmp->type = T_NEURON4; 326 // duplicate links 327 f4_CellLink * ll; 328 for (i=0; i<nolink; i++) { 329 ll = links[i]; 330 tmp->addlink(ll->from, ll->w, ll->t); 331 } 332 org->addCell( tmp ); 333 } 334 // adjustments for this cell 335 gcur = gcur->child; 336 // halt development 337 return 0; 338 339 case '>': 340 // finish 341 // see if there is a repet count 342 if (repeat.top > 0) 343 { // there is a repeat counter 344 if (!repeat.first()->isNull()) 345 { // repeat counter is not null 346 repeat.first()->dec(); 347 if (repeat.first()->count > 0) 348 { 349 // return to repeat 350 gcur = repeat.first()->node->child; 351 } else { 352 // continue 353 gcur = repeat.first()->node->child2; 354 repeat.pop(); 355 } 356 break; 357 } else { 358 repeat.pop(); 359 } 360 } else { 361 // error: still undiff 362 if (T_UNDIFF4 == type) 363 { 364 // fix it: insert an 'X' 365 f4_node * insertnode = new f4_node('X', NULL, gcur->pos); 366 if (org->setRepairInsert(gcur->pos, gcur, insertnode)) 367 // not in repair mode, release 368 delete insertnode; 369 return 1; 370 } 371 repeat.null(); 372 active = 0; // stop 373 // eat up rest 374 gcur = NULL; 375 return 0; 376 } 377 378 case '#': 379 // repetition marker 380 if (repeat.top >= repeat_stack::stackSize) 381 { 382 // repepeat pointer stack is full, cannot remember this one. 383 // fix: delete it 384 org->setRepairRemove(gcur->pos, gcur); 385 return 1; // stop 386 } 387 repeat.push( repeat_ptr(gcur, gcur->i1) ); 388 gcur = gcur->child; 389 break; 390 391 case ',': 392 commacount++; 393 gcur = gcur->child; 394 break; 395 396 case 'r': case 'R': 397 // error: if neuron 398 if (T_NEURON4 == type) { 399 // fix: delete it 400 org->setRepairRemove(gcur->pos, gcur); 401 return 1; // stop 402 } 403 switch (gcur->name) { 404 case 'r': rolling_dec( &rolling ); break; 405 case 'R': rolling_inc( &rolling ); break; 406 } 407 gcur = gcur->child; 408 break; 409 410 case 'l': case 'L': 411 case 'c': case 'C': 412 case 'q': case 'Q': 413 case 'a': case 'A': 414 case 'i': case 'I': 415 case 's': case 'S': 416 case 'm': case 'M': 417 case 'f': case 'F': 418 case 'w': case 'W': 419 case 'e': case 'E': 420 // error: if neuron 421 if (T_NEURON4 == type) { 422 // fix: delete it 423 org->setRepairRemove(gcur->pos, gcur); 424 return 1; // stop 425 } 426 P.executeModifier(gcur->name); 427 gcur = gcur->child; 428 break; 429 430 case 'X': 431 // turn undiff. cell into a stick 432 // error: already differentiated 433 if (T_UNDIFF4 != type) { 434 // fix: delete this node 435 org->setRepairRemove(gcur->pos, gcur); 436 return 1; // stop 437 } 438 type = T_STICK4; 439 // fix dad commacount and own anglepos 440 if (NULL != dadlink) { 441 dadlink->commacount++; 442 anglepos = dadlink->commacount; 443 } 444 // change of type halts developments, see comment at 'N' 445 gcur = gcur->child; 446 return 0; 447 448 case 'N': 449 // turn undiff. cell into a neuron 450 // error: already differentiated 451 if (T_UNDIFF4 != type) { 452 // fix: delete this node 453 org->setRepairRemove(gcur->pos, gcur); 454 return 1; // stop 455 } 456 // error: if no previous 457 if (NULL == dadlink) { 458 // fix: delete it 459 org->setRepairRemove(gcur->pos, gcur); 460 return 1; // stop 461 } 462 type = T_NEURON4; 463 // change of type also halts development, to give other 464 // cells a chance for adjustment. Namely, it is important 465 // to wait for other cells to turn N before adding links 466 gcur = gcur->child; 467 return 0; 468 469 case '@': 470 case '|': 471 // neuron rotating / bending 472 j = 1; 473 if ('@' == gcur->name) j = 1; // rot 474 if ('|' == gcur->name) j = 2; // bend 475 // error: not a neuron (undiff) 476 if (T_UNDIFF4 == type) { 477 // fix: delete it 478 org->setRepairRemove(gcur->pos, gcur); 479 return 1; // stop 480 } 481 // error: not a neuron (stick) 482 if (T_NEURON4 != type) { 483 // fix: delete it 484 org->setRepairRemove(gcur->pos, gcur); 485 return 1; // stop 486 } 487 // error: already has control 488 if (ctrl != 0) { 489 // fix: delete it 490 org->setRepairRemove(gcur->pos, gcur); 491 return 1; // stop 492 } 493 // make neuron ctrl = 1 or 2 494 ctrl = j; 495 gcur = gcur->child; 496 break; 497 498 case '[': 499 // link to neuron 500 // error: not a neuron 501 if (T_NEURON4 != type) { 502 // fix: delete it 503 org->setRepairRemove(gcur->pos, gcur); 504 return 1; // stop 505 } 506 // input ('*', 'G', 'T', 'S', or %d) 507 t = gcur->i1; 508 relfrom = gcur->l1; 509 w = gcur->f1; 510 if (t>0) { 511 // * or G 512 tneu = NULL; 513 } else { 514 // input from other neuron 515 // find neuron at relative i 516 // find own index 517 j = 0; k = 0; 518 for(i=0; i<org->nc; i++) { 519 if (org->C[i]->type == T_NEURON4) k++; 520 if (org->C[i] == this) {j=k-1; break;} 521 } 522 // find index of incoming 523 j = j + relfrom; 524 if (j<0) goto wait_link; 525 if (j>=org->nc) goto wait_link; 526 // find that neuron 527 k = 0; 528 for(i=0; i<org->nc; i++) { 529 if (org->C[i]->type == T_NEURON4) k++; 530 if (j == (k-1)) break; 531 } 532 if (i>=org->nc) goto wait_link; 533 tneu = org->C[i]; 534 } 535 // add link 536 // error: could not add link (too many?) 537 if (addlink(tneu, w, t)) { 538 // cannot fix 539 org->setError(gcur->pos); 540 return 1; // stop 541 } 542 gcur = gcur->child; 543 break; 544 wait_link: 545 // wait for other neurons to develop 546 // if there are others still active 547 active = 0; 548 j = 0; 549 for(i=0; i<org->nc; i++) { 550 if (org->C[i]->active) j++; 551 } 552 if (j>0) 553 return 0; // there is other active, halt, try again 554 // no more actives, cannot add link, ignore, but treat not as an error 555 gcur = gcur->child; 556 break; 557 558 case ':': 559 // neuron parameter 560 // error: not a neuron 561 if (T_NEURON4 != type) { 562 // fix: delete it 563 org->setRepairRemove(gcur->pos, gcur); 564 return 1; // stop 565 } 566 j = (int)gcur->l1; 567 switch ((char)gcur->i1) { 568 case '!': 569 if (j) force += (1.0 - force) * 0.2; 570 else force -= force * 0.2; break; 571 case '=': 572 if (j) inertia += (1.0 - inertia) * 0.2; 573 else inertia -= inertia * 0.2; break; 574 case '/': 575 if (j) sigmo *= 1.4; 576 else sigmo /= 1.4; break; 577 default: 578 org->setRepairRemove(gcur->pos, gcur); 579 return 1; // stop 580 } 581 gcur = gcur->child; 582 break; 583 584 case ' ': 585 // space has no effect, should not occur 586 // fix: delete it 587 org->setRepairRemove(gcur->pos, gcur); 588 gcur = gcur->child; 589 break; 590 591 default: 592 // error: unknown code 593 char buf[40]; 594 sprintf(buf, "unknown code '%c'", gcur->name); 595 FramMessage("f4_Cell", "onestep", buf, 2); 596 // fix: delete it 597 org->setRepairRemove(gcur->pos, gcur); 598 return 1; // stop 599 } 600 } 601 active = 0; // done 602 return 0; 260 int i, j, k, relfrom, t; 261 double w; 262 f4_Cell * tmp; 263 f4_Cell * tneu; 264 if (gcur == NULL) 265 { 266 active = 0; 267 return 0; // stop 268 } 269 while (NULL != gcur) 270 { 271 //DB( printf(" %d (%d) executing '%c' %d\n", name, type, gcur->name, gcur->pos); ) 272 // currently this is the last one processed 273 // the current genotype code is processed 274 genoRange.add(gcur->pos); 275 switch (gcur->name) 276 { 277 case '<': 278 // cell division! 279 //DB( printf(" div! %d\n", name); ) 280 281 // error: sticks cannot divide 282 if (T_STICK4 == type) { 283 // cannot fix 284 org->setError(gcur->pos); 285 return 1; // stop 286 } 287 288 // undiff divides 289 if (T_UNDIFF4 == type) { 290 // commacount is set only when daughter turns into X 291 // daughter cell 292 // adjust new len 293 f4_Props newP = P; 294 newP.adjust(); 295 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, 296 this, commacount, newP); 297 tmp->repeat = repeat; 298 repeat.null(); 299 org->addCell(tmp); 300 } 301 // a neuron divides: create a new, duplicate links 302 if (T_NEURON4 == type) { 303 // daughter cell 304 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, 305 // has the same dadlink 306 this->dadlink, commacount, P); 307 tmp->repeat = repeat; 308 repeat.null(); 309 // it is a neuron from start 310 tmp->type = T_NEURON4; 311 // duplicate links 312 f4_CellLink * ll; 313 for (i = 0; i < nolink; i++) { 314 ll = links[i]; 315 tmp->addlink(ll->from, ll->w, ll->t); 316 } 317 org->addCell(tmp); 318 } 319 // adjustments for this cell 320 gcur = gcur->child; 321 // halt development 322 return 0; 323 324 case '>': 325 // finish 326 // see if there is a repet count 327 if (repeat.top > 0) 328 { // there is a repeat counter 329 if (!repeat.first()->isNull()) 330 { // repeat counter is not null 331 repeat.first()->dec(); 332 if (repeat.first()->count > 0) 333 { 334 // return to repeat 335 gcur = repeat.first()->node->child; 336 } 337 else { 338 // continue 339 gcur = repeat.first()->node->child2; 340 repeat.pop(); 341 } 342 break; 343 } 344 else { 345 repeat.pop(); 346 } 347 } 348 else { 349 // error: still undiff 350 if (T_UNDIFF4 == type) 351 { 352 // fix it: insert an 'X' 353 f4_node * insertnode = new f4_node('X', NULL, gcur->pos); 354 if (org->setRepairInsert(gcur->pos, gcur, insertnode)) 355 // not in repair mode, release 356 delete insertnode; 357 return 1; 358 } 359 repeat.null(); 360 active = 0; // stop 361 // eat up rest 362 gcur = NULL; 363 return 0; 364 } 365 366 case '#': 367 // repetition marker 368 if (repeat.top >= repeat_stack::stackSize) 369 { 370 // repepeat pointer stack is full, cannot remember this one. 371 // fix: delete it 372 org->setRepairRemove(gcur->pos, gcur); 373 return 1; // stop 374 } 375 repeat.push(repeat_ptr(gcur, gcur->i1)); 376 gcur = gcur->child; 377 break; 378 379 case ',': 380 commacount++; 381 gcur = gcur->child; 382 break; 383 384 case 'r': case 'R': 385 // error: if neuron 386 if (T_NEURON4 == type) { 387 // fix: delete it 388 org->setRepairRemove(gcur->pos, gcur); 389 return 1; // stop 390 } 391 switch (gcur->name) { 392 case 'r': rolling_dec(&rolling); break; 393 case 'R': rolling_inc(&rolling); break; 394 } 395 gcur = gcur->child; 396 break; 397 398 case 'l': case 'L': 399 case 'c': case 'C': 400 case 'q': case 'Q': 401 case 'a': case 'A': 402 case 'i': case 'I': 403 case 's': case 'S': 404 case 'm': case 'M': 405 case 'f': case 'F': 406 case 'w': case 'W': 407 case 'e': case 'E': 408 // error: if neuron 409 if (T_NEURON4 == type) { 410 // fix: delete it 411 org->setRepairRemove(gcur->pos, gcur); 412 return 1; // stop 413 } 414 P.executeModifier(gcur->name); 415 gcur = gcur->child; 416 break; 417 418 case 'X': 419 // turn undiff. cell into a stick 420 // error: already differentiated 421 if (T_UNDIFF4 != type) { 422 // fix: delete this node 423 org->setRepairRemove(gcur->pos, gcur); 424 return 1; // stop 425 } 426 type = T_STICK4; 427 // fix dad commacount and own anglepos 428 if (NULL != dadlink) { 429 dadlink->commacount++; 430 anglepos = dadlink->commacount; 431 } 432 // change of type halts developments, see comment at 'N' 433 gcur = gcur->child; 434 return 0; 435 436 case 'N': 437 // turn undiff. cell into a neuron 438 // error: already differentiated 439 if (T_UNDIFF4 != type) { 440 // fix: delete this node 441 org->setRepairRemove(gcur->pos, gcur); 442 return 1; // stop 443 } 444 // error: if no previous 445 if (NULL == dadlink) { 446 // fix: delete it 447 org->setRepairRemove(gcur->pos, gcur); 448 return 1; // stop 449 } 450 type = T_NEURON4; 451 // change of type also halts development, to give other 452 // cells a chance for adjustment. Namely, it is important 453 // to wait for other cells to turn N before adding links 454 gcur = gcur->child; 455 return 0; 456 457 case '@': 458 case '|': 459 // neuron rotating / bending 460 j = 1; 461 if ('@' == gcur->name) j = 1; // rot 462 if ('|' == gcur->name) j = 2; // bend 463 // error: not a neuron (undiff) 464 if (T_UNDIFF4 == type) { 465 // fix: delete it 466 org->setRepairRemove(gcur->pos, gcur); 467 return 1; // stop 468 } 469 // error: not a neuron (stick) 470 if (T_NEURON4 != type) { 471 // fix: delete it 472 org->setRepairRemove(gcur->pos, gcur); 473 return 1; // stop 474 } 475 // error: already has control 476 if (ctrl != 0) { 477 // fix: delete it 478 org->setRepairRemove(gcur->pos, gcur); 479 return 1; // stop 480 } 481 // make neuron ctrl = 1 or 2 482 ctrl = j; 483 gcur = gcur->child; 484 break; 485 486 case '[': 487 // link to neuron 488 // error: not a neuron 489 if (T_NEURON4 != type) { 490 // fix: delete it 491 org->setRepairRemove(gcur->pos, gcur); 492 return 1; // stop 493 } 494 // input ('*', 'G', 'T', 'S', or %d) 495 t = gcur->i1; 496 relfrom = gcur->l1; 497 w = gcur->f1; 498 if (t > 0) { 499 // * or G 500 tneu = NULL; 501 } 502 else { 503 // input from other neuron 504 // find neuron at relative i 505 // find own index 506 j = 0; k = 0; 507 for (i = 0; i < org->nc; i++) { 508 if (org->C[i]->type == T_NEURON4) k++; 509 if (org->C[i] == this) { j = k - 1; break; } 510 } 511 // find index of incoming 512 j = j + relfrom; 513 if (j < 0) goto wait_link; 514 if (j >= org->nc) goto wait_link; 515 // find that neuron 516 k = 0; 517 for (i = 0; i < org->nc; i++) { 518 if (org->C[i]->type == T_NEURON4) k++; 519 if (j == (k - 1)) break; 520 } 521 if (i >= org->nc) goto wait_link; 522 tneu = org->C[i]; 523 } 524 // add link 525 // error: could not add link (too many?) 526 if (addlink(tneu, w, t)) { 527 // cannot fix 528 org->setError(gcur->pos); 529 return 1; // stop 530 } 531 gcur = gcur->child; 532 break; 533 wait_link: 534 // wait for other neurons to develop 535 // if there are others still active 536 active = 0; 537 j = 0; 538 for (i = 0; i<org->nc; i++) { 539 if (org->C[i]->active) j++; 540 } 541 if (j>0) 542 return 0; // there is other active, halt, try again 543 // no more actives, cannot add link, ignore, but treat not as an error 544 gcur = gcur->child; 545 break; 546 547 case ':': 548 // neuron parameter 549 // error: not a neuron 550 if (T_NEURON4 != type) { 551 // fix: delete it 552 org->setRepairRemove(gcur->pos, gcur); 553 return 1; // stop 554 } 555 j = (int)gcur->l1; 556 switch ((char)gcur->i1) { 557 case '!': 558 if (j) force += (1.0 - force) * 0.2; 559 else force -= force * 0.2; break; 560 case '=': 561 if (j) inertia += (1.0 - inertia) * 0.2; 562 else inertia -= inertia * 0.2; break; 563 case '/': 564 if (j) sigmo *= 1.4; 565 else sigmo /= 1.4; break; 566 default: 567 org->setRepairRemove(gcur->pos, gcur); 568 return 1; // stop 569 } 570 gcur = gcur->child; 571 break; 572 573 case ' ': 574 // space has no effect, should not occur 575 // fix: delete it 576 org->setRepairRemove(gcur->pos, gcur); 577 gcur = gcur->child; 578 break; 579 580 default: 581 // error: unknown code 582 char buf[40]; 583 sprintf(buf, "unknown code '%c'", gcur->name); 584 FramMessage("f4_Cell", "onestep", buf, 2); 585 // fix: delete it 586 org->setRepairRemove(gcur->pos, gcur); 587 return 1; // stop 588 } 589 } 590 active = 0; // done 591 return 0; 603 592 } 604 593 … … 606 595 int f4_Cell::addlink(f4_Cell * nfrom, double nw, long nt) 607 596 { 608 if (nolink >= MAXINPUTS-1) return -1; // full!609 links[nolink] = new f4_CellLink(nfrom, nw, nt);610 nolink++;611 return 0;597 if (nolink >= MAXINPUTS - 1) return -1; // full! 598 links[nolink] = new f4_CellLink(nfrom, nw, nt); 599 nolink++; 600 return 0; 612 601 } 613 602 … … 615 604 void f4_Cell::adjustRec() 616 605 { 617 //f4_OrientMat rot; 618 int i; 619 620 if (recProcessedFlag) 621 // already processed 622 return; 623 624 // mark it processed 625 recProcessedFlag = 1; 626 627 // make sure its parent is processed first 628 if (NULL != dadlink) 629 dadlink->adjustRec(); 630 631 // count children 632 childcount = 0; 633 for(i=0; i<org->nc; i++) 634 { 635 if (org->C[i]->dadlink == this) 636 if (org->C[i]->type == T_STICK4) 637 childcount++; 638 } 639 640 if (type == T_STICK4) 641 { 642 if (NULL == dadlink) 643 { 644 //firstend = Pt3D_0; 645 // rotation due to rolling 646 xrot = rolling; 647 mz = 1; 648 } else { 649 //firstend = dadlink->lastend; 650 f4_Props Pdad = dadlink->P; 651 f4_Props Padj = Pdad; 652 Padj.adjust(); 653 654 //rot = Orient_1; 655 656 // rotation due to rolling 657 xrot = rolling + 658 // rotation due to twist 659 Pdad.twist; 660 if (dadlink->commacount <= 1) 661 { 662 // rotation due to curvedness 663 zrot = Padj.curv; 664 } else { 665 zrot = Padj.curv + 666 // GDK uses 3.141 instead of PI! 667 (anglepos * 1.0/(dadlink->commacount+1) - 0.5) * 3.141 * 2.0; 668 } 669 670 //rot = rot * f4_OrientMat(yOz, xrot); 671 //rot = rot * f4_OrientMat(xOy, zrot); 672 // rotation relative to parent stick 673 //OM = rot * OM; 674 675 // rotation in world coordinates 676 //OM = ((f4_OrientMat)dadlink->OM) * OM; 677 mz = dadlink->mz / dadlink->childcount; 678 } 679 //Pt3D lastoffset = (Orient)OM * (Pt3D(1,0,0)*P.len); 680 //lastend = firstend + lastoffset; 681 } 606 //f4_OrientMat rot; 607 int i; 608 609 if (recProcessedFlag) 610 // already processed 611 return; 612 613 // mark it processed 614 recProcessedFlag = 1; 615 616 // make sure its parent is processed first 617 if (NULL != dadlink) 618 dadlink->adjustRec(); 619 620 // count children 621 childcount = 0; 622 for (i = 0; i < org->nc; i++) 623 { 624 if (org->C[i]->dadlink == this) 625 if (org->C[i]->type == T_STICK4) 626 childcount++; 627 } 628 629 if (type == T_STICK4) 630 { 631 if (NULL == dadlink) 632 { 633 //firstend = Pt3D_0; 634 // rotation due to rolling 635 xrot = rolling; 636 mz = 1; 637 } 638 else { 639 //firstend = dadlink->lastend; 640 f4_Props Pdad = dadlink->P; 641 f4_Props Padj = Pdad; 642 Padj.adjust(); 643 644 //rot = Orient_1; 645 646 // rotation due to rolling 647 xrot = rolling + 648 // rotation due to twist 649 Pdad.twist; 650 if (dadlink->commacount <= 1) 651 { 652 // rotation due to curvedness 653 zrot = Padj.curv; 654 } 655 else { 656 zrot = Padj.curv + 657 // GDK uses 3.141 instead of PI! 658 (anglepos * 1.0 / (dadlink->commacount + 1) - 0.5) * 3.141 * 2.0; 659 } 660 661 //rot = rot * f4_OrientMat(yOz, xrot); 662 //rot = rot * f4_OrientMat(xOy, zrot); 663 // rotation relative to parent stick 664 //OM = rot * OM; 665 666 // rotation in world coordinates 667 //OM = ((f4_OrientMat)dadlink->OM) * OM; 668 mz = dadlink->mz / dadlink->childcount; 669 } 670 //Pt3D lastoffset = (Orient)OM * (Pt3D(1,0,0)*P.len); 671 //lastend = firstend + lastoffset; 672 } 682 673 } 683 674 … … 686 677 f4_CellLink::f4_CellLink(f4_Cell * nfrom, double nw, long nt) 687 678 { 688 from = nfrom;689 w= nw;690 t= nt;679 from = nfrom; 680 w = nw; 681 t = nt; 691 682 } 692 683 … … 695 686 f4_Cells::f4_Cells(f4_node * genome, int nrepair) 696 687 { 697 // create ancestor cell698 repair = nrepair;699 error= 0;700 errorpos = -1;701 repair_remove = NULL;702 repair_parent = NULL;703 repair_insert = NULL;704 tmpcel = NULL;705 f4rootnode = NULL;706 707 C[0] = new f4_Cell(this, 0, genome, genome, NULL, 0, stdProps);708 nc= 1;688 // create ancestor cell 689 repair = nrepair; 690 error = 0; 691 errorpos = -1; 692 repair_remove = NULL; 693 repair_parent = NULL; 694 repair_insert = NULL; 695 tmpcel = NULL; 696 f4rootnode = NULL; 697 698 C[0] = new f4_Cell(this, 0, genome, genome, NULL, 0, stdProps); 699 nc = 1; 709 700 } 710 701 … … 712 703 f4_Cells::f4_Cells(SString & genome, int nrepair) 713 704 { 714 int res;715 repair = nrepair;716 error= 0;717 errorpos = -1;718 repair_remove = NULL;719 repair_parent = NULL;720 repair_insert = NULL;721 tmpcel = NULL;722 f4rootnode = NULL;723 724 // transform geno from string to nodes725 f4rootnode = new f4_node();726 res = f4_processrec((const char*)genome, (unsigned)0, f4rootnode);727 if ((res<0) || (1 != f4rootnode->childCount()))728 {729 error = GENOPER_OPFAIL;730 errorpos = -1;731 }732 733 // create ancestor cell734 C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child,735 NULL, 0, stdProps);736 nc= 1;705 int res; 706 repair = nrepair; 707 error = 0; 708 errorpos = -1; 709 repair_remove = NULL; 710 repair_parent = NULL; 711 repair_insert = NULL; 712 tmpcel = NULL; 713 f4rootnode = NULL; 714 715 // transform geno from string to nodes 716 f4rootnode = new f4_node(); 717 res = f4_processrec((const char*)genome, (unsigned)0, f4rootnode); 718 if ((res < 0) || (1 != f4rootnode->childCount())) 719 { 720 error = GENOPER_OPFAIL; 721 errorpos = -1; 722 } 723 724 // create ancestor cell 725 C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child, 726 NULL, 0, stdProps); 727 nc = 1; 737 728 } 738 729 739 730 f4_Cells::~f4_Cells() 740 731 { 741 // release cells742 int i;743 if (nc)744 {745 for (i=nc-1; i>=0; i--)746 delete C[i];747 nc = 0;748 }749 if (f4rootnode)750 delete f4rootnode;732 // release cells 733 int i; 734 if (nc) 735 { 736 for (i = nc - 1; i >= 0; i--) 737 delete C[i]; 738 nc = 0; 739 } 740 if (f4rootnode) 741 delete f4rootnode; 751 742 } 752 743 … … 754 745 int f4_Cells::onestep() 755 746 { 756 int i, ret, oldnc, ret2;757 oldnc = nc;758 ret=0;759 for (i=0; i<oldnc; i++) {760 ret2 = C[i]->onestep();761 if (ret2>0) {762 // error763 C[i]->active = 0; // stop764 return 0;765 }766 // if still active767 if (C[i]->active)768 ret=1;769 }770 return ret;747 int i, ret, oldnc, ret2; 748 oldnc = nc; 749 ret = 0; 750 for (i = 0; i<oldnc; i++) { 751 ret2 = C[i]->onestep(); 752 if (ret2>0) { 753 // error 754 C[i]->active = 0; // stop 755 return 0; 756 } 757 // if still active 758 if (C[i]->active) 759 ret = 1; 760 } 761 return ret; 771 762 } 772 763 … … 774 765 int f4_Cells::simulate() 775 766 { 776 int i;777 error = GENOPER_OK;778 779 for (i=0; i<nc; i++) C[i]->active = 1;780 781 // execute onestep() in a cycle782 while (onestep());783 784 if (GENOPER_OK != error) return error;785 786 // fix neuron attachements787 for(i=0; i<nc; i++)788 if (C[i]->type == T_NEURON4) {789 while (T_NEURON4 == C[i]->dadlink->type) {790 C[i]->dadlink = C[i]->dadlink->dadlink;791 }792 }793 794 // there should be no undiff. cells795 // make undifferentiated cells sticks796 for (i=0; i<nc; i++)797 if (C[i]->type == T_UNDIFF4) {798 C[i]->type = T_STICK4;799 //seterror();800 }801 802 // recursive adjust803 // reset recursive traverse flags804 for(i=0; i<nc; i++)805 C[i]->recProcessedFlag = 0;806 // process every cell807 for(i=0; i<nc; i++)808 C[i]->adjustRec();809 810 //DB( printf("Cell simulation done, %d cells. \n", nc); )811 812 return error;767 int i; 768 error = GENOPER_OK; 769 770 for (i = 0; i < nc; i++) C[i]->active = 1; 771 772 // execute onestep() in a cycle 773 while (onestep()); 774 775 if (GENOPER_OK != error) return error; 776 777 // fix neuron attachements 778 for (i = 0; i < nc; i++) 779 if (C[i]->type == T_NEURON4) { 780 while (T_NEURON4 == C[i]->dadlink->type) { 781 C[i]->dadlink = C[i]->dadlink->dadlink; 782 } 783 } 784 785 // there should be no undiff. cells 786 // make undifferentiated cells sticks 787 for (i = 0; i < nc; i++) 788 if (C[i]->type == T_UNDIFF4) { 789 C[i]->type = T_STICK4; 790 //seterror(); 791 } 792 793 // recursive adjust 794 // reset recursive traverse flags 795 for (i = 0; i < nc; i++) 796 C[i]->recProcessedFlag = 0; 797 // process every cell 798 for (i = 0; i < nc; i++) 799 C[i]->adjustRec(); 800 801 //DB( printf("Cell simulation done, %d cells. \n", nc); ) 802 803 return error; 813 804 } 814 805 … … 816 807 void f4_Cells::addCell(f4_Cell * newcell) 817 808 { 818 if (nc >= MAX4CELLS-1) {819 delete newcell;820 return;821 }822 C[nc] = newcell;823 nc++;809 if (nc >= MAX4CELLS - 1) { 810 delete newcell; 811 return; 812 } 813 C[nc] = newcell; 814 nc++; 824 815 } 825 816 … … 827 818 void f4_Cells::setError(int nerrpos) 828 819 { 829 error = GENOPER_OPFAIL;830 errorpos = nerrpos;820 error = GENOPER_OPFAIL; 821 errorpos = nerrpos; 831 822 } 832 823 833 824 void f4_Cells::setRepairRemove(int nerrpos, f4_node * rem) 834 825 { 835 if (!repair) { 836 // not in repair mode, treat as repairable error 837 error = GENOPER_REPAIR; 838 errorpos = nerrpos; 839 } else { 840 error = GENOPER_REPAIR; 841 errorpos = nerrpos; 842 repair_remove = rem; 843 } 826 if (!repair) { 827 // not in repair mode, treat as repairable error 828 error = GENOPER_REPAIR; 829 errorpos = nerrpos; 830 } 831 else { 832 error = GENOPER_REPAIR; 833 errorpos = nerrpos; 834 repair_remove = rem; 835 } 844 836 } 845 837 846 838 int f4_Cells::setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert) 847 839 { 848 if (!repair) { 849 // not in repair mode, treat as repairable error 850 error = GENOPER_REPAIR; 851 errorpos = nerrpos; 852 return -1; 853 } else { 854 error = GENOPER_REPAIR; 855 errorpos = nerrpos; 856 repair_parent = parent; 857 repair_insert = insert; 858 return 0; 859 } 840 if (!repair) { 841 // not in repair mode, treat as repairable error 842 error = GENOPER_REPAIR; 843 errorpos = nerrpos; 844 return -1; 845 } 846 else { 847 error = GENOPER_REPAIR; 848 errorpos = nerrpos; 849 repair_parent = parent; 850 repair_insert = insert; 851 return 0; 852 } 860 853 } 861 854 862 855 void f4_Cells::repairGeno(f4_node * geno, int whichchild) 863 856 { 864 // assemble repaired geno, if the case865 if (!repair) return;866 if ((NULL==repair_remove) && (NULL==repair_insert)) return;867 // traverse genotype tree, remove / insert node868 f4_node * g2;869 if (1==whichchild) g2 = geno->child;870 else g2 = geno->child2;871 if (NULL == g2)872 return;873 if (g2 == repair_remove) {874 f4_node * oldgeno;875 geno->removeChild(g2);876 if (g2->child) {877 // add g2->child as child to geno878 if (1==whichchild) geno->child= g2->child;879 else geno->child2 = g2->child;880 g2->child->parent = geno;881 }882 oldgeno = g2;883 oldgeno->child = NULL;884 delete oldgeno;885 if (NULL == geno->child) return;886 // check this new887 repairGeno(geno, whichchild);888 return;889 }890 if (g2 == repair_parent) {891 geno->removeChild(g2);892 geno->addChild(repair_insert);893 repair_insert->parent = geno;894 repair_insert->child= g2;895 repair_insert->child2 = NULL;896 g2->parent = repair_insert;897 }898 // recurse899 if (g2->child) repairGeno(g2, 1);900 if (g2->child2) repairGeno(g2, 2);857 // assemble repaired geno, if the case 858 if (!repair) return; 859 if ((NULL == repair_remove) && (NULL == repair_insert)) return; 860 // traverse genotype tree, remove / insert node 861 f4_node * g2; 862 if (1 == whichchild) g2 = geno->child; 863 else g2 = geno->child2; 864 if (NULL == g2) 865 return; 866 if (g2 == repair_remove) { 867 f4_node * oldgeno; 868 geno->removeChild(g2); 869 if (g2->child) { 870 // add g2->child as child to geno 871 if (1 == whichchild) geno->child = g2->child; 872 else geno->child2 = g2->child; 873 g2->child->parent = geno; 874 } 875 oldgeno = g2; 876 oldgeno->child = NULL; 877 delete oldgeno; 878 if (NULL == geno->child) return; 879 // check this new 880 repairGeno(geno, whichchild); 881 return; 882 } 883 if (g2 == repair_parent) { 884 geno->removeChild(g2); 885 geno->addChild(repair_insert); 886 repair_insert->parent = geno; 887 repair_insert->child = g2; 888 repair_insert->child2 = NULL; 889 g2->parent = repair_insert; 890 } 891 // recurse 892 if (g2->child) repairGeno(g2, 1); 893 if (g2->child2) repairGeno(g2, 2); 901 894 } 902 895 … … 904 897 void f4_Cells::toF1Geno(SString &out) 905 898 { 906 if (tmpcel) delete tmpcel;907 tmpcel = new f4_Cell(-1, NULL, 0, stdProps);908 out = "";909 toF1GenoRec(0, out);910 delete tmpcel;899 if (tmpcel) delete tmpcel; 900 tmpcel = new f4_Cell(-1, NULL, 0, stdProps); 901 out = ""; 902 toF1GenoRec(0, out); 903 delete tmpcel; 911 904 } 912 905 … … 914 907 void f4_Cells::toF1GenoRec(int curc, SString &out) 915 908 { 916 int i, j, ccount; 917 f4_Cell * thisti; 918 f4_Cell * thneu; 919 char buf[200]; 920 921 if (curc >= nc) return; 922 923 if (T_STICK4 != C[curc]->type) return; 924 925 thisti = C[curc]; 926 if (NULL != thisti->dadlink) 927 *tmpcel = *(thisti->dadlink); 928 929 // adjust length, curvedness, etc. 930 tmpcel->P.adjust(); 931 while (tmpcel->P.len > thisti->P.len) 932 { 933 tmpcel->P.executeModifier('l'); 934 out += "l"; 935 } 936 while (tmpcel->P.len < thisti->P.len) 937 { 938 tmpcel->P.executeModifier('L'); 939 out += "L"; 940 } 941 while (tmpcel->P.curv > thisti->P.curv) 942 { 943 tmpcel->P.executeModifier('c'); 944 out += "c"; 945 } 946 while (tmpcel->P.curv < thisti->P.curv) 947 { 948 tmpcel->P.executeModifier('C'); 949 out += "C"; 950 } 951 while (thisti->rolling > 0.0f) { 952 rolling_dec( &(thisti->rolling) ); 953 out += "R"; 954 } 955 while (thisti->rolling < 0.0f) { 956 rolling_inc( &(thisti->rolling) ); 957 out += "r"; 958 } 959 960 // output X for this stick 961 out += "X"; 962 963 // neurons attached to it 964 for (i=0; i<nc; i++) 965 if (C[i]->type == T_NEURON4) { 966 if (C[i]->dadlink == thisti) { 967 thneu = C[i]; 968 out += "["; 969 // ctrl 970 if (1 == thneu->ctrl) out += "@"; 971 if (2 == thneu->ctrl) out += "|"; 972 // links 973 for (j=0; j<thneu->nolink; j++) 974 { 975 if (j) out += ","; 976 if (NULL == thneu->links[j]->from) 977 { 978 // sensory 979 if (1 == thneu->links[j]->t) out += "*"; 980 if (2 == thneu->links[j]->t) out += "G"; 981 if (3 == thneu->links[j]->t) out += "T"; 982 if (4 == thneu->links[j]->t) out += "S"; 983 } else { 984 sprintf(buf, "%d", thneu->links[j]->from->name - thneu->name); 985 out += buf; 986 } 987 out += ":"; 988 // weight 989 sprintf(buf, "%g", thneu->links[j]->w ); 990 out += buf; 991 } 992 out += "]"; 993 } 994 } 995 996 // sticks connected to it 997 if (thisti->commacount>=2) 998 out += "("; 999 1000 ccount=1; 1001 for (i=0; i<nc; i++) 1002 if (C[i]->type == T_STICK4) 1003 if (C[i]->dadlink == thisti) { 1004 while (ccount < (C[i])->anglepos) { 1005 ccount++; 1006 out += ","; 1007 } 1008 toF1GenoRec(i, out); 1009 } 1010 while (ccount < thisti->commacount) { 1011 ccount++; 1012 out += ","; 1013 } 1014 1015 if (thisti->commacount >= 2) 1016 out += ")"; 909 int i, j, ccount; 910 f4_Cell * thisti; 911 f4_Cell * thneu; 912 char buf[200]; 913 914 if (curc >= nc) return; 915 916 if (T_STICK4 != C[curc]->type) return; 917 918 thisti = C[curc]; 919 if (NULL != thisti->dadlink) 920 *tmpcel = *(thisti->dadlink); 921 922 // adjust length, curvedness, etc. 923 tmpcel->P.adjust(); 924 while (tmpcel->P.len > thisti->P.len) 925 { 926 tmpcel->P.executeModifier('l'); 927 out += "l"; 928 } 929 while (tmpcel->P.len < thisti->P.len) 930 { 931 tmpcel->P.executeModifier('L'); 932 out += "L"; 933 } 934 while (tmpcel->P.curv > thisti->P.curv) 935 { 936 tmpcel->P.executeModifier('c'); 937 out += "c"; 938 } 939 while (tmpcel->P.curv < thisti->P.curv) 940 { 941 tmpcel->P.executeModifier('C'); 942 out += "C"; 943 } 944 while (thisti->rolling > 0.0f) { 945 rolling_dec(&(thisti->rolling)); 946 out += "R"; 947 } 948 while (thisti->rolling < 0.0f) { 949 rolling_inc(&(thisti->rolling)); 950 out += "r"; 951 } 952 953 // output X for this stick 954 out += "X"; 955 956 // neurons attached to it 957 for (i = 0; i < nc; i++) 958 if (C[i]->type == T_NEURON4) { 959 if (C[i]->dadlink == thisti) { 960 thneu = C[i]; 961 out += "["; 962 // ctrl 963 if (1 == thneu->ctrl) out += "@"; 964 if (2 == thneu->ctrl) out += "|"; 965 // links 966 for (j = 0; j < thneu->nolink; j++) 967 { 968 if (j) out += ","; 969 if (NULL == thneu->links[j]->from) 970 { 971 // sensory 972 if (1 == thneu->links[j]->t) out += "*"; 973 if (2 == thneu->links[j]->t) out += "G"; 974 if (3 == thneu->links[j]->t) out += "T"; 975 if (4 == thneu->links[j]->t) out += "S"; 976 } 977 else { 978 sprintf(buf, "%d", thneu->links[j]->from->name - thneu->name); 979 out += buf; 980 } 981 out += ":"; 982 // weight 983 sprintf(buf, "%g", thneu->links[j]->w); 984 out += buf; 985 } 986 out += "]"; 987 } 988 } 989 990 // sticks connected to it 991 if (thisti->commacount >= 2) 992 out += "("; 993 994 ccount = 1; 995 for (i = 0; i < nc; i++) 996 if (C[i]->type == T_STICK4) 997 if (C[i]->dadlink == thisti) { 998 while (ccount < (C[i])->anglepos) { 999 ccount++; 1000 out += ","; 1001 } 1002 toF1GenoRec(i, out); 1003 } 1004 while (ccount < thisti->commacount) { 1005 ccount++; 1006 out += ","; 1007 } 1008 1009 if (thisti->commacount >= 2) 1010 out += ")"; 1017 1011 } 1018 1012 … … 1023 1017 f4_node::f4_node() 1024 1018 { 1025 name= '?';1026 parent = NULL;1027 child= NULL;1028 child2 = NULL;1029 pos= -1;1019 name = '?'; 1020 parent = NULL; 1021 child = NULL; 1022 child2 = NULL; 1023 pos = -1; 1030 1024 } 1031 1025 1032 1026 f4_node::f4_node(char nname, f4_node * nparent, int npos) 1033 1027 { 1034 name= nname;1035 parent = nparent;1036 child= NULL;1037 child2 = NULL;1038 pos= npos;1039 if (parent) parent->addChild(this);1028 name = nname; 1029 parent = nparent; 1030 child = NULL; 1031 child2 = NULL; 1032 pos = npos; 1033 if (parent) parent->addChild(this); 1040 1034 } 1041 1035 1042 1036 f4_node::~f4_node() 1043 1037 { 1044 // (destroy() copied here for efficiency)1045 // children are destroyed (recursively) through the destructor1046 if (NULL != child2) delete child2;1047 if (NULL != child) delete child;1038 // (destroy() copied here for efficiency) 1039 // children are destroyed (recursively) through the destructor 1040 if (NULL != child2) delete child2; 1041 if (NULL != child) delete child; 1048 1042 } 1049 1043 1050 1044 int f4_node::addChild(f4_node * nchi) 1051 1045 { 1052 if (NULL==child) {1053 child = nchi;1054 return 0;1055 }1056 if (NULL==child2) {1057 child2 = nchi;1058 return 0;1059 }1060 return -1;1046 if (NULL == child) { 1047 child = nchi; 1048 return 0; 1049 } 1050 if (NULL == child2) { 1051 child2 = nchi; 1052 return 0; 1053 } 1054 return -1; 1061 1055 } 1062 1056 1063 1057 int f4_node::removeChild(f4_node * nchi) 1064 1058 { 1065 if (nchi==child2) {1066 child2 = NULL;1067 return 0;1068 }1069 if (nchi==child) {1070 child = NULL;1071 return 0;1072 }1073 return -1;1059 if (nchi == child2) { 1060 child2 = NULL; 1061 return 0; 1062 } 1063 if (nchi == child) { 1064 child = NULL; 1065 return 0; 1066 } 1067 return -1; 1074 1068 } 1075 1069 1076 1070 int f4_node::childCount() 1077 1071 { 1078 if (NULL!=child) { 1079 if (NULL!=child2) return 2; 1080 else return 1; 1081 } else { 1082 if (NULL!=child2) return 1; 1083 else return 0; 1084 } 1072 if (NULL != child) { 1073 if (NULL != child2) return 2; 1074 else return 1; 1075 } 1076 else { 1077 if (NULL != child2) return 1; 1078 else return 0; 1079 } 1085 1080 } 1086 1081 1087 1082 int f4_node::count() 1088 1083 { 1089 int c=1;1090 if (NULL!=child) c+=child->count();1091 if (NULL!=child2) c+=child2->count();1092 return c;1084 int c = 1; 1085 if (NULL != child) c += child->count(); 1086 if (NULL != child2) c += child2->count(); 1087 return c; 1093 1088 } 1094 1089 1095 1090 f4_node * f4_node::ordNode(int n) 1096 1091 { 1097 int n1;1098 if (0 == n) return this;1099 n--;1100 if (NULL != child) {1101 n1 = child->count();1102 if (n<n1) return child->ordNode(n);1103 n -= n1;1104 }1105 if (NULL != child2) {1106 n1 = child2->count();1107 if (n<n1) return child2->ordNode(n);1108 n -= n1;1109 }1110 return NULL;1092 int n1; 1093 if (0 == n) return this; 1094 n--; 1095 if (NULL != child) { 1096 n1 = child->count(); 1097 if (n < n1) return child->ordNode(n); 1098 n -= n1; 1099 } 1100 if (NULL != child2) { 1101 n1 = child2->count(); 1102 if (n < n1) return child2->ordNode(n); 1103 n -= n1; 1104 } 1105 return NULL; 1111 1106 } 1112 1107 1113 1108 f4_node * f4_node::randomNode() 1114 1109 { 1115 int n, i; 1116 n = count(); 1117 // pick a random node, between 0 and n-1 1118 i = (int)( ((float)n-0.0001) / RAND_MAX * rand()); 1119 return ordNode(i); 1110 int n = count(); 1111 // pick a random node, between 0 and n-1 1112 return ordNode(randomN(n)); 1120 1113 } 1121 1114 1122 1115 f4_node * f4_node::randomNodeWithSize(int min, int max) 1123 1116 { 1124 // try random nodes, and accept if size in range1125 // limit to maxlim tries1126 int i, n, maxlim;1127 f4_node * nod = NULL;1128 maxlim = count();1129 for (i=0; i<maxlim; i++) {1130 nod = randomNode();1131 n = nod->count();1132 if ((n>=min) && (n<=max)) return nod;1133 }1134 // failed, doesn't matter1135 return nod;1117 // try random nodes, and accept if size in range 1118 // limit to maxlim tries 1119 int i, n, maxlim; 1120 f4_node * nod = NULL; 1121 maxlim = count(); 1122 for (i = 0; i < maxlim; i++) { 1123 nod = randomNode(); 1124 n = nod->count(); 1125 if ((n >= min) && (n <= max)) return nod; 1126 } 1127 // failed, doesn't matter 1128 return nod; 1136 1129 } 1137 1130 1138 1131 void f4_node::sprint(SString & out) 1139 1132 { 1140 char buf2[20]; 1141 // special case: repetition code 1142 if ('#' == name) 1143 { 1144 out += "#"; 1145 if (i1 != 1) { 1146 sprintf(buf2, "%d", i1); 1147 out += buf2; 1148 } 1149 } else { 1150 // special case: neuron link 1151 if ('[' == name) { 1152 out += "["; 1153 if (i1>0) { 1154 // sensor input 1155 if (1==i1) out += "*"; 1156 if (2==i1) out += "G"; 1157 if (3==i1) out += "T"; 1158 if (4==i1) out += "S"; 1159 } else { 1160 sprintf(buf2, "%ld", l1); 1161 out += buf2; 1162 } 1163 sprintf(buf2, ":%g]", f1); 1164 out += buf2; 1165 } else if (':' == name) { 1166 sprintf(buf2, ":%c%c:", l1 ? '+' : '-', (char)i1); 1167 out += buf2; 1168 } else { 1169 buf2[0] = name; 1170 buf2[1] = 0; 1171 out += buf2; 1172 }} 1173 if (NULL != child) child->sprint(out); 1174 // if two children, make sure last char is a '>' 1175 if (2 == childCount()) 1176 if (0 == out[0]) out += ">"; else 1177 if ('>' != out[out.len()-1]) out += ">"; 1178 if (NULL != child2) child2->sprint(out); 1179 // make sure last char is a '>' 1180 if (0 == out[0]) out += ">"; else 1181 if ('>' != out[out.len()-1]) out += ">"; 1133 char buf2[20]; 1134 // special case: repetition code 1135 if ('#' == name) 1136 { 1137 out += "#"; 1138 if (i1 != 1) { 1139 sprintf(buf2, "%d", i1); 1140 out += buf2; 1141 } 1142 } 1143 else { 1144 // special case: neuron link 1145 if ('[' == name) { 1146 out += "["; 1147 if (i1 > 0) { 1148 // sensor input 1149 if (1 == i1) out += "*"; 1150 if (2 == i1) out += "G"; 1151 if (3 == i1) out += "T"; 1152 if (4 == i1) out += "S"; 1153 } 1154 else { 1155 sprintf(buf2, "%ld", l1); 1156 out += buf2; 1157 } 1158 sprintf(buf2, ":%g]", f1); 1159 out += buf2; 1160 } 1161 else if (':' == name) { 1162 sprintf(buf2, ":%c%c:", l1 ? '+' : '-', (char)i1); 1163 out += buf2; 1164 } 1165 else { 1166 buf2[0] = name; 1167 buf2[1] = 0; 1168 out += buf2; 1169 } 1170 } 1171 if (NULL != child) child->sprint(out); 1172 // if two children, make sure last char is a '>' 1173 if (2 == childCount()) 1174 if (0 == out[0]) out += ">"; else 1175 if ('>' != out[out.len() - 1]) out += ">"; 1176 if (NULL != child2) child2->sprint(out); 1177 // make sure last char is a '>' 1178 if (0 == out[0]) out += ">"; else 1179 if ('>' != out[out.len() - 1]) out += ">"; 1182 1180 } 1183 1181 1184 1182 void f4_node::sprintAdj(char *& buf) 1185 1183 { 1186 unsigned int len;1187 // build in a SString, with initial size1188 SString out(strlen(buf)+2000);1189 out="";1190 1191 sprint(out);1192 1193 // very last '>' can be omitted1194 len = out.len();1195 if (len>1)1196 if ('>' == out[len-1]) { (out.directWrite())[len-1]=0; out.endWrite();};1197 // copy back to string1198 // if new is longer, reallocate buf1199 if (len+1 > strlen(buf)) {1200 buf = (char*) realloc(buf, len+1);1201 }1202 strcpy(buf, (const char*)out);1184 unsigned int len; 1185 // build in a SString, with initial size 1186 SString out(strlen(buf) + 2000); 1187 out = ""; 1188 1189 sprint(out); 1190 1191 // very last '>' can be omitted 1192 len = out.len(); 1193 if (len > 1) 1194 if ('>' == out[len - 1]) { (out.directWrite())[len - 1] = 0; out.endWrite(); }; 1195 // copy back to string 1196 // if new is longer, reallocate buf 1197 if (len + 1 > strlen(buf)) { 1198 buf = (char*)realloc(buf, len + 1); 1199 } 1200 strcpy(buf, (const char*)out); 1203 1201 } 1204 1202 1205 1203 f4_node * f4_node::duplicate() 1206 1204 { 1207 f4_node * copy;1208 copy = new f4_node(*this);1209 copy->parent = NULL; // set later1210 copy->child= NULL;1211 copy->child2 = NULL;1212 if (NULL != child) {1213 copy->child = child->duplicate();1214 copy->child->parent = copy;1215 }1216 if (NULL != child2) {1217 copy->child2 = child2->duplicate();1218 copy->child2->parent = copy;1219 }1220 return copy;1205 f4_node * copy; 1206 copy = new f4_node(*this); 1207 copy->parent = NULL; // set later 1208 copy->child = NULL; 1209 copy->child2 = NULL; 1210 if (NULL != child) { 1211 copy->child = child->duplicate(); 1212 copy->child->parent = copy; 1213 } 1214 if (NULL != child2) { 1215 copy->child2 = child2->duplicate(); 1216 copy->child2->parent = copy; 1217 } 1218 return copy; 1221 1219 } 1222 1220 … … 1224 1222 void f4_node::destroy() 1225 1223 { 1226 // children are destroyed (recursively) through the destructor1227 if (NULL != child2) delete child2;1228 if (NULL != child) delete child;1224 // children are destroyed (recursively) through the destructor 1225 if (NULL != child2) delete child2; 1226 if (NULL != child) delete child; 1229 1227 } 1230 1228 … … 1234 1232 int f4_processrec(const char * genot, unsigned pos0, f4_node * parent) 1235 1233 { 1236 int i, j, t, res; 1237 char tc1, tc2; 1238 long relfrom; 1239 double w; 1240 unsigned gpos, oldpos; 1241 f4_node * node1, * par; 1242 1243 gpos = pos0; 1244 par = parent; 1245 if (gpos >= strlen(genot) ) return 1; 1246 while (gpos<strlen(genot)) { 1247 //DB( printf(" processing '%c' %d %s\n", genot[gpos], gpos, genot); ) 1248 switch (genot[gpos]) { 1249 case '<': 1250 // cell division! 1251 //DB( printf(" div! %d\n", name); ) 1252 1253 // find out genotype start for child 1254 j = scanrec(genot+gpos+1, strlen(genot+gpos+1), '>'); 1255 1256 node1 = new f4_node('<', par, gpos); 1257 par = node1; 1258 res = f4_processrec(genot, gpos+1, par); 1259 if (res) return res; 1260 if (gpos+j+2 < strlen(genot)) { 1261 res = f4_processrec(genot, gpos+j+2, par); 1262 if (res) return res; 1263 } else { // ran out 1264 node1 = new f4_node('>', par, strlen(genot)-1 ); 1265 par = node1; 1266 } 1267 // adjustments 1268 gpos++; 1269 return 0; // OK 1270 1271 case '>': 1272 node1 = new f4_node('>', par, gpos ); 1273 par = node1; 1274 gpos = strlen(genot); 1275 return 0; // OK 1276 1277 case '#': 1278 // repetition marker, 1 by default 1279 if (sscanf(genot+gpos, "#%d", &i) != 1) i=1; 1280 // find out genotype start for continuation 1281 j = scanrec(genot+gpos+1, strlen(genot+gpos+1), '>'); 1282 // skip number 1283 oldpos = gpos; 1284 gpos++; 1285 while ((genot[gpos]>='0') && (genot[gpos]<='9')) gpos++; 1286 node1 = new f4_node('#', par, oldpos ); 1287 node1->i1 = i; 1288 par = node1; 1289 res = f4_processrec(genot, gpos, node1); 1290 if (res) return res; 1291 if (oldpos+j+2 < strlen(genot) ) { 1292 res = f4_processrec(genot, oldpos+j+2, node1); 1293 if (res) return res; 1294 } else { // ran out 1295 node1 = new f4_node('>', par, strlen(genot)-1 ); 1296 } 1297 return 0; // OK 1298 1299 // 'simple' nodes: 1300 case ',': 1301 case 'l': case 'L': 1302 case 'c': case 'C': 1303 case 'q': case 'Q': 1304 case 'r': case 'R': 1305 case 'X': case 'N': 1306 case '@': case '|': 1307 case 'a': case 'A': 1308 case 's': case 'S': 1309 case 'm': case 'M': 1310 case 'i': case 'I': 1311 case 'f': case 'F': 1312 case 'w': case 'W': 1313 case 'e': case 'E': 1314 node1 = new f4_node(genot[gpos], par, gpos ); 1315 par = node1; 1316 gpos++; 1317 break; 1318 1319 case '[': 1320 // link to neuron 1321 // input (%d, '*', 'G', 'T', 'S') 1322 t = -1; 1323 if (sscanf(genot+gpos, "[%ld:%lf]", &relfrom, &w) == 2) t=0; 1324 else if (sscanf(genot+gpos, "[*:%lf]", &w) == 1) t=1; 1325 else if (sscanf(genot+gpos, "[G:%lf]", &w) == 1) t=2; 1326 else if (sscanf(genot+gpos, "[T:%lf]", &w) == 1) t=3; 1327 else if (sscanf(genot+gpos, "[S:%lf]", &w) == 1) t=4; 1328 // error: no correct format 1329 if (t<0) return gpos+1+1; 1330 node1 = new f4_node('[', par, gpos ); 1331 node1->i1 = t; 1332 node1->l1 = relfrom; 1333 node1->f1 = w; 1334 par = node1; 1335 j = scanrec(genot+gpos+1, strlen(genot+gpos+1), ']'); 1336 gpos += j+2; 1337 break; 1338 1339 case ':': 1340 // neuron parameter +! -! += -= +/ or -/ 1341 if (sscanf(genot+gpos, ":%c%c:", &tc1, &tc2) != 2) 1342 // error: incorrect format 1343 return gpos+1+1; 1344 if ('+' == tc1) j=1; 1345 else if ('-' == tc1) j=0; 1346 else return gpos+1+1; 1347 switch (tc2) { 1348 case '!': case '=': case '/': break; 1349 default: 1350 return gpos+1+1; 1351 } 1352 node1 = new f4_node(':', par, gpos ); 1353 node1->l1 = j; 1354 node1->i1 = (int)tc2; 1355 par = node1; 1356 j = scanrec(genot+gpos+1, strlen(genot+gpos+1), ':'); 1357 gpos += j+2; 1358 break; 1359 1360 case ' ': 1361 case '\n': 1362 case '\t': 1363 // whitespace: ignore 1364 //node1 = new f4_node(' ', par, gpos ); 1365 //par = node1; 1366 gpos++; 1367 break; 1368 1369 default: 1370 //DB( printf("unknown character '%c' ! \n", genot[gpos]); ) 1371 //add it, build will give the error or repair 1372 node1 = new f4_node(genot[gpos], par, gpos ); 1373 par = node1; 1374 gpos++; 1375 break; 1376 } 1377 } 1378 // should end with a '>' 1379 if (par) 1380 if ('>' != par->name) { 1381 node1 = new f4_node('>', par, strlen(genot)-1 ); 1382 par = node1; 1383 } 1384 return 0; // OK 1234 int i, j, t, res; 1235 char tc1, tc2; 1236 long relfrom; 1237 double w; 1238 unsigned gpos, oldpos; 1239 f4_node * node1, *par; 1240 1241 gpos = pos0; 1242 par = parent; 1243 if (gpos >= strlen(genot)) return 1; 1244 while (gpos < strlen(genot)) { 1245 //DB( printf(" processing '%c' %d %s\n", genot[gpos], gpos, genot); ) 1246 switch (genot[gpos]) { 1247 case '<': 1248 // cell division! 1249 //DB( printf(" div! %d\n", name); ) 1250 1251 // find out genotype start for child 1252 j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>'); 1253 1254 node1 = new f4_node('<', par, gpos); 1255 par = node1; 1256 res = f4_processrec(genot, gpos + 1, par); 1257 if (res) return res; 1258 if (gpos + j + 2 < strlen(genot)) { 1259 res = f4_processrec(genot, gpos + j + 2, par); 1260 if (res) return res; 1261 } 1262 else { // ran out 1263 node1 = new f4_node('>', par, strlen(genot) - 1); 1264 par = node1; 1265 } 1266 // adjustments 1267 gpos++; 1268 return 0; // OK 1269 1270 case '>': 1271 node1 = new f4_node('>', par, gpos); 1272 par = node1; 1273 gpos = strlen(genot); 1274 return 0; // OK 1275 1276 case '#': 1277 // repetition marker, 1 by default 1278 if (sscanf(genot + gpos, "#%d", &i) != 1) i = 1; 1279 // find out genotype start for continuation 1280 j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>'); 1281 // skip number 1282 oldpos = gpos; 1283 gpos++; 1284 while ((genot[gpos] >= '0') && (genot[gpos] <= '9')) gpos++; 1285 node1 = new f4_node('#', par, oldpos); 1286 node1->i1 = i; 1287 par = node1; 1288 res = f4_processrec(genot, gpos, node1); 1289 if (res) return res; 1290 if (oldpos + j + 2 < strlen(genot)) { 1291 res = f4_processrec(genot, oldpos + j + 2, node1); 1292 if (res) return res; 1293 } 1294 else { // ran out 1295 node1 = new f4_node('>', par, strlen(genot) - 1); 1296 } 1297 return 0; // OK 1298 1299 // 'simple' nodes: 1300 case ',': 1301 case 'l': case 'L': 1302 case 'c': case 'C': 1303 case 'q': case 'Q': 1304 case 'r': case 'R': 1305 case 'X': case 'N': 1306 case '@': case '|': 1307 case 'a': case 'A': 1308 case 's': case 'S': 1309 case 'm': case 'M': 1310 case 'i': case 'I': 1311 case 'f': case 'F': 1312 case 'w': case 'W': 1313 case 'e': case 'E': 1314 node1 = new f4_node(genot[gpos], par, gpos); 1315 par = node1; 1316 gpos++; 1317 break; 1318 1319 case '[': 1320 // link to neuron 1321 // input (%d, '*', 'G', 'T', 'S') 1322 t = -1; 1323 if (sscanf(genot + gpos, "[%ld:%lf]", &relfrom, &w) == 2) t = 0; 1324 else if (sscanf(genot + gpos, "[*:%lf]", &w) == 1) t = 1; 1325 else if (sscanf(genot + gpos, "[G:%lf]", &w) == 1) t = 2; 1326 else if (sscanf(genot + gpos, "[T:%lf]", &w) == 1) t = 3; 1327 else if (sscanf(genot + gpos, "[S:%lf]", &w) == 1) t = 4; 1328 // error: no correct format 1329 if (t < 0) return gpos + 1 + 1; 1330 node1 = new f4_node('[', par, gpos); 1331 node1->i1 = t; 1332 node1->l1 = relfrom; 1333 node1->f1 = w; 1334 par = node1; 1335 j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ']'); 1336 gpos += j + 2; 1337 break; 1338 1339 case ':': 1340 // neuron parameter +! -! += -= +/ or -/ 1341 if (sscanf(genot + gpos, ":%c%c:", &tc1, &tc2) != 2) 1342 // error: incorrect format 1343 return gpos + 1 + 1; 1344 if ('+' == tc1) j = 1; 1345 else if ('-' == tc1) j = 0; 1346 else return gpos + 1 + 1; 1347 switch (tc2) { 1348 case '!': case '=': case '/': break; 1349 default: 1350 return gpos + 1 + 1; 1351 } 1352 node1 = new f4_node(':', par, gpos); 1353 node1->l1 = j; 1354 node1->i1 = (int)tc2; 1355 par = node1; 1356 j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ':'); 1357 gpos += j + 2; 1358 break; 1359 1360 case ' ': 1361 case '\n': 1362 case '\t': 1363 // whitespace: ignore 1364 //node1 = new f4_node(' ', par, gpos ); 1365 //par = node1; 1366 gpos++; 1367 break; 1368 1369 default: 1370 //DB( printf("unknown character '%c' ! \n", genot[gpos]); ) 1371 //add it, build will give the error or repair 1372 node1 = new f4_node(genot[gpos], par, gpos); 1373 par = node1; 1374 gpos++; 1375 break; 1376 } 1377 } 1378 // should end with a '>' 1379 if (par) 1380 if ('>' != par->name) { 1381 node1 = new f4_node('>', par, strlen(genot) - 1); 1382 par = node1; 1383 } 1384 return 0; // OK 1385 1385 } 1386 1386 … … 1388 1388 f4_node * f4_processtree(const char * geno) 1389 1389 { 1390 f4_node * root; 1391 int res; 1392 root = new f4_node(); 1393 res = f4_processrec(geno, 0, root); 1394 if (res) return NULL; 1395 //DB( printf("test f4 "); ) 1396 DB( 1397 if (root->child) { 1398 char * buf = (char*) malloc( 300 ); 1399 DB( printf("(%d) ", root->child->count() ); ) 1400 buf[0]=0; 1401 root->child->sprintAdj(buf); 1402 DB( printf("%s\n", buf); ) 1403 free(buf); 1404 } 1405 ) 1406 return root->child; 1407 } 1408 1390 f4_node * root; 1391 int res; 1392 root = new f4_node(); 1393 res = f4_processrec(geno, 0, root); 1394 if (res) return NULL; 1395 //DB( printf("test f4 "); ) 1396 DB( 1397 if (root->child) { 1398 char * buf = (char*)malloc(300); 1399 DB(printf("(%d) ", root->child->count());) 1400 buf[0] = 0; 1401 root->child->sprintAdj(buf); 1402 DB(printf("%s\n", buf);) 1403 free(buf); 1404 } 1405 ) 1406 return root->child; 1407 } -
cpp/frams/genetics/f4/f4_general.h
r193 r196 1 /* 2 * f4_general.h - f4 genotype functions. 3 * 4 * f4genotype - f4 format genotype conversions for FramSticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 23 6 24 7 #ifndef _F4_GENERAL_H_ 25 8 #define _F4_GENERAL_H_ 26 9 27 #include "f4_orientmat.h"28 #include "3d.h"29 #include "sstring.h"30 #include "multirange.h"10 //#include "f4_orientmat.h" 11 #include <frams/util/3d.h> 12 #include <frams/util/sstring.h> 13 #include <frams/util/multirange.h> 31 14 32 15 #ifdef DMALLOC … … 37 20 class f4_Props 38 21 { 39 public:40 // fill with default values41 f4_Props();42 // must sum to 143 void normalizeBiol4();44 void executeModifier(char modif);45 void adjust();46 47 double len; // length (dlug)48 double curv; // curvedness (skr)49 double mass;50 double friction;51 double ruch;52 double assim;53 double odpor;54 double ingest; // ingestion (wchl)55 double twist;56 double energ;22 public: 23 // fill with default values 24 f4_Props(); 25 // must sum to 1 26 void normalizeBiol4(); 27 void executeModifier(char modif); 28 void adjust(); 29 30 double len; // length (dlug) 31 double curv; // curvedness (skr) 32 double mass; 33 double friction; 34 double ruch; 35 double assim; 36 double odpor; 37 double ingest; // ingestion (wchl) 38 double twist; 39 double energ; 57 40 }; 58 41 … … 85 68 { 86 69 public: 87 class repeat_ptr88 {89 public:90 repeat_ptr() : node(NULL), count(-1) { };91 repeat_ptr(f4_node * a, int b) : node(a), count(b) { };92 inline void null() { node = NULL; count = -1; };93 inline bool isNull() const { return ((node == NULL) || (count <= 0)); };94 inline void dec() { count--; };95 f4_node * node; // ptr to repetition code96 char count; // repetition counter97 };98 99 class repeat_stack // a stack of repet_ptr's100 {101 public:102 repeat_stack() { top=0; };103 inline void null() { top=0; };104 inline void push(repeat_ptr A) { if (top>=stackSize) return; ptr[top]=A; top++; };105 inline void pop() { if (top>0) top--; };106 inline repeat_ptr * first() { return &(ptr[top-(top>0)]); };107 static const int stackSize = 4; // max 4 nested levels108 repeat_ptr ptr[stackSize];109 short int top; // top of the stack110 };111 112 f4_Cell(int nname,113 f4_Cell * ndad, int nangle, f4_Props newP);114 f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur,115 f4_Cell * ndad, int nangle, f4_Props newP);116 ~f4_Cell();117 118 int onestep(); // execute one simulation step (till a division)119 120 int addlink(f4_Cell * nfrom, double nw, long nt);121 void adjustRec();122 123 int name; // name (number)124 int type; // type125 f4_Cell * dadlink;126 f4_Cells * org; // uplink to organism127 128 f4_node * genot; // genotype129 f4_node * gcur; // current genotype execution pointer130 int active; // whether development is still active131 repeat_stack repeat;132 int recProcessedFlag; // used during recursive traverse133 // remember the genotype codes affecting this cell so far134 MultiRange genoRange;135 136 f4_Props P; // properties137 int anglepos; // number of position within dad's children (,)138 int childcount; // number of children139 int commacount; // number of postitions at lastend (>=childcount)140 double rolling; // rolling angle ('R') (around x)141 double xrot;142 double zrot; // horizontal rotation angle due to143 // branching (around z)144 //Pt3D firstend; // coord.s of first end (connects to parent)145 //Pt3D lastend; // last end146 //f4_OrientMat OM;147 double mz; // freedom in z148 long p2_refno; // number of last end part object, used in f0149 long joint_refno; // number of the joint object, used in f0150 long neuro_refno; // number of the neuro object, used in f0151 152 long ctrl; // neuron type153 double state;154 double inertia;155 double force;156 double sigmo;157 f4_CellLink* links[MAXINPUTS];158 int nolink;70 class repeat_ptr 71 { 72 public: 73 repeat_ptr() : node(NULL), count(-1) { }; 74 repeat_ptr(f4_node * a, int b) : node(a), count(b) { }; 75 inline void null() { node = NULL; count = -1; }; 76 inline bool isNull() const { return ((node == NULL) || (count <= 0)); }; 77 inline void dec() { count--; }; 78 f4_node * node; // ptr to repetition code 79 char count; // repetition counter 80 }; 81 82 class repeat_stack // a stack of repet_ptr's 83 { 84 public: 85 repeat_stack() { top = 0; }; 86 inline void null() { top = 0; }; 87 inline void push(repeat_ptr A) { if (top >= stackSize) return; ptr[top] = A; top++; }; 88 inline void pop() { if (top > 0) top--; }; 89 inline repeat_ptr * first() { return &(ptr[top - (top > 0)]); }; 90 static const int stackSize = 4; // max 4 nested levels 91 repeat_ptr ptr[stackSize]; 92 short int top; // top of the stack 93 }; 94 95 f4_Cell(int nname, 96 f4_Cell * ndad, int nangle, f4_Props newP); 97 f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur, 98 f4_Cell * ndad, int nangle, f4_Props newP); 99 ~f4_Cell(); 100 101 int onestep(); // execute one simulation step (till a division) 102 103 int addlink(f4_Cell * nfrom, double nw, long nt); 104 void adjustRec(); 105 106 int name; // name (number) 107 int type; // type 108 f4_Cell * dadlink; 109 f4_Cells * org; // uplink to organism 110 111 f4_node * genot; // genotype 112 f4_node * gcur; // current genotype execution pointer 113 int active; // whether development is still active 114 repeat_stack repeat; 115 int recProcessedFlag; // used during recursive traverse 116 // remember the genotype codes affecting this cell so far 117 MultiRange genoRange; 118 119 f4_Props P; // properties 120 int anglepos; // number of position within dad's children (,) 121 int childcount; // number of children 122 int commacount; // number of postitions at lastend (>=childcount) 123 double rolling; // rolling angle ('R') (around x) 124 double xrot; 125 double zrot; // horizontal rotation angle due to 126 // branching (around z) 127 //Pt3D firstend; // coord.s of first end (connects to parent) 128 //Pt3D lastend; // last end 129 //f4_OrientMat OM; 130 double mz; // freedom in z 131 long p2_refno; // number of last end part object, used in f0 132 long joint_refno; // number of the joint object, used in f0 133 long neuro_refno; // number of the neuro object, used in f0 134 135 long ctrl; // neuron type 136 double state; 137 double inertia; 138 double force; 139 double sigmo; 140 f4_CellLink* links[MAXINPUTS]; 141 int nolink; 159 142 }; 160 143 … … 164 147 { 165 148 public: 166 f4_CellLink(f4_Cell * nfrom, double nw, long nt);167 f4_Cell * from;168 // type: 0: input, 1 '*', 2 'G', 3 'T', 4 'S'169 long t;170 double w;149 f4_CellLink(f4_Cell * nfrom, double nw, long nt); 150 f4_Cell * from; 151 // type: 0: input, 1 '*', 2 'G', 3 'T', 4 'S' 152 long t; 153 double w; 171 154 }; 172 155 … … 176 159 class f4_Cells 177 160 { 178 public:179 f4_Cells(f4_node * genome, int nrepair);180 f4_Cells(SString &genome, int nrepair);181 ~f4_Cells();182 void addCell(f4_Cell * newcell);183 void toF1Geno(SString &out); // output to f1 format, approximation184 int onestep(); // simulate all parts for one step185 int simulate(); // simulate development, return error (0 for ok)186 // for error reporting / genotype fixing187 int geterror() { return error;};188 int geterrorpos() { return errorpos;};189 void setError(int nerrpos);190 void setRepairRemove(int nerrpos, f4_node * rem);191 int setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert);192 void repairGeno(f4_node * geno, int whichchild);193 194 // the cells195 f4_Cell * C[MAX4CELLS];196 int nc;161 public: 162 f4_Cells(f4_node * genome, int nrepair); 163 f4_Cells(SString &genome, int nrepair); 164 ~f4_Cells(); 165 void addCell(f4_Cell * newcell); 166 void toF1Geno(SString &out); // output to f1 format, approximation 167 int onestep(); // simulate all parts for one step 168 int simulate(); // simulate development, return error (0 for ok) 169 // for error reporting / genotype fixing 170 int geterror() { return error; }; 171 int geterrorpos() { return errorpos; }; 172 void setError(int nerrpos); 173 void setRepairRemove(int nerrpos, f4_node * rem); 174 int setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert); 175 void repairGeno(f4_node * geno, int whichchild); 176 177 // the cells 178 f4_Cell * C[MAX4CELLS]; 179 int nc; 197 180 198 181 private: 199 // for error reporting / genotype fixing200 int repair;201 int error;202 int errorpos;203 f4_node * repair_remove;204 f4_node * repair_parent;205 f4_node * repair_insert;206 void toF1GenoRec(int curc, SString &out);207 f4_Cell * tmpcel; // needed by toF1Geno208 f4_node * f4rootnode; // used by constructor182 // for error reporting / genotype fixing 183 int repair; 184 int error; 185 int errorpos; 186 f4_node * repair_remove; 187 f4_node * repair_parent; 188 f4_node * repair_insert; 189 void toF1GenoRec(int curc, SString &out); 190 f4_Cell * tmpcel; // needed by toF1Geno 191 f4_node * f4rootnode; // used by constructor 209 192 }; 210 193 … … 216 199 { 217 200 public: 218 char name; // one-letter 'name'219 f4_node * parent; // parent link, or NULL220 f4_node * child; // child, or NULL221 f4_node * child2; // second child, or NULL222 int pos; // original position in string223 int i1; // internal int parameter1224 long l1; // internal long parameter1225 double f1; // internal double parameter1226 227 f4_node();228 f4_node(char nname, f4_node * nparent, int npos);229 ~f4_node();230 int addChild(f4_node * nchi);231 int removeChild(f4_node * nchi);232 int childCount(); // return no of children, 0, 1, or 2233 int count(); // return no of nodes (recursive)234 f4_node * ordNode(int n); // returns the nth subnode (0-)235 f4_node * randomNode(); // returns a random subnode236 f4_node * randomNodeWithSize(int min, int max); // returns a random subnode with given size237 void sprintAdj(char *& buf); // print recursively238 f4_node * duplicate(); // create duplicate copy. recursive.239 void destroy(); // release memory. recursive.201 char name; // one-letter 'name' 202 f4_node * parent; // parent link, or NULL 203 f4_node * child; // child, or NULL 204 f4_node * child2; // second child, or NULL 205 int pos; // original position in string 206 int i1; // internal int parameter1 207 long l1; // internal long parameter1 208 double f1; // internal double parameter1 209 210 f4_node(); 211 f4_node(char nname, f4_node * nparent, int npos); 212 ~f4_node(); 213 int addChild(f4_node * nchi); 214 int removeChild(f4_node * nchi); 215 int childCount(); // return no of children, 0, 1, or 2 216 int count(); // return no of nodes (recursive) 217 f4_node * ordNode(int n); // returns the nth subnode (0-) 218 f4_node * randomNode(); // returns a random subnode 219 f4_node * randomNodeWithSize(int min, int max); // returns a random subnode with given size 220 void sprintAdj(char *& buf); // print recursively 221 f4_node * duplicate(); // create duplicate copy. recursive. 222 void destroy(); // release memory. recursive. 240 223 private: 241 void sprint(SString & out); // print recursively224 void sprint(SString & out); // print recursively 242 225 }; 243 226 -
cpp/frams/genetics/f4/oper_f4.cpp
r193 r196 1 /* 2 * geno_f4.cpp - f4 genetic operators. 3 * 4 * f4genotype - f4 format genotype conversions for FramSticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * Copyright (C) 2001-2004 Maciej Komosinski 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25 #include "geno_f4.h" 26 #include "nonstd.h" 27 #include "sstring.h" 28 #include "framsg.h" 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 // Copyright (C) since 2001 Maciej Komosinski 7 8 #include "oper_f4.h" 9 #include <frams/util/sstring.h> 10 #include <common/framsg.h> 29 11 30 12 #include <stdio.h> 31 13 #include <stdlib.h> 32 #include <math.h>14 #include "common/nonstd_math.h" 33 15 #include <string.h> 34 16 … … 36 18 #define FIELDSTRUCT Geno_f4 37 19 38 static ParamEntry GENO4param_tab[] =39 { 40 {"Genetics: f4",1,F4_COUNT+F4_ADD_COUNT,},41 {"f4_mut_add", 0, 0, "Add node", "f 0 100 50", FIELD(prob[F4_ADD]),"mutation: probability of adding a node", },42 {"f4_mut_add_div", 0, 0, "- add division", "f 0 100 20", FIELD(probadd[F4_ADD_DIV]),"add node mutation: probability of adding a division", },43 {"f4_mut_add_conn", 0, 0, "- add connection", "f 0 100 15", FIELD(probadd[F4_ADD_CONN]),"add node mutation: probability of adding a neural connection", },44 {"f4_mut_add_neupar", 0, 0, "- add neuron property", "f 0 100 5", FIELD(probadd[F4_ADD_NEUPAR]),"add node mutation: probability of adding a neuron property/modifier", },45 {"f4_mut_add_rep", 0, 0, "- add repetition", "f 0 100 10",FIELD(probadd[F4_ADD_REP]),"add node mutation: probability of adding a repetition", },46 {"f4_mut_add_simp", 0, 0, "- add simple node", "f 0 100 50",FIELD(probadd[F4_ADD_SIMP]),"add node mutation: probability of adding a random, simple gene", },47 {"f4_mut_del", 0, 0, "Delete node", "f 0 100 20", FIELD(prob[F4_DEL]),"mutation: probability of deleting a node", },48 {"f4_mut_mod", 0, 0, "Modify node", "f 0 100 30", FIELD(prob[F4_MOD]),"mutation: probability of changing a node", },49 {0,},20 static ParamEntry GENO4param_tab[] = 21 { 22 { "Genetics: f4", 1, F4_COUNT + F4_ADD_COUNT, }, 23 { "f4_mut_add", 0, 0, "Add node", "f 0 100 50", FIELD(prob[F4_ADD]), "mutation: probability of adding a node", }, 24 { "f4_mut_add_div", 0, 0, "- add division", "f 0 100 20", FIELD(probadd[F4_ADD_DIV]), "add node mutation: probability of adding a division", }, 25 { "f4_mut_add_conn", 0, 0, "- add connection", "f 0 100 15", FIELD(probadd[F4_ADD_CONN]), "add node mutation: probability of adding a neural connection", }, 26 { "f4_mut_add_neupar", 0, 0, "- add neuron property", "f 0 100 5", FIELD(probadd[F4_ADD_NEUPAR]), "add node mutation: probability of adding a neuron property/modifier", }, 27 { "f4_mut_add_rep", 0, 0, "- add repetition", "f 0 100 10", FIELD(probadd[F4_ADD_REP]), "add node mutation: probability of adding a repetition", }, 28 { "f4_mut_add_simp", 0, 0, "- add simple node", "f 0 100 50", FIELD(probadd[F4_ADD_SIMP]), "add node mutation: probability of adding a random, simple gene", }, 29 { "f4_mut_del", 0, 0, "Delete node", "f 0 100 20", FIELD(prob[F4_DEL]), "mutation: probability of deleting a node", }, 30 { "f4_mut_mod", 0, 0, "Modify node", "f 0 100 30", FIELD(prob[F4_MOD]), "mutation: probability of changing a node", }, 31 { 0, }, 50 32 }; 51 33 … … 55 37 Geno_f4::Geno_f4() 56 38 { 57 supported_format='4';58 par.setParamTab(GENO4param_tab);59 par.select(this);60 par.setDefault();61 62 mutation_method_names=new char*[F4_COUNT+F4_ADD_COUNT-1];63 int index=0;64 mutation_method_names[index++]="added division";65 mutation_method_names[index++]="added neural connection";66 mutation_method_names[index++]="added neuron property";67 mutation_method_names[index++]="added repetition gene";68 mutation_method_names[index++]="added a simple node";69 mutation_method_names[index++]="deleted a node";70 mutation_method_names[index++]="modified a node";71 if (index!=F4_COUNT+F4_ADD_COUNT-1) FramMessage("Geno_f4","Constructor","Mutation names init error",3);39 supported_format = '4'; 40 par.setParamTab(GENO4param_tab); 41 par.select(this); 42 par.setDefault(); 43 44 mutation_method_names = new char*[F4_COUNT + F4_ADD_COUNT - 1]; 45 int index = 0; 46 mutation_method_names[index++] = "added division"; 47 mutation_method_names[index++] = "added neural connection"; 48 mutation_method_names[index++] = "added neuron property"; 49 mutation_method_names[index++] = "added repetition gene"; 50 mutation_method_names[index++] = "added a simple node"; 51 mutation_method_names[index++] = "deleted a node"; 52 mutation_method_names[index++] = "modified a node"; 53 if (index != F4_COUNT + F4_ADD_COUNT - 1) FramMessage("Geno_f4", "Constructor", "Mutation names init error", 3); 72 54 } 73 55 74 56 int Geno_f4::ValidateRec(f4_node * geno, int retrycount) const 75 57 { 76 // ! the genotype is geno->child (not geno) !77 // build from it with repair on78 79 f4_Cells cells(geno->child, 1);80 cells.simulate(); //we should simulate?!81 82 // errors not fixed:83 if (GENOPER_OPFAIL == cells.geterror())84 {85 if (cells.geterrorpos() >= 0) return 1+cells.geterrorpos();86 return GENOPER_OPFAIL;87 }88 // errors can be fixed89 if (GENOPER_REPAIR == cells.geterror())90 {91 cells.repairGeno(geno, 1);92 // note: geno might have been fixed93 // check again94 int res2 = GENOPER_OK;95 if (retrycount>0)96 res2 = ValidateRec( geno, retrycount-1);97 98 if (res2==GENOPER_OK) return GENOPER_REPAIR;99 return res2;100 }101 // no errors:102 return GENOPER_OK;58 // ! the genotype is geno->child (not geno) ! 59 // build from it with repair on 60 61 f4_Cells cells(geno->child, 1); 62 cells.simulate(); //we should simulate?! 63 64 // errors not fixed: 65 if (GENOPER_OPFAIL == cells.geterror()) 66 { 67 if (cells.geterrorpos() >= 0) return 1 + cells.geterrorpos(); 68 return GENOPER_OPFAIL; 69 } 70 // errors can be fixed 71 if (GENOPER_REPAIR == cells.geterror()) 72 { 73 cells.repairGeno(geno, 1); 74 // note: geno might have been fixed 75 // check again 76 int res2 = GENOPER_OK; 77 if (retrycount > 0) 78 res2 = ValidateRec(geno, retrycount - 1); 79 80 if (res2 == GENOPER_OK) return GENOPER_REPAIR; 81 return res2; 82 } 83 // no errors: 84 return GENOPER_OK; 103 85 } 104 86 … … 106 88 int Geno_f4::validate(char *& geno) 107 89 { 108 // convert geno to tree, then try to validate 20 times109 f4_node root;110 if (f4_processrec(geno, 0, &root) || root.childCount()!=1) return GENOPER_OK; // cannot repair111 if (ValidateRec( &root, 20 )==GENOPER_REPAIR) // if repaired, make it back to string112 {113 geno[0]=0;114 root.child->sprintAdj(geno);115 }116 return GENOPER_OK;90 // convert geno to tree, then try to validate 20 times 91 f4_node root; 92 if (f4_processrec(geno, 0, &root) || root.childCount() != 1) return GENOPER_OK; // cannot repair 93 if (ValidateRec(&root, 20) == GENOPER_REPAIR) // if repaired, make it back to string 94 { 95 geno[0] = 0; 96 root.child->sprintAdj(geno); 97 } 98 return GENOPER_OK; 117 99 } 118 100 … … 120 102 int Geno_f4::checkValidity(const char * geno) 121 103 { 122 f4_node root; 123 int res = f4_processrec(geno, 0, &root); 124 if (res) return res; // errorpos, >0 125 if (root.childCount()!=1) return 1; //earlier: GENOPER_OPFAIL 126 f4_Cells cells( root.child, 0); 127 cells.simulate(); 128 if (cells.geterror()==GENOPER_OPFAIL || cells.geterror()==GENOPER_REPAIR) 129 { 130 if (cells.geterrorpos() >= 0) return 1+cells.geterrorpos(); 131 else return 1; //earlier: GENOPER_OPFAIL; 132 } else return GENOPER_OK; 133 } 134 135 136 int Geno_f4::MutateOne(f4_node *& g,int &method) const 137 { 138 // ! the genotype is g->child (not g) ! 139 140 // codes that can be changed (apart being added/deleted) 141 #define MUT_CHAN_CODES "<[#" 142 #define ADD_SIMPLE_CODES ",XlLcCrRaAiIsSmMfFwWeEN@|" 143 #define REP_MAXCOUNT 19 144 145 f4_node * n1, * n2, * n3, * n4, * n5; 146 int i, j; 147 148 // do the mutation 149 // pick a random node 150 n1 = g->child->randomNode(); 151 //DB( printf("%c\n", n1->name); ) 152 153 switch(roulette(prob,F4_COUNT)) 154 { 155 case F4_ADD: 156 { 157 // add a node 158 switch(method=roulette(probadd,F4_ADD_COUNT)) 159 { 160 case F4_ADD_DIV: 161 { 162 // add division ('<') 163 n3 = n1->parent; 164 n3->removeChild(n1); 165 n2 = new f4_node('<', n3, n3->pos ); 166 n2->addChild(n1); 167 // new cell is stick or neuron 168 // "X>" or "N>" 169 double pr = rnd01; 170 pr -= 0.5; 171 if (pr<0) n3 = new f4_node('X', n2, n2->pos); 172 else 173 { 174 pr -= 0.5; 175 if (pr<0) 176 { 177 // if neuron, make muscle and add a link 178 n3 = new f4_node('N', n2, n2->pos); 179 if (randomN(2) == 0) 180 n4 = new f4_node('|', n3, n2->pos); 181 else 182 n4 = new f4_node('@', n3, n2->pos); 183 n5 = new f4_node('[', n4, n2->pos); 184 linkNodeMakeRandom(n5); 185 } 186 } 187 new f4_node('>', n3, n3->pos); 188 n1->parent = n2; 189 // now with 50% chance swap children 190 if (randomN(2) == 0) 191 { 192 n3 = n2->child; 193 n2->child = n2->child2; 194 n2->child2 = n3; 195 } 196 } 197 break; 198 case F4_ADD_CONN: 199 { 200 // add link 201 n1->parent->removeChild(n1); 202 n2 = new f4_node('[', n1->parent, n1->parent->pos); 203 linkNodeMakeRandom(n2); 204 n2->addChild(n1); 205 n1->parent = n2; 206 } 207 break; 208 case F4_ADD_NEUPAR: 209 { 210 // add neuron modifier 211 n1->parent->removeChild(n1); 212 n2 = new f4_node(':', n1->parent, n1->parent->pos); 213 nparNodeMakeRandom(n2); 214 n2->addChild(n1); 215 n1->parent = n2; 216 } 217 break; 218 case F4_ADD_REP: 219 { 220 // add repetition ('#') 221 // repeated code (left child) is the original, right child is empty, count is 2 222 n3 = n1->parent; 223 n3->removeChild(n1); 224 n2 = new f4_node('#', n3, n3->pos ); 225 n2->i1 = 2; 226 n2->addChild(n1); 227 new f4_node('>', n2, n2->pos); 228 n1->parent = n2; 229 } 230 break; 231 case F4_ADD_SIMP: 232 { 233 // add simple node 234 // choose a simple node from ADD_SIMPLE_CODES 235 n1->parent->removeChild(n1); 236 n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos ); 237 n2->addChild(n1); 238 n1->parent = n2; 239 } 240 break; 241 } 242 } 243 break; 244 245 case F4_DEL: 246 { 247 method=F4_ADD_COUNT-1+F4_DEL; 248 // delete a node 249 // must pick a node with parent, and at least one child 250 // already picked a node, but repeat may be needed 251 for (i=0; i<10; i++) { 252 if ((NULL != n1->parent) && (g != n1->parent)) 253 if (NULL != n1->child) 254 break; 255 // try a new one 256 n1 = g->child->randomNode(); 257 } 258 if ((NULL != n1->parent) && (g != n1->parent)) 259 { 260 switch (n1->childCount()) 261 { 262 case 0: break; 263 case 1: // one child 264 { 265 n2 = n1->parent; 266 n2->removeChild(n1); 267 if (NULL != n1->child) { 268 n1->child->parent = n2; 269 n2->addChild(n1->child); 270 n1->child = NULL; 271 } 272 if (NULL != n1->child2) { 273 n1->child2->parent = n2; 274 n2->addChild(n1->child2); 275 n1->child2 = NULL; 276 } 277 // destroy n1 278 n1->parent=NULL; 279 delete n1; 280 } 281 break; 282 283 case 2: // two children 284 { 285 // two children 286 n2 = n1->parent; 287 n2->removeChild(n1); 288 // n1 has two children. pick one randomly 50-50, destroy other 289 if (randomN(2) == 0) 290 { 291 n1->child->parent = n2; 292 n2->addChild(n1->child); 293 n1->child = NULL; 294 n1->child2->parent = NULL; 295 } else 296 { 297 n1->child2->parent = n2; 298 n2->addChild(n1->child2); 299 n1->child2 = NULL; 300 n1->child->parent = NULL; 301 } 302 // destroy n1 303 n1->parent=NULL; 304 delete n1; 305 } 306 break; 307 } 308 } else return GENOPER_OPFAIL; 309 } 310 break; 311 case F4_MOD: 312 { 313 method=F4_ADD_COUNT-1+F4_MOD; 314 // change a node 315 // the only nodes that are modifiable are MUT_CHAN_CODES 316 // try to get a modifiable node 317 // already picked a node, but repeat may be needed 318 i=0; 319 while (1) 320 { 321 if (strchr(MUT_CHAN_CODES, n1->name)) break; 322 // try a new one 323 n1 = g->child->randomNode(); 324 i++; 325 if (i>=20) return GENOPER_OPFAIL; 326 } 327 switch (n1->name) { 328 case '<': 329 // swap children 330 n2 = n1->child; n1->child = n1->child2; n1->child2 = n2; 331 break; 332 case '[': 333 linkNodeChangeRandom(n1); 334 break; 335 case '#': 336 repeatNodeChangeRandom(n1); 337 break; 338 } 339 } 340 break; 341 342 default: //no mutations allowed? 343 return GENOPER_OPFAIL; 344 } 345 346 return GENOPER_OK; 104 f4_node root; 105 int res = f4_processrec(geno, 0, &root); 106 if (res) return res; // errorpos, >0 107 if (root.childCount() != 1) return 1; //earlier: GENOPER_OPFAIL 108 f4_Cells cells(root.child, 0); 109 cells.simulate(); 110 if (cells.geterror() == GENOPER_OPFAIL || cells.geterror() == GENOPER_REPAIR) 111 { 112 if (cells.geterrorpos() >= 0) return 1 + cells.geterrorpos(); 113 else return 1; //earlier: GENOPER_OPFAIL; 114 } 115 else return GENOPER_OK; 116 } 117 118 119 int Geno_f4::MutateOne(f4_node *& g, int &method) const 120 { 121 // ! the genotype is g->child (not g) ! 122 123 // codes that can be changed (apart being added/deleted) 124 #define MUT_CHAN_CODES "<[#" 125 #define ADD_SIMPLE_CODES ",XlLcCrRaAiIsSmMfFwWeEN@|" 126 #define REP_MAXCOUNT 19 127 128 f4_node * n1, *n2, *n3, *n4, *n5; 129 130 // do the mutation 131 // pick a random node 132 n1 = g->child->randomNode(); 133 //DB( printf("%c\n", n1->name); ) 134 135 switch (roulette(prob, F4_COUNT)) 136 { 137 case F4_ADD: 138 { 139 // add a node 140 switch (method = roulette(probadd, F4_ADD_COUNT)) 141 { 142 case F4_ADD_DIV: 143 { 144 // add division ('<') 145 n3 = n1->parent; 146 n3->removeChild(n1); 147 n2 = new f4_node('<', n3, n3->pos); 148 n2->addChild(n1); 149 // new cell is stick or neuron 150 // "X>" or "N>" 151 double pr = rnd01; 152 pr -= 0.5; 153 if (pr < 0) n3 = new f4_node('X', n2, n2->pos); 154 else 155 { 156 pr -= 0.5; 157 if (pr < 0) 158 { 159 // if neuron, make muscle and add a link 160 n3 = new f4_node('N', n2, n2->pos); 161 if (randomN(2) == 0) 162 n4 = new f4_node('|', n3, n2->pos); 163 else 164 n4 = new f4_node('@', n3, n2->pos); 165 n5 = new f4_node('[', n4, n2->pos); 166 linkNodeMakeRandom(n5); 167 } 168 } 169 new f4_node('>', n3, n3->pos); 170 n1->parent = n2; 171 // now with 50% chance swap children 172 if (randomN(2) == 0) 173 { 174 n3 = n2->child; 175 n2->child = n2->child2; 176 n2->child2 = n3; 177 } 178 } 179 break; 180 case F4_ADD_CONN: 181 { 182 // add link 183 n1->parent->removeChild(n1); 184 n2 = new f4_node('[', n1->parent, n1->parent->pos); 185 linkNodeMakeRandom(n2); 186 n2->addChild(n1); 187 n1->parent = n2; 188 } 189 break; 190 case F4_ADD_NEUPAR: 191 { 192 // add neuron modifier 193 n1->parent->removeChild(n1); 194 n2 = new f4_node(':', n1->parent, n1->parent->pos); 195 nparNodeMakeRandom(n2); 196 n2->addChild(n1); 197 n1->parent = n2; 198 } 199 break; 200 case F4_ADD_REP: 201 { 202 // add repetition ('#') 203 // repeated code (left child) is the original, right child is empty, count is 2 204 n3 = n1->parent; 205 n3->removeChild(n1); 206 n2 = new f4_node('#', n3, n3->pos); 207 n2->i1 = 2; 208 n2->addChild(n1); 209 new f4_node('>', n2, n2->pos); 210 n1->parent = n2; 211 } 212 break; 213 case F4_ADD_SIMP: 214 { 215 // add simple node 216 // choose a simple node from ADD_SIMPLE_CODES 217 n1->parent->removeChild(n1); 218 n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos); 219 n2->addChild(n1); 220 n1->parent = n2; 221 } 222 break; 223 } 224 } 225 break; 226 227 case F4_DEL: 228 { 229 method = F4_ADD_COUNT - 1 + F4_DEL; 230 // delete a node 231 // must pick a node with parent, and at least one child 232 // already picked a node, but repeat may be needed 233 for (int i = 0; i < 10; i++) { 234 if ((NULL != n1->parent) && (g != n1->parent)) 235 if (NULL != n1->child) 236 break; 237 // try a new one 238 n1 = g->child->randomNode(); 239 } 240 if ((NULL != n1->parent) && (g != n1->parent)) 241 { 242 switch (n1->childCount()) 243 { 244 case 0: break; 245 case 1: // one child 246 { 247 n2 = n1->parent; 248 n2->removeChild(n1); 249 if (NULL != n1->child) { 250 n1->child->parent = n2; 251 n2->addChild(n1->child); 252 n1->child = NULL; 253 } 254 if (NULL != n1->child2) { 255 n1->child2->parent = n2; 256 n2->addChild(n1->child2); 257 n1->child2 = NULL; 258 } 259 // destroy n1 260 n1->parent = NULL; 261 delete n1; 262 } 263 break; 264 265 case 2: // two children 266 { 267 // two children 268 n2 = n1->parent; 269 n2->removeChild(n1); 270 // n1 has two children. pick one randomly 50-50, destroy other 271 if (randomN(2) == 0) 272 { 273 n1->child->parent = n2; 274 n2->addChild(n1->child); 275 n1->child = NULL; 276 n1->child2->parent = NULL; 277 } 278 else 279 { 280 n1->child2->parent = n2; 281 n2->addChild(n1->child2); 282 n1->child2 = NULL; 283 n1->child->parent = NULL; 284 } 285 // destroy n1 286 n1->parent = NULL; 287 delete n1; 288 } 289 break; 290 } 291 } 292 else return GENOPER_OPFAIL; 293 } 294 break; 295 case F4_MOD: 296 { 297 method = F4_ADD_COUNT - 1 + F4_MOD; 298 // change a node 299 // the only nodes that are modifiable are MUT_CHAN_CODES 300 // try to get a modifiable node 301 // already picked a node, but repeat may be needed 302 int i = 0; 303 while (1) 304 { 305 if (strchr(MUT_CHAN_CODES, n1->name)) break; 306 // try a new one 307 n1 = g->child->randomNode(); 308 i++; 309 if (i >= 20) return GENOPER_OPFAIL; 310 } 311 switch (n1->name) { 312 case '<': 313 // swap children 314 n2 = n1->child; n1->child = n1->child2; n1->child2 = n2; 315 break; 316 case '[': 317 linkNodeChangeRandom(n1); 318 break; 319 case '#': 320 repeatNodeChangeRandom(n1); 321 break; 322 } 323 } 324 break; 325 326 default: //no mutations allowed? 327 return GENOPER_OPFAIL; 328 } 329 330 return GENOPER_OK; 347 331 } 348 332 … … 350 334 void Geno_f4::linkNodeMakeRandom(f4_node * nn) const 351 335 { 352 int i;353 float prob1;354 355 i = 0;356 // 35% chance one of *GTS357 prob1 = 1.0f / RAND_MAX * rand();358 prob1 -= 0.35f;359 if (prob1 < 0)360 {361 // '*', 'G', 'T', or 'S', 1/4 chance each362 i = 1 + (int)(3.999f / RAND_MAX * rand());363 }364 nn->i1 = i;365 nn->l1 = 0;366 if (0 == i) {367 // relative input link368 nn->l1 = (int)(4.0f * (1.0f / RAND_MAX * rand()- 0.5f));369 }370 // weight371 nn->f1 = 10.0f * (1.0f / RAND_MAX * rand()- 0.5f);336 int i; 337 float prob1; 338 339 i = 0; 340 // 35% chance one of *GTS 341 prob1 = rnd01; 342 prob1 -= 0.35f; 343 if (prob1 < 0) 344 { 345 // '*', 'G', 'T', or 'S', 1/4 chance each 346 i = 1 + (int)(3.999f * rnd01); 347 } 348 nn->i1 = i; 349 nn->l1 = 0; 350 if (0 == i) { 351 // relative input link 352 nn->l1 = (int)(4.0f * (rnd01 - 0.5f)); 353 } 354 // weight 355 nn->f1 = 10.0f * (rnd01 - 0.5f); 372 356 } 373 357 … … 375 359 void Geno_f4::linkNodeChangeRandom(f4_node * nn) const //rewritten by M.K. - should work as before (not tested) 376 360 { 377 int i;378 float prob2;379 380 double probs[3]={0.1, 0.3, 0.6};381 // 10% change type382 // 30% change link383 // 60% change weight384 385 switch (roulette(probs,3))386 {387 case 0: // change type388 i = 0;389 // * G, 10% chance each390 prob2 = rnd01 - 0.10f;391 if (prob2 < 0) i=1; else {prob2 -= 0.10f; if (prob2 < 0) i=2;}392 nn->i1 = i;393 break;394 case 1: // change link395 if (0 == nn->i1) // relative input link396 nn->l1 += (int)(2.0f * (rnd01 - 0.5f));397 break;398 case 2: // change weight399 nn->f1 += 1.0f * (rnd01 - 0.5f);400 break;401 }361 int i; 362 float prob2; 363 364 double probs[3] = { 0.1, 0.3, 0.6 }; 365 // 10% change type 366 // 30% change link 367 // 60% change weight 368 369 switch (roulette(probs, 3)) 370 { 371 case 0: // change type 372 i = 0; 373 // * G, 10% chance each 374 prob2 = rnd01 - 0.10f; 375 if (prob2 < 0) i = 1; else { prob2 -= 0.10f; if (prob2 < 0) i = 2; } 376 nn->i1 = i; 377 break; 378 case 1: // change link 379 if (0 == nn->i1) // relative input link 380 nn->l1 += (int)(2.0f * (rnd01 - 0.5f)); 381 break; 382 case 2: // change weight 383 nn->f1 += 1.0f * (rnd01 - 0.5f); 384 break; 385 } 402 386 } 403 387 … … 405 389 void Geno_f4::nparNodeMakeRandom(f4_node * nn) const 406 390 { 407 int sign = (int)( 2.0f / RAND_MAX * rand());408 int param = (int)( 3.0f / RAND_MAX * rand());409 if (param>2) param=2;410 nn->l1 = sign;411 nn->i1 = "!=/"[param];391 int sign = (int)(2.0f * rnd01); 392 int param = (int)(3.0f * rnd01); 393 if (param > 2) param = 2; 394 nn->l1 = sign; 395 nn->i1 = "!=/"[param]; 412 396 } 413 397 … … 415 399 void Geno_f4::repeatNodeChangeRandom(f4_node * nn) const 416 400 { 417 int count;418 float prob1;419 420 // change count421 count = nn->i1;422 prob1 = 1.0f / RAND_MAX * rand();423 if (prob1 < 0.5f) count++;424 else count--;425 if (count<1) count=1;426 if (count>REP_MAXCOUNT) count=REP_MAXCOUNT;427 nn->i1 = count;428 } 429 430 431 int Geno_f4::MutateOneValid(f4_node *& g, int &method) const401 int count; 402 float prob1; 403 404 // change count 405 count = nn->i1; 406 prob1 = rnd01; 407 if (prob1 < 0.5f) count++; 408 else count--; 409 if (count<1) count = 1; 410 if (count>REP_MAXCOUNT) count = REP_MAXCOUNT; 411 nn->i1 = count; 412 } 413 414 415 int Geno_f4::MutateOneValid(f4_node *& g, int &method) const 432 416 // mutate one, until a valid genotype is obtained 433 417 { 434 // ! the genotype is g->child (not g) !435 int i, res;436 f4_node * gcopy = NULL;437 // try this max 20 times:438 // copy, mutate, then validate439 440 for (i=0; i<20; i++)441 {442 gcopy = g->duplicate();443 444 res = MutateOne(gcopy,method);445 446 if (GENOPER_OK != res)447 {448 // mutation failed, try again449 delete gcopy;450 continue; // for451 }452 // try to validate it453 res = ValidateRec(gcopy, 10);454 // accept if it is OK, or was repaired455 if (GENOPER_OK == res)456 //(GENOPER_REPAIR == res)457 {458 // destroy the original one459 g->destroy();460 // make it the new one461 *g = *gcopy;462 gcopy->child=NULL;463 gcopy->child2=NULL;464 delete gcopy;465 res = GENOPER_OK;466 goto retm1v;467 }468 delete gcopy;469 }470 // attempts failed471 res = GENOPER_OPFAIL;418 // ! the genotype is g->child (not g) ! 419 int i, res; 420 f4_node * gcopy = NULL; 421 // try this max 20 times: 422 // copy, mutate, then validate 423 424 for (i = 0; i < 20; i++) 425 { 426 gcopy = g->duplicate(); 427 428 res = MutateOne(gcopy, method); 429 430 if (GENOPER_OK != res) 431 { 432 // mutation failed, try again 433 delete gcopy; 434 continue; // for 435 } 436 // try to validate it 437 res = ValidateRec(gcopy, 10); 438 // accept if it is OK, or was repaired 439 if (GENOPER_OK == res) 440 //(GENOPER_REPAIR == res) 441 { 442 // destroy the original one 443 g->destroy(); 444 // make it the new one 445 *g = *gcopy; 446 gcopy->child = NULL; 447 gcopy->child2 = NULL; 448 delete gcopy; 449 res = GENOPER_OK; 450 goto retm1v; 451 } 452 delete gcopy; 453 } 454 // attempts failed 455 res = GENOPER_OPFAIL; 472 456 retm1v: 473 return res; 474 } 475 476 477 int Geno_f4::mutate(char *& g, float & chg,int &method) 478 { 479 f4_node *root=new f4_node; 480 if (f4_processrec(g, 0, root) || root->childCount()!=1) 481 {delete root; return GENOPER_OPFAIL;} // could not convert or bad: fail 482 // mutate one node, set chg as this percent 483 chg = 1.0/float(root->child->count()); 484 if (MutateOneValid(root,method)!=GENOPER_OK) 485 {delete root; return GENOPER_OPFAIL;} 486 // OK, convert back to string 487 g[0]=0; 488 root->child->sprintAdj(g); 489 delete root; 490 return GENOPER_OK; 457 return res; 458 } 459 460 461 int Geno_f4::mutate(char *& g, float & chg, int &method) 462 { 463 f4_node *root = new f4_node; 464 if (f4_processrec(g, 0, root) || root->childCount() != 1) 465 { 466 delete root; return GENOPER_OPFAIL; 467 } // could not convert or bad: fail 468 // mutate one node, set chg as this percent 469 chg = 1.0 / float(root->child->count()); 470 if (MutateOneValid(root, method) != GENOPER_OK) 471 { 472 delete root; return GENOPER_OPFAIL; 473 } 474 // OK, convert back to string 475 g[0] = 0; 476 root->child->sprintAdj(g); 477 delete root; 478 return GENOPER_OK; 491 479 } 492 480 … … 497 485 // make a number of mutations 498 486 { 499 int res, n, i;500 int totNodes = 0;501 int maxToMut = 0;502 503 // convert to tree504 f4_node * root;505 root = new f4_node();506 res = f4_processrec(g, 0, root);507 if (res) {508 // could not convert, fail509 goto retm;510 }511 if (1 != root->childCount()) {512 res = GENOPER_OPFAIL;513 goto retm;514 }515 516 // check if original is valid517 res = ValidateRec( root, 20 );518 // might have been repaired!519 if (GENOPER_REPAIR==res) {520 res = GENOPER_OK;521 }522 if (GENOPER_OK != res) {523 goto retm;524 }525 526 // decide number of nodes to mutate527 // decide maximum number of nodes to mutate: 0.25*nodes, min 2528 totNodes = root->child->count();529 maxToMut = (int)( 0.25f * totNodes);530 if (maxToMut<2) maxToMut=2;531 if (maxToMut>totNodes) maxToMut=totNodes;532 533 // decide number of nodes to mutate534 n = (int)( 0.5f + 1.0f/RAND_MAX * rand()* maxToMut );535 if (n<1) n=1;536 if (n>totNodes) n=totNodes;537 // set chg as this percent538 chg = ((float)n) / ((float)totNodes);539 for (i=0; i<n; i++)540 {541 res = MutateOneValid(root);542 if (GENOPER_OK != res)543 {544 res = GENOPER_OPFAIL;545 goto retm;546 }547 }548 // OK, convert back to string549 g[0]=0;550 root->child->sprintAdj(g);487 int res, n, i; 488 int totNodes = 0; 489 int maxToMut = 0; 490 491 // convert to tree 492 f4_node * root; 493 root = new f4_node(); 494 res = f4_processrec(g, 0, root); 495 if (res) { 496 // could not convert, fail 497 goto retm; 498 } 499 if (1 != root->childCount()) { 500 res = GENOPER_OPFAIL; 501 goto retm; 502 } 503 504 // check if original is valid 505 res = ValidateRec( root, 20 ); 506 // might have been repaired! 507 if (GENOPER_REPAIR==res) { 508 res = GENOPER_OK; 509 } 510 if (GENOPER_OK != res) { 511 goto retm; 512 } 513 514 // decide number of nodes to mutate 515 // decide maximum number of nodes to mutate: 0.25*nodes, min 2 516 totNodes = root->child->count(); 517 maxToMut = (int)( 0.25f * totNodes); 518 if (maxToMut<2) maxToMut=2; 519 if (maxToMut>totNodes) maxToMut=totNodes; 520 521 // decide number of nodes to mutate 522 n = (int)( 0.5f + rnd01 * maxToMut ); 523 if (n<1) n=1; 524 if (n>totNodes) n=totNodes; 525 // set chg as this percent 526 chg = ((float)n) / ((float)totNodes); 527 for (i=0; i<n; i++) 528 { 529 res = MutateOneValid(root); 530 if (GENOPER_OK != res) 531 { 532 res = GENOPER_OPFAIL; 533 goto retm; 534 } 535 } 536 // OK, convert back to string 537 g[0]=0; 538 root->child->sprintAdj(g); 551 539 retm: 552 delete root;553 return res;540 delete root; 541 return res; 554 542 } 555 543 */ … … 558 546 int Geno_f4::CrossOverOne(f4_node * g1, f4_node * g2, float chg) const 559 547 { 560 // ! the genotypes are g1->child and g2->child (not g1 g2) !561 // single offspring in g1562 int smin, smax;563 float size;564 f4_node * n1, * n2, * n1p, *n2p;565 566 // determine desired size567 size = (1-chg) * (float)g1->count();568 smin = (int)(size*0.9f-1);569 smax = (int)(size*1.1f+1);570 // get a random node with desired size571 n1 = g1->child->randomNodeWithSize(smin, smax);572 573 // determine desired size574 size = (1-chg) * (float)g2->count();575 smin = (int)(size*0.9f-1);576 smax = (int)(size*1.1f+1);577 // get a random node with desired size578 n2 = g2->child->randomNodeWithSize(smin, smax);579 580 // exchange the two nodes:581 n1p = n1->parent;582 n2p = n2->parent;583 n1p->removeChild(n1);584 n1p->addChild(n2);585 n2p->removeChild(n2);586 n2p->addChild(n1);587 n1->parent = n2p;588 n2->parent = n1p;589 590 return GENOPER_OK;548 // ! the genotypes are g1->child and g2->child (not g1 g2) ! 549 // single offspring in g1 550 int smin, smax; 551 float size; 552 f4_node * n1, *n2, *n1p, *n2p; 553 554 // determine desired size 555 size = (1 - chg) * (float)g1->count(); 556 smin = (int)(size*0.9f - 1); 557 smax = (int)(size*1.1f + 1); 558 // get a random node with desired size 559 n1 = g1->child->randomNodeWithSize(smin, smax); 560 561 // determine desired size 562 size = (1 - chg) * (float)g2->count(); 563 smin = (int)(size*0.9f - 1); 564 smax = (int)(size*1.1f + 1); 565 // get a random node with desired size 566 n2 = g2->child->randomNodeWithSize(smin, smax); 567 568 // exchange the two nodes: 569 n1p = n1->parent; 570 n2p = n2->parent; 571 n1p->removeChild(n1); 572 n1p->addChild(n2); 573 n2p->removeChild(n2); 574 n2p->addChild(n1); 575 n1->parent = n2p; 576 n2->parent = n1p; 577 578 return GENOPER_OK; 591 579 } 592 580 593 581 int Geno_f4::crossOver(char *&g1, char *&g2, float &chg1, float &chg2) 594 582 { 595 f4_node root1, root2, *copy1, *copy2;596 597 // convert genotype strings into tree structures598 if (f4_processrec(g1,0,&root1) || (root1.childCount()!=1)) return GENOPER_OPFAIL;599 if (f4_processrec(g2,0,&root2) || (root2.childCount()!=1)) return GENOPER_OPFAIL;600 601 // decide amounts of crossover, 0.25-0.75602 // adam: seems 0.1-0.9 -- MacKo603 chg1 = 0.1f + 0.8f*rnd01;604 chg2 = 0.1f + 0.8f*rnd01;605 606 copy1 = root1.duplicate();607 if (CrossOverOne(copy1, &root2, chg1) != GENOPER_OK) {delete copy1; copy1=NULL;}608 copy2 = root2.duplicate();609 if (CrossOverOne(copy2, &root1, chg2) != GENOPER_OK) {delete copy2; copy2=NULL;}610 611 g1[0]=0;612 g2[0]=0;613 if (copy1) {copy1->child->sprintAdj(g1); delete copy1;}614 if (copy2) {copy2->child->sprintAdj(g2); delete copy2;}615 if (g1[0] || g2[0]) return GENOPER_OK; else return GENOPER_OPFAIL;583 f4_node root1, root2, *copy1, *copy2; 584 585 // convert genotype strings into tree structures 586 if (f4_processrec(g1, 0, &root1) || (root1.childCount() != 1)) return GENOPER_OPFAIL; 587 if (f4_processrec(g2, 0, &root2) || (root2.childCount() != 1)) return GENOPER_OPFAIL; 588 589 // decide amounts of crossover, 0.25-0.75 590 // adam: seems 0.1-0.9 -- MacKo 591 chg1 = 0.1f + 0.8f*rnd01; 592 chg2 = 0.1f + 0.8f*rnd01; 593 594 copy1 = root1.duplicate(); 595 if (CrossOverOne(copy1, &root2, chg1) != GENOPER_OK) { delete copy1; copy1 = NULL; } 596 copy2 = root2.duplicate(); 597 if (CrossOverOne(copy2, &root1, chg2) != GENOPER_OK) { delete copy2; copy2 = NULL; } 598 599 g1[0] = 0; 600 g2[0] = 0; 601 if (copy1) { copy1->child->sprintAdj(g1); delete copy1; } 602 if (copy2) { copy2->child->sprintAdj(g2); delete copy2; } 603 if (g1[0] || g2[0]) return GENOPER_OK; else return GENOPER_OPFAIL; 616 604 } 617 605 … … 620 608 unsigned long Geno_f4::style(const char *g, int pos) 621 609 { 622 char ch = g[pos]; 623 // style categories 624 #define STYL4CAT_MODIFIC "LlRrCcQqAaIiSsMmFfWwEe," 625 #define STYL4CAT_NEUMOD "[]|@*GTS:+-/!=" 626 #define STYL4CAT_DIGIT "0123456789." 627 #define STYL4CAT_REST "XN<># " 628 if (!strchr(STYL4CAT_MODIFIC STYL4CAT_NEUMOD STYL4CAT_DIGIT STYL4CAT_REST, ch)) 629 return GENSTYLE_CS(0,GENSTYLE_INVALID); 630 unsigned long style=GENSTYLE_CS(0,GENSTYLE_STRIKEOUT); //default, should be changed below 631 if (strchr("X ", ch)) style=GENSTYLE_CS(0,GENSTYLE_NONE); 632 if (strchr("N", ch)) style=GENSTYLE_RGBS(0,200,0,GENSTYLE_NONE); 633 if (strchr("<", ch)) style=GENSTYLE_RGBS(0,0,200,GENSTYLE_BOLD); 634 if (strchr(">", ch)) style=GENSTYLE_RGBS(0,0,100,GENSTYLE_NONE); 635 if (strchr(STYL4CAT_DIGIT, ch)) style=GENSTYLE_RGBS(100,100,100,GENSTYLE_NONE); 636 if (strchr(STYL4CAT_MODIFIC, ch)) style=GENSTYLE_RGBS(100,100,100,GENSTYLE_NONE); 637 if (strchr(STYL4CAT_NEUMOD, ch)) style=GENSTYLE_RGBS(0,150,0,GENSTYLE_NONE); 638 return style; 639 } 640 641 610 char ch = g[pos]; 611 // style categories 612 #define STYL4CAT_MODIFIC "LlRrCcQqAaIiSsMmFfWwEe," 613 #define STYL4CAT_NEUMOD "[]|@*GTS:+-/!=" 614 #define STYL4CAT_DIGIT "0123456789." 615 #define STYL4CAT_REST "XN<># " 616 if (!strchr(STYL4CAT_MODIFIC STYL4CAT_NEUMOD STYL4CAT_DIGIT STYL4CAT_REST, ch)) 617 return GENSTYLE_CS(0, GENSTYLE_INVALID); 618 unsigned long style = GENSTYLE_CS(0, GENSTYLE_STRIKEOUT); //default, should be changed below 619 if (strchr("X ", ch)) style = GENSTYLE_CS(0, GENSTYLE_NONE); 620 if (strchr("N", ch)) style = GENSTYLE_RGBS(0, 200, 0, GENSTYLE_NONE); 621 if (strchr("<", ch)) style = GENSTYLE_RGBS(0, 0, 200, GENSTYLE_BOLD); 622 if (strchr(">", ch)) style = GENSTYLE_RGBS(0, 0, 100, GENSTYLE_NONE); 623 if (strchr(STYL4CAT_DIGIT, ch)) style = GENSTYLE_RGBS(100, 100, 100, GENSTYLE_NONE); 624 if (strchr(STYL4CAT_MODIFIC, ch)) style = GENSTYLE_RGBS(100, 100, 100, GENSTYLE_NONE); 625 if (strchr(STYL4CAT_NEUMOD, ch)) style = GENSTYLE_RGBS(0, 150, 0, GENSTYLE_NONE); 626 return style; 627 } -
cpp/frams/genetics/f4/oper_f4.h
r193 r196 1 /* 2 * geno_f4.h - f4 genetic operators. 3 * 4 * f4genotype - f4 format genotype conversions for FramSticks 5 * 6 * Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com) 7 * Copyright (C) 2001-2004 Maciej Komosinski 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 1 // This file is a part of the Framsticks GDK. 2 // Copyright (C) 2002-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. 3 // Refer to http://www.framsticks.com/ for further information. 4 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 // Copyright (C) since 2001 Maciej Komosinski 24 7 25 8 #ifndef _GENO_F4_H_ 26 9 #define _GENO_F4_H_ 27 10 11 #include <stdio.h> 28 12 #include "f4_general.h" 29 #include "nonstd.h" 30 #include <stdio.h> 31 #include "geno_fx.h" 32 #include "param.h" 13 #include "common/nonstd.h" 14 #include "../oper_fx.h" 15 #include <frams/param/param.h> 33 16 34 17 … … 46 29 47 30 48 class Geno_f4 : public Geno_fx31 class Geno_f4 : public GenoOperators 49 32 { 50 33 public: 51 Geno_f4();52 int validate(char *&);53 int checkValidity(const char *);54 int mutate(char *& g, float & chg,int &method);55 int crossOver(char *&g1, char *&g2, float& chg1, float& chg2);56 char* getSimplest() {return "X";}; 57 unsigned long style(const char *g, int pos);34 Geno_f4(); 35 int validate(char *&); 36 int checkValidity(const char *); 37 int mutate(char *& g, float & chg, int &method); 38 int crossOver(char *&g1, char *&g2, float& chg1, float& chg2); 39 const char* getSimplest() { return "X"; } 40 unsigned long style(const char *g, int pos); 58 41 59 // mutation probabilities60 double prob[F4_COUNT],probadd[F4_ADD_COUNT];42 // mutation probabilities 43 double prob[F4_COUNT], probadd[F4_ADD_COUNT]; 61 44 62 45 protected: 63 /* int MutateMany(char *& g, float & chg); // not used anymore */64 int ValidateRec(f4_node * geno, int retrycount) const;65 int MutateOne(f4_node *& g,int &method) const;66 void linkNodeMakeRandom(f4_node * nn) const;67 void linkNodeChangeRandom(f4_node * nn) const;68 void nparNodeMakeRandom(f4_node * nn) const;69 void repeatNodeChangeRandom(f4_node * nn) const;70 int MutateOneValid(f4_node * &g,int &method) const;71 int CrossOverOne(f4_node *g1, f4_node *g2, float chg) const;72 // returns GENOPER_OK or GENOPER_OPFAIL73 // chg: fraction of parent1 genes in child (in g1) (parent2 has the rest)46 /* int MutateMany(char *& g, float & chg); // not used anymore */ 47 int ValidateRec(f4_node * geno, int retrycount) const; 48 int MutateOne(f4_node *& g, int &method) const; 49 void linkNodeMakeRandom(f4_node * nn) const; 50 void linkNodeChangeRandom(f4_node * nn) const; 51 void nparNodeMakeRandom(f4_node * nn) const; 52 void repeatNodeChangeRandom(f4_node * nn) const; 53 int MutateOneValid(f4_node * &g, int &method) const; 54 int CrossOverOne(f4_node *g1, f4_node *g2, float chg) const; 55 // returns GENOPER_OK or GENOPER_OPFAIL 56 // chg: fraction of parent1 genes in child (in g1) (parent2 has the rest) 74 57 }; 75 58 -
cpp/frams/genetics/gen-config-GDK.h
r194 r196 15 15 //#define USE_GENCONV_f21 16 16 //#define USE_GENCONV_f30 17 //#define USE_GENCONV_f4017 #define USE_GENCONV_f40 18 18 //#define USE_GENCONV_f41_TEST 19 19 //#define USE_GENCONV_f50 … … 25 25 //#define USE_GENMAN_f2 26 26 //#define USE_GENMAN_f3 27 //#define USE_GENMAN_f427 #define USE_GENMAN_f4 28 28 //#define USE_GENMAN_f5 29 29 #define USE_GENMAN_f9
Note: See TracChangeset
for help on using the changeset viewer.
