Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.53 KB | None | 0 0
  1. %% Assignment 04
  2. clear all;
  3. clc;
  4.  
  5. %% Initial parameters
  6. max_generations=500;
  7. generation=1;
  8. target_fitness = 1000;
  9. num_i_nodes = 6;
  10. num_b_nodes = 1;
  11. num_o_nodes = 1;
  12. num_h_nodes = 0;
  13. pop_size = 150;
  14. fixed_topology=1;
  15.  
  16. stagnation.threshold=1e-2;
  17. stagnation.number_generation=15;
  18. refocus.threshold=1e-2;
  19. refocus.number_generation=20;
  20.  
  21. initial.kill_percentage=0.2;
  22. initial.number_for_kill=5;
  23. initial.number_copy=5;
  24.  
  25. selection.pressure=2;
  26.  
  27. % crossover.percentage=0.8;
  28. crossover.percentage=0;
  29. crossover.probability_interspecies=0.0;
  30. crossover.probability_multipoint=0.6;
  31. crossover.rate = 0.1;
  32. % Mutation related parameters
  33. mutation.rate = 0.2;
  34. mutation.perturbation_rate = 0.9;
  35. mutation.perturbation_range=0.1;
  36. mutation.cap = 5;
  37. mutation.range = 2;
  38. mutation.mutate_weight=0.9;
  39. mutation.add_node_rate=0.03;
  40. mutation.add_connection_rate=0.05;
  41. mutation.recurrency_rate=0.0;
  42. mutation.reenabled_rate=0.25;
  43.  
  44. speciation.c1 = 0;
  45. speciation.c2 = 0;
  46. speciation.c3 = 4;
  47. speciation.threshold=5;
  48.  
  49. species_record(1).ID=0;
  50. species_record(1).number_individuals=0;
  51. species_record(1).generation_record=[];
  52.  
  53. % if fixed_topology == 1
  54. %
  55. % num_nodes = num_i_nodes+num_b_nodes+num_o_nodes+num_h_nodes;
  56. % num_conections = num_i_nodes+num_b_nodes;
  57. % connections_from = 1:num_i_nodes+num_b_nodes;
  58. % connections_to = num_nodes*ones(1,num_conections);
  59. % global_innovation_number=num_conections+1;
  60. % end
  61.  
  62. num_nodes = num_i_nodes+num_b_nodes+num_o_nodes+num_h_nodes;
  63. num_conections = num_i_nodes+num_b_nodes;
  64. connections_from = 1:num_i_nodes+num_b_nodes;
  65. connections_to = num_nodes*ones(1,num_conections);
  66. global_innovation_number=num_conections+1;
  67. innovation_record = [];
  68. max_gen_fit = [];
  69. %% Initialize population
  70. for ind=1:pop_size
  71.  
  72. %node ID's
  73. %node type: 1=input 2=output 3=hidden 4=bias
  74. %node input state
  75. %node output state
  76. population(ind).node_genes=[1:(num_i_nodes+num_b_nodes+num_o_nodes+num_h_nodes);
  77. ones(1,num_i_nodes),4*ones(1,num_b_nodes),2*ones(1,num_o_nodes),3*ones(1,num_h_nodes);
  78. zeros(1,num_i_nodes),ones(1,num_b_nodes),zeros(1,num_o_nodes),zeros(1,num_h_nodes);
  79. zeros(1,num_nodes)];
  80.  
  81. %innovation number
  82. %connection from,
  83. %connection to
  84. %weights (uniformly distributed in [-2 +2], all connections enabled)
  85. %enable bit
  86. population(ind).connection_genes=[1:num_conections;
  87. connections_from;
  88. connections_to;
  89. rand(1,num_conections)*2*mutation.range-mutation.range;
  90. ones(1,num_conections)];
  91. population(ind).wMat = weight_matrix(population(ind).node_genes,population(ind).connection_genes);
  92. population(ind).fitness=0;
  93. population(ind).species=0;
  94. end
  95. %% Innovation reccord for initial population
  96. %Innovation ID
  97. %Connections from
  98. %Connection to
  99. %New node(Highest)
  100. %Generation this innovation occured
  101. innovation_record=[population(ind).connection_genes(1:3,:);zeros(size(population(ind).connection_genes(1:2,:)))];
  102. innovation_record(4,size(innovation_record,2))=max(population(1).node_genes(1,:));
  103.  
  104. %% Initial speciation
  105. population(1).species=1;
  106. %fill in first individual in species record and propogating species matrix
  107.  
  108. mat=population(1).connection_genes(4,:);
  109. species_record(1).ID=1;
  110. species_record(1).number_individuals=1;
  111.  
  112. for ind=2:size(population,2);
  113.  
  114. added = false
  115. sp=1;
  116.  
  117. while ~added
  118. %species compatibility distance
  119.  
  120. distance=speciation.c3*sum(abs(population(ind).connection_genes(4,:)-mat(sp,:)))/num_conections;
  121. if distance<speciation.threshold %If within threshold, assign to the existing species
  122. population(ind).species=sp;
  123. species_record(sp).number_individuals=species_record(sp).number_individuals+1;
  124. added=true;
  125. end
  126. sp=sp+1; % check with all species
  127.  
  128. %Outside of species references, must be new species
  129. if sp>size(mat,1) & ~added
  130. population(ind).species=sp;
  131. species_record(sp).ID=sp;
  132. species_record(sp).number_individuals=1;
  133. mat=[mat;population(ind).connection_genes(4,:)];
  134. added=true;
  135. end
  136. end
  137. end
  138.  
  139. %% Start generation loop
  140. maximal_fit=0;
  141. sol_found=false;
  142. while generation<=max_generations & ~sol_found
  143. cur_max_fit=zeros(1,size(species_record,2));
  144.  
  145. % Fitness of population
  146. population = get_pop_fitness(population, @RNNet, target_fitness);
  147.  
  148. for sp=1:size(species_record,2)
  149. if species_record(sp).number_individuals>0
  150. % max fitness
  151. [max_fit,ind_max]=max(([population.species]==sp).*[population.fitness]);
  152. %mean fitness
  153. mean_fit=sum(([population.species]==sp).*[population.fitness])/species_record(sp).number_individuals;
  154. % Compute stagnation vector (last stagnation.number_generation-1 max fitnesses plus current fitness
  155.  
  156. if size(species_record(sp).generation_record,2)>stagnation.number_generation-2
  157. stag_vec=[species_record(sp).generation_record(3,size(species_record(sp).generation_record,2)-stagnation.number_generation+2:size(species_record(sp).generation_record,2)),max_fit];
  158. if sum(abs(stag_vec-mean(stag_vec))<stagnation.threshold)==stagnation.number_generation %Check for stagnation
  159. mean_fit=0.01; %set mean fitness to small value to eliminate species (cannot be set to 0, if only one species is present, we would have divide by zero in fitness sharing. anyways, with only one species present, we have to keep it)
  160. end
  161. end
  162. % update generation record
  163. species_record(sp).generation_record=[species_record(sp).generation_record,[generation;mean_fit;max_fit;ind_max]];
  164. cur_max_fit(1,sp)=max_fit;
  165. end
  166. end
  167.  
  168. c=[];
  169. for sp=1:size(species_record,2)
  170. c=[c,species_record(sp).generation_record(1:4,size(species_record(sp).generation_record,2))];
  171. end
  172. maximal_fit=max(c(3,:).*(c(1,:)==generation));
  173. max_gen_fit=[max_gen_fit,[maximal_fit;generation]];
  174. if maximal_fit>=target_fitness
  175. sol_found = true;
  176. else
  177. % Function reproduce goes here
  178. [population,species_record,innovation_record]=...
  179. reproduce_pop(population, species_record, innovation_record, initial, selection, ...
  180. crossover, mutation, speciation, generation, pop_size,@RNNet,target_fitness);
  181. end
  182. generation
  183. generation=generation+1;
  184. subplot(2,2,3);
  185. plot(max_gen_fit(2,:),max_gen_fit(1,:));
  186. ylabel('max fitness');
  187. end
  188.  
  189. [max_fit, max_fit_individual] = max([population(:).fitness]);
  190.  
  191. % simulate = twoPole_test( population(max_fit_individual).wMat, @RNNet, target_fitness,'vis');
  192.  
  193.  
  194. %% Function implementing crossover, mutation, and speciation
  195. function [new_population,updated_species_record,updated_innovation_record]=...
  196. reproduce_pop(population, species_record, innovation_record, initial, selection, ...
  197. crossover, mutation, speciation, generation, pop_size,RNNet,target_fitness)
  198.  
  199.  
  200.  
  201. % new_population(1) = population(1);
  202. %new_population = rank_based_selection(population,species_record);
  203.  
  204. % Sum of avg from every species
  205. avg_fit=0;
  206. for s_ind=1:size(species_record,2)
  207. avg_fit=avg_fit+species_record(s_ind).generation_record(2,size(species_record(s_ind).generation_record,2))...
  208. *(species_record(s_ind).number_individuals>0);
  209. end
  210.  
  211. % Matrix containing iformation about species that currently exist and
  212. % will be propagating.
  213. propagating_species=[];
  214. overflow=0;
  215. index_individual=0;
  216. for s_ind = 1:size(species_record,2)
  217. if species_record(s_ind).number_individuals>0
  218. avg_specie_fitness = species_record(s_ind).generation_record(2,size(species_record(s_ind).generation_record,2));
  219. offsprings = (avg_specie_fitness/avg_fit)*pop_size;
  220. overflow=overflow+offsprings-floor(offsprings);
  221. if overflow>=1
  222. offsprings=ceil(offsprings);
  223. overflow=overflow-1;
  224. else
  225. offsprings=floor(offsprings);
  226. end
  227.  
  228. if offsprings>0
  229. propagating_species=[propagating_species,[species_record(s_ind).ID;offsprings;0]];
  230. if species_record(s_ind).number_individuals>=initial.number_copy %check for condition for objective 2
  231. index_individual=index_individual+1;
  232. new_population(index_individual)=population(species_record(s_ind).generation_record(4,size(species_record(s_ind).generation_record,2))); % Objective 2
  233. propagating_species(3,size(propagating_species,2))=1; %Update matrix_existing_and_propagating_species
  234. end
  235. end
  236.  
  237. end
  238. end
  239. % propagating_species
  240. % Reference individuals from every species
  241. ref=0;
  242. for sp=1:size(species_record,2)
  243. if sum([population.species]==sp)>0
  244. ref=ref+1;
  245. % take any of the individuals from all existing species in population
  246. [discard,ind]=max(([population.species]==sp).*rand(1,size(population,2)));
  247. pop_ref(ref)=population(ind);
  248. end
  249. end
  250.  
  251. pop_ind = 0;
  252. for sp=1:size(propagating_species,2)
  253. count_individuals_species=0;
  254. species_ID=propagating_species(1,sp);
  255.  
  256. ind_species=find([population.species]==species_ID);
  257.  
  258. fitnesses_species=[population(ind_species).fitness];
  259. [discard,sorted_fitnesses]=sort(fitnesses_species);
  260. ranking=zeros(1,size(fitnesses_species,2));
  261. ranking(sorted_fitnesses)=1:size(fitnesses_species,2);
  262. %normalized fitness
  263. if size(fitnesses_species,2)>1
  264. FitnV=(2-selection.pressure+2*(selection.pressure-1)/(size(fitnesses_species,2)-1)*(ranking-1))';
  265. else
  266. FitnV=2;
  267. end
  268.  
  269. number_overall=propagating_species(2,sp)-propagating_species(3,sp);
  270. number_crossover=round(crossover.percentage*number_overall);
  271. number_mutate=number_overall-number_crossover;
  272. Nind=size(fitnesses_species,2);
  273. Nsel=2*number_crossover+number_mutate;
  274.  
  275. if Nsel==0
  276. Nsel=1;
  277. end
  278.  
  279. cumfit = cumsum(FitnV);
  280. trials = cumfit(Nind) / Nsel * (rand + (0:Nsel-1)');
  281. Mf = cumfit(:, ones(1, Nsel));
  282. Mt = trials(:, ones(1, Nind))';
  283. [NewChrIx, ans] = find(Mt < Mf & [ zeros(1, Nsel); Mf(1:Nind-1, :) ] <= Mt);
  284. [ans, shuf] = sort(rand(Nsel, 1));
  285. NewChrIx = NewChrIx(shuf);
  286. NewChrIx = ind_species(NewChrIx);
  287.  
  288.  
  289.  
  290. species_individuals = population(find([population(:).species]==propagating_species(1,sp)));
  291. while propagating_species(3,find([propagating_species(1,:)]==species_ID)) < propagating_species(2,find([propagating_species(1,:)]==species_ID))
  292. % species_individuals
  293. % rand_offs = randi(size(species_individuals,2));
  294. % offspring = species_individuals(rand_offs);
  295. pop_ind=pop_ind+1;
  296. count_individuals_species=count_individuals_species+1;
  297. offspring = population(NewChrIx(count_individuals_species));
  298.  
  299.  
  300. if rand < crossover.rate
  301. parent1 = population(NewChrIx(randi(size(NewChrIx,2))));
  302. parent2 = population(NewChrIx(randi(size(NewChrIx,2))));
  303. parent_nodes = [parent1.node_genes(:,:) parent2.node_genes(:,:)];
  304. parent_connection_genes = [parent1.connection_genes(:,:) parent2.connection_genes(:,:)];
  305.  
  306. [unique_nodes, u_n_ind, ~] = ...
  307. unique(parent_nodes(1,:));
  308. [unique_innovation_num, u_i_ind, ~] = ...
  309. unique(parent_connection_genes(1,:));
  310. offspring.node_genes = [];
  311. offspring.connection_genes = [];
  312. for node_id = 1:size(unique_nodes,2)
  313. offspring.node_genes = [offspring.node_genes ...
  314. parent_nodes(:,u_n_ind(node_id))];
  315. end
  316. for innov_id = 1:size(unique_innovation_num,2)
  317. offspring.connection_genes = [offspring.connection_genes ...
  318. parent_connection_genes(:,u_i_ind(innov_id))];
  319. end
  320. offspring.wMat = weight_matrix(offspring.node_genes,offspring.connection_genes);
  321. offspring.fitness = get_ind_fitness(offspring, RNNet, target_fitness);
  322. else
  323. offspring = population(NewChrIx(count_individuals_species));
  324. end
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333. % Weight value mutation
  334. if rand < mutation.mutate_weight
  335. offspring = weight_value_mutation(offspring,mutation);
  336. end
  337.  
  338. % Add connection mutation
  339. if rand < mutation.add_node_rate
  340. [offspring,innovation_record] = ...
  341. add_connection(offspring,innovation_record,generation,mutation.range);
  342. end
  343.  
  344. % Add node mutation
  345. if rand < mutation.add_connection_rate
  346. [offspring,innovation_record] = ...
  347. add_node(offspring,innovation_record,generation,mutation.range);
  348.  
  349. end
  350.  
  351. % % Speciation
  352. species_assigned=0;
  353. ref=0;
  354. while species_assigned==0 & ref<size(pop_ref,2)
  355. ref=ref+1;
  356. ref_ind=pop_ref(ref);
  357.  
  358. max_ref_inn = max(ref_ind.connection_genes(1,:));
  359. max_off_inn = max(offspring.connection_genes(1,:));
  360.  
  361.  
  362. if max_ref_inn > max_off_inn
  363. excess_cutoff = max_off_inn;
  364. else
  365. excess_cutoff = max_ref_inn;
  366.  
  367. end
  368.  
  369. ref_conn = ref_ind.connection_genes(1,:);
  370. off_conn = offspring.connection_genes(1,:);
  371.  
  372. matching_genes = intersect(ref_conn,off_conn);
  373. all_conn = union(ref_conn,off_conn);
  374.  
  375. disj_or_exs = setdiff(all_conn,matching_genes);
  376.  
  377. excess_inn = disj_or_exs(disj_or_exs>excess_cutoff);
  378.  
  379. disjoint_inn = setdiff(disj_or_exs,excess_inn);
  380.  
  381.  
  382. excess = size(excess_inn,2);
  383. disjoint = size(disjoint_inn,2);
  384.  
  385.  
  386.  
  387. weight_diff =0;
  388. for weight_ind = 1:size(matching_genes,2)
  389. weight1 = offspring.connection_genes(4,(offspring.connection_genes(1,:)==matching_genes(weight_ind)));
  390. weight2 = ref_ind.connection_genes(4,(ref_ind.connection_genes(1,:)==matching_genes(weight_ind)));
  391. weight_diff = weight_diff + abs(weight1 - weight2);
  392. end
  393.  
  394. average_weight_difference=weight_diff/size(matching_genes,2);
  395.  
  396. max_genes=1;
  397. distance=speciation.c1*excess/max_genes+speciation.c2*disjoint/max_genes+speciation.c3*average_weight_difference;
  398. if distance<speciation.threshold
  399. % assign individual to same species as current reference individual
  400. offspring.species=ref_ind.species;
  401. species_assigned=1; %set flag indicating new_individual has been assigned to species
  402. end
  403. end
  404. % not compatible with any? well, then create new species
  405. if species_assigned==0
  406. new_species_ID=size(species_record,2)+1;
  407. % assign individual to new species
  408. offspring.species=new_species_ID;
  409. % update species_record
  410. species_record(new_species_ID).ID=new_species_ID;
  411. species_record(new_species_ID).number_individuals=1;
  412. species_record(new_species_ID).generation_record=[generation;offspring.fitness;offspring.fitness;pop_ind];
  413. % update population reference
  414. pop_ref(size(pop_ref,2)+1)=offspring;
  415. end
  416.  
  417.  
  418. new_population(pop_ind) = offspring;
  419. propagating_species(3,sp) = propagating_species(3,sp) + 1;
  420. end
  421. end
  422.  
  423. for sp=1:size(species_record,2)
  424. species_record(sp).number_individuals=sum([new_population(:).species]==sp);
  425. end
  426.  
  427. updated_species_record = species_record;
  428. updated_innovation_record = innovation_record;
  429. end
  430.  
  431. %% Rank based selection
  432. function [new_population] = rank_based_selection(population,species_record)
  433. pop_ind = 1;
  434. new_population = population;
  435. for species_ID=1:size(species_record,2)
  436. species_individuals = population(find([population(:).species]==species_ID));
  437. if size(species_individuals,2)<0
  438. num_ind_species = species_record(species_ID).number_individuals;
  439. competitors = randi([1,size(species_individuals,2)],2,num_ind_species);
  440. for species_ind=1:num_ind_species
  441. species_ind
  442. fitness_1 = species_individuals(competitors(1,species_ind)).fitness
  443. fitness_2 = species_individuals(competitors(2,species_ind)).fitness;
  444.  
  445. if fitness_1 >= fitness_2
  446. new_population(pop_ind) = species_individuals(competitors(1,species_ind));
  447. else
  448. new_population(pop_ind) = species_individuals(competitors(2,species_ind));
  449. end
  450. pop_ind = pop_ind + 1;
  451. end
  452. end
  453. end
  454. % max_fitness=[];
  455. % max_fitness = [max_fitness population(:).fitness];
  456. % [max_v,max_id] = max(max_fitness);
  457. % min_fitness=[];
  458. % min_fitness = [min_fitness new_population(:).fitness];
  459. % [min_v,min_id] = min(min_fitness);
  460. % new_population(min_id) = population(max_id);
  461. end
  462.  
  463. %% Weight value mutation
  464. function individual = weight_value_mutation(individual,mutation)
  465. num_connections = size(individual.connection_genes(1,:),2);
  466. mutate_weights = rand(1,num_connections);
  467. perturbate_weight = rand(1,num_connections);
  468. for con_id=1:num_connections
  469. node_from = find(individual.node_genes(1,:)==individual.connection_genes(2,con_id));
  470. node_to = find(individual.node_genes(1,:)==individual.connection_genes(3,con_id));
  471. if mutate_weights(con_id) < mutation.rate
  472. if perturbate_weight(con_id) < mutation.perturbation_rate
  473. perturbation = rand(1)*2*mutation.perturbation_range-...
  474. mutation.perturbation_range;
  475. new_weight = individual.connection_genes(4,con_id) + perturbation;
  476. if new_weight < -mutation.cap
  477. new_weight = -mutation.cap;
  478. elseif new_weight > mutation.cap
  479. new_weight = mutation.cap;
  480. end
  481. individual.wMat(node_from,node_to) = new_weight;
  482. individual.connection_genes(4,con_id) = new_weight;
  483. else
  484. new_weight = rand(1)*2*mutation.range-mutation.range;
  485. individual.wMat(node_from,node_to) = new_weight;
  486. individual.connection_genes(4,con_id) = new_weight;
  487. end
  488. end
  489. end
  490. end
  491.  
  492. %% Call simulator for every individual in population to get fitness
  493. function population = get_pop_fitness(population, RNNet, target_fitness)
  494. for ind=1:size(population(:),1)
  495. population(ind).fitness = twoPole_test( population(ind).wMat, RNNet, target_fitness);%,'vis')
  496. end
  497. end
  498.  
  499. %% Call simulator for one individual to get fitness
  500. function steps = get_ind_fitness(individual, RNNet, target_fitness)
  501. steps = twoPole_test(individual.wMat, RNNet, target_fitness);%,'vis')
  502.  
  503. end
  504.  
  505. %% Built the weight matrix from connected genes
  506. function wMat = weight_matrix(node_genes,connection_genes)
  507. wMat = zeros(size(node_genes(1,:),2),size(node_genes(1,:),2));
  508. for c = 1:size(connection_genes(1,:),2)
  509. enabled = connection_genes(5,c);
  510. from_node = find(node_genes(1,:)==connection_genes(2,c));
  511. to_node = find(node_genes(1,:)==connection_genes(3,c));
  512. weight=connection_genes(4,c);
  513. if enabled
  514. wMat(from_node, to_node) = weight;
  515. else
  516. wMat(from_node, to_node) = 0;
  517. end
  518. end
  519. end
  520.  
  521. %% Add a connection to the network
  522. function [individual,innovation_record] = ...
  523. add_connection(individual,innovation_record,generation, mutation_range)
  524.  
  525. % individual.connection_genes
  526. %get all possible connection from enabled ones
  527. inn_old=max((innovation_record(5,:)<generation).*innovation_record(1,:));
  528.  
  529. pos_conn=individual.connection_genes(2:3,(individual.connection_genes(5,:)==1) & (individual.connection_genes(1,:)<=inn_old));
  530.  
  531. %choose a random 'from node' and 'to node' connection
  532.  
  533. rand_node_connection=pos_conn(:,round(rand*size(pos_conn,2)+0.5));
  534. %
  535. % rand_from_node = rand_node_connection(1);
  536. % rand_to_node = rand_node_connection(2);
  537. rand_from_node = individual.node_genes(1,round(rand*size(individual.node_genes,2)+0.5));
  538. rand_to_node = individual.node_genes(1,round(rand*size(individual.node_genes,2)+0.5));
  539.  
  540. %check innovation duplicacy
  541. current_gen_changes = innovation_record(:,innovation_record(5,:)==generation);
  542. dup = 0;
  543. if (~isempty(current_gen_changes))
  544.  
  545. for cc=1:size(current_gen_changes,2)
  546. if current_gen_changes(2,cc) == rand_from_node & current_gen_changes(3,cc) == rand_to_node
  547. next_inn_num = current_gen_changes(1,cc);
  548.  
  549. dup = 1;
  550. else
  551. next_inn_num = max(innovation_record(1,:))+1;
  552. end
  553. end
  554. else
  555. next_inn_num = max(innovation_record(1,:))+1;
  556. end
  557.  
  558. %choose a random 'from node' and 'to node'
  559.  
  560. weight = rand(1)*2*mutation_range-mutation_range;
  561. new_connection = [next_inn_num; rand_from_node; rand_to_node; weight; 1];
  562. individual.connection_genes = [individual.connection_genes new_connection];
  563. if dup==0
  564. innovation_record = [innovation_record [next_inn_num rand_from_node rand_to_node 0 generation]'];
  565. end
  566. % innovation_record
  567.  
  568. individual.wMat = weight_matrix(individual.node_genes,individual.connection_genes);
  569.  
  570. end
  571.  
  572. %% Add node to network
  573. function [individual,innovation_record] = ...
  574. add_node(individual,innovation_record,generation,mutation_range)
  575.  
  576. num_nodes = size(individual.node_genes(1,:),2);
  577. num_connections = size(individual.connection_genes(1,:),2);
  578. new_node_ID =max(innovation_record(4,:))+1;
  579.  
  580. %get all possible connection from enabled ones
  581. inn_old=max((innovation_record(5,:)<generation).*innovation_record(1,:));
  582.  
  583. pos_conn=individual.connection_genes(2:3,(individual.connection_genes(5,:)==1) & (individual.connection_genes(1,:)<=inn_old));
  584.  
  585. %choose a random 'from node' and 'to node' connection
  586.  
  587. rand_node_connection=pos_conn(:,round(rand*size(pos_conn,2)+0.5));
  588. %
  589. rand_from_node = rand_node_connection(1);
  590. rand_to_node = rand_node_connection(2);
  591.  
  592. %sanity check
  593. % rand_from_node = innovation_record(2,8);
  594. % rand_to_node = innovation_record(3,9);
  595.  
  596. %check innovation duplicacy
  597. current_gen_changes = innovation_record(:,innovation_record(5,:)==generation);
  598. % current_gen_changes;
  599. dup = 0;
  600. current_gen_changes;
  601. if (~isempty(current_gen_changes))
  602. next_inn_num = max(innovation_record(1,:))+1;
  603. for cc=1:size(current_gen_changes,2)-1
  604. if current_gen_changes(2,cc) == rand_from_node & current_gen_changes(3,cc+1) == rand_to_node
  605. next_inn_num = current_gen_changes(1,cc);
  606. new_node_ID =current_gen_changes(3,cc);
  607. dup = 1;
  608.  
  609. end
  610. end
  611. else
  612. next_inn_num = max(innovation_record(1,:))+1;
  613. end
  614. % new node gene's properties [assign node ID, type=hidden,
  615. % inp_state = 0, o_state = 0
  616. new_node_gene = [ new_node_ID ; 3; 0; 0];
  617. individual.node_genes(:,num_nodes+1) = new_node_gene;
  618.  
  619.  
  620.  
  621. %check if connection it already exists
  622. exist_from_con = find(individual.connection_genes(2,:)==rand_from_node);
  623.  
  624. if(isempty(exist_from_con))
  625. weight1=rand(1)*2*mutation_range-mutation_range;
  626. weight2=rand(1)*2*mutation_range-mutation_range;
  627. else
  628. for i=1:length(exist_from_con)
  629. if(individual.connection_genes(3,exist_from_con(i)) == rand_to_node)
  630. individual.connection_genes(5,exist_from_con(i))=0;
  631.  
  632. weight1=1;
  633. weight2=individual.connection_genes(4,exist_from_con(i));
  634.  
  635. break;
  636. else
  637. weight1=rand(1)*2*mutation_range-mutation_range;
  638. weight2=rand(1)*2*mutation_range-mutation_range;
  639. end
  640. end
  641. end
  642. new_connection_gene_1 = [ next_inn_num; rand_from_node;new_node_ID;weight1;1];
  643. new_connection_gene_2 = [ next_inn_num+1; new_node_ID;rand_to_node;weight2;1];
  644.  
  645. %return incremented global innovation number
  646. individual.connection_genes(:,num_connections+1) = new_connection_gene_1;
  647. individual.connection_genes(:,num_connections+2) = new_connection_gene_2;
  648.  
  649. individual.wMat = weight_matrix(individual.node_genes,individual.connection_genes);
  650.  
  651. %update innovation
  652. if dup==0
  653. innovation_record = [innovation_record [next_inn_num;rand_from_node;new_node_ID;new_node_ID;generation] [next_inn_num+1;new_node_ID;rand_to_node;0;generation]];
  654. end
  655. innovation_record;
  656. % individual
  657. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement