Changeset 760 for cpp/frams/genetics/f4/oper_f4.cpp
- Timestamp:
- 03/15/18 22:55:05 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/f4/oper_f4.cpp
r676 r760 5 5 // Copyright (C) 1999,2000 Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL 6 6 // Copyright (C) since 2001 Maciej Komosinski 7 // 2018, Grzegorz Latosinski, added support for new API for neuron types and their properties 7 8 8 9 #include "oper_f4.h" … … 138 139 #define REP_MAXCOUNT 19 139 140 140 f4_node * n1, *n2, *n3, *n4, *n5;141 142 141 // do the mutation 143 142 // pick a random node 144 n1 = g->child->randomNode(); 143 f4_node *n1 = g->child->randomNode(); 144 vector<NeuroClass*> neulist; 145 145 //DB( printf("%c\n", n1->name); ) 146 int neuronid = -1; 146 147 147 148 switch (roulette(prob, F4_COUNT)) … … 155 156 { 156 157 // add division ('<') 157 n3 = n1->parent;158 f4_node *n3 = n1->parent; 158 159 n3->removeChild(n1); 159 n2 = new f4_node('<', n3, n3->pos);160 f4_node *n2 = new f4_node('<', n3, n3->pos); 160 161 n2->addChild(n1); 161 162 // new cell is stick or neuron 162 163 // "X>" or "N>" 164 f4_node *n5 = NULL; 163 165 double pr = rnd01; 164 166 pr -= 0.5; 165 if (pr < 0) n 3= new f4_node('X', n2, n2->pos);167 if (pr < 0) n5 = new f4_node('X', n2, n2->pos); 166 168 else 167 169 { 168 pr -= 0.5; 169 if (pr < 0) 170 { 171 // if neuron, make muscle and add a link 172 n3 = new f4_node('N', n2, n2->pos); 173 if (randomN(2) == 0) 174 n4 = new f4_node('|', n3, n2->pos); 175 else 176 n4 = new f4_node('@', n3, n2->pos); 177 n5 = new f4_node('[', n4, n2->pos); 178 linkNodeMakeRandom(n5); 179 } 180 } 181 new f4_node('>', n3, n3->pos); 170 // make neuron 171 NeuroClass * rndclass = GenoOperators::getRandomNeuroClass(); 172 if (rndclass == NULL) 173 { 174 n5 = new f4_node('X', n2, n2->pos); 175 } 176 else 177 { 178 f4_node *n4 = new f4_node(rndclass->getName().c_str(), n2, n2->pos); //TODO move this above 179 if (rndclass->getPreferredInputs() != 0) 180 { 181 neuronid = -1; 182 for (int i = 0; i < g->count(); i++) 183 { 184 f4_node * gcur = g->ordNode(i); 185 char * temp = (char*)gcur->name.c_str(); 186 NeuroClass * neuclass = GenoOperators::parseNeuroClass(temp); 187 if (neuclass != NULL) 188 { 189 neulist.push_back(neuclass); 190 } 191 if (g->ordNode(i) == n3) 192 { 193 neuronid = neulist.size()-1; 194 } 195 } 196 if (neuronid == -1) 197 { 198 return GENOPER_OPFAIL; 199 } 200 n5 = new f4_node('[', n4, n2->pos); 201 linkNodeMakeRandom(n5, neuronid, neulist); 202 } 203 else { 204 n5 = n4; 205 } 206 } 207 } 208 new f4_node('>', n5, n5->pos); 182 209 n1->parent = n2; 183 210 // now with 50% chance swap children … … 193 220 { 194 221 // add link 195 n1->parent->removeChild(n1); 196 n2 = new f4_node('[', n1->parent, n1->parent->pos); 197 linkNodeMakeRandom(n2); 198 n2->addChild(n1); 199 n1->parent = n2; 222 f4_node * par = n1->parent; 223 char * temp = (char*)par->name.c_str(); 224 NeuroClass * neuclass = GenoOperators::parseNeuroClass(temp); 225 if (neuclass != NULL) 226 { 227 n1->parent->removeChild(n1); 228 f4_node *n2 = new f4_node('[', n1->parent, n1->parent->pos); 229 n2->addChild(n1); 230 n1->parent = n2; 231 neuronid = -1; 232 for (int i = 0; i < g->count(); i++) 233 { 234 f4_node *gcur = g->ordNode(i); 235 temp = (char*)gcur->name.c_str(); 236 NeuroClass *neuclass = GenoOperators::parseNeuroClass(temp); 237 if (neuclass != NULL) 238 { 239 neulist.push_back(neuclass); 240 } 241 if (gcur == par) 242 { 243 neuronid = neulist.size()-1; 244 } 245 } 246 if (neuronid == -1) 247 { 248 return GENOPER_OPFAIL; 249 } 250 linkNodeMakeRandom(n2, neuronid, neulist); 251 } 200 252 } 201 253 break; … … 204 256 // add neuron modifier 205 257 n1->parent->removeChild(n1); 206 n2 = new f4_node(':', n1->parent, n1->parent->pos);258 f4_node *n2 = new f4_node(':', n1->parent, n1->parent->pos); 207 259 nparNodeMakeRandom(n2); 208 260 n2->addChild(n1); … … 214 266 // add repetition ('#') 215 267 // repeated code (left child) is the original, right child is empty, count is 2 216 n3 = n1->parent;268 f4_node *n3 = n1->parent; 217 269 n3->removeChild(n1); 218 n2 = new f4_node('#', n3, n3->pos);270 f4_node *n2 = new f4_node('#', n3, n3->pos); 219 271 n2->i1 = 2; 220 272 n2->addChild(n1); … … 228 280 // choose a simple node from ADD_SIMPLE_CODES 229 281 n1->parent->removeChild(n1); 230 n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos);282 f4_node *n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos); 231 283 n2->addChild(n1); 232 284 n1->parent = n2; … … 258 310 case 1: // one child 259 311 { 260 n2 = n1->parent;312 f4_node *n2 = n1->parent; 261 313 n2->removeChild(n1); 262 314 if (NULL != n1->child) … … 281 333 { 282 334 // two children 283 n2 = n1->parent;335 f4_node *n2 = n1->parent; 284 336 n2->removeChild(n1); 285 337 // n1 has two children. pick one randomly 50-50, destroy other … … 318 370 while (1) 319 371 { 320 if (strchr(MUT_CHAN_CODES, n1->name )) break;372 if (strchr(MUT_CHAN_CODES, n1->name[0])) break; 321 373 // try a new one 322 374 n1 = g->child->randomNode(); … … 324 376 if (i >= 20) return GENOPER_OPFAIL; 325 377 } 326 switch (n1->name )378 switch (n1->name[0]) 327 379 { 328 380 case '<': 381 { 329 382 // swap children 330 n2 = n1->child; n1->child = n1->child2; n1->child2 = n2; 383 f4_node *n2 = n1->child; n1->child = n1->child2; n1->child2 = n2; 384 } 331 385 break; 332 386 case '[': 333 linkNodeChangeRandom(n1); 387 { 388 neuronid = -1; 389 for (int i = 0; i < g->count(); i++) 390 { 391 f4_node *gcur = g->ordNode(i); 392 char *temp = (char*)gcur->name.c_str(); 393 NeuroClass *neuclass = GenoOperators::parseNeuroClass(temp); 394 if (neuclass != NULL) 395 { 396 neulist.push_back(neuclass); 397 } 398 if (gcur == n1) 399 { 400 neuronid = neulist.size()-1; 401 } 402 } 403 if (neuronid == -1) 404 { 405 return GENOPER_OPFAIL; 406 } 407 linkNodeChangeRandom(n1, neuronid, neulist); 408 } 334 409 break; 410 335 411 case '#': 412 { 336 413 repeatNodeChangeRandom(n1); 414 } 337 415 break; 338 416 } … … 348 426 349 427 // make a random [ node 350 void Geno_f4::linkNodeMakeRandom(f4_node * nn) const 351 { 352 int i; 428 void Geno_f4::linkNodeMakeRandom(f4_node *nn, int neuid, vector<NeuroClass*> neulist) const 429 { 353 430 float prob1; 354 355 i = 0; 431 NeuroClass *nc = NULL; 432 356 433 // 35% chance one of *GTS 357 434 prob1 = rnd01; … … 360 437 { 361 438 // '*', 'G', 'T', or 'S', 1/4 chance each 362 i = 1 + (int)(3.999f * rnd01); 363 } 364 nn->i1 = i; 365 nn->l1 = 0; 366 if (0 == i) 439 nc = GenoOperators::getRandomNeuroClassWithOutputAndNoInputs(); 440 } 441 if (nc != NULL) 442 { 443 nn->i1 = 1; 444 nn->s1 = nc->getName().c_str(); 445 nn->l1 = 0; 446 } 447 else 367 448 { 368 449 // relative input link 369 nn->l1 = (int)(4.0f * (rnd01 - 0.5f)); 450 int id = GenoOperators::getRandomNeuroClassWithOutput(neulist); 451 int relid = neuid - id; 452 nn->l1 = relid; 453 //nn->l1 = (int)(4.0f * (rnd01 - 0.5f)); 370 454 } 371 455 // weight 372 nn->f1 = 10.0f * (rnd01 - 0.5f); 456 nn->f1 = GenoOperators::mutateNeuProperty(nn->f1,NULL,-1); 457 //nn->f1 = 10.0f * (rnd01 - 0.5f); 373 458 } 374 459 375 460 // change a [ node 376 void Geno_f4::linkNodeChangeRandom(f4_node * nn) const //rewritten by M.K. - should work as before (not tested) 377 { 378 int i; 379 float prob2; 380 461 void Geno_f4::linkNodeChangeRandom(f4_node * nn, int neuid, std::vector<NeuroClass*> neulist) const //rewritten by M.K. - should work as before (not tested) 462 { 381 463 double probs[3] = { 0.1, 0.3, 0.6 }; 464 NeuroClass *cl; 382 465 // 10% change type 383 466 // 30% change link … … 387 470 { 388 471 case 0: // change type 389 i = 0; 390 // * G, 10% chance each 391 prob2 = rnd01 - 0.10f; 392 if (prob2 < 0) i = 1; else { prob2 -= 0.10f; if (prob2 < 0) i = 2; } 393 nn->i1 = i; 472 // 80% for link, 20% for random sensor 473 if (rnd01 < 0.2f) 474 { 475 cl = GenoOperators::getRandomNeuroClassWithOutputAndNoInputs(); 476 if (cl != NULL) 477 { 478 nn->i1 = 1; 479 nn->s1 = cl->name.c_str(); 480 nn->l1 = 0; 481 } 482 } 394 483 break; 395 484 case 1: // change link 396 485 if (0 == nn->i1) // relative input link 397 nn->l1 += (int)(2.0f * (rnd01 - 0.5f)); 486 { 487 int id = GenoOperators::getRandomNeuroClassWithOutput(neulist); 488 nn->l1 = neuid - id; 489 } 490 //nn->l1 += (int)(2.0f * (rnd01 - 0.5f)); 398 491 break; 399 492 case 2: // change weight 400 nn->f1 += 1.0f * (rnd01 - 0.5f); 493 nn->f1 = GenoOperators::mutateNeuProperty(nn->f1,NULL,-1); 494 //nn->f1 += 1.0f * (rnd01 - 0.5f); 401 495 break; 402 496 }
Note: See TracChangeset
for help on using the changeset viewer.