Advertisement
Guest User

Untitled

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