⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reproduce.m

📁 这个是关于neural fuzzy 算法的工具箱, 有例子程序, 请您用winzip解压缩
💻 M
📖 第 1 页 / 共 2 页
字号:
         new_individual=population(NewChrIx(number_crossover+count_individuals_species));
      end
      
      % Hidden nodes culling (remove any hidden nodes where there is no corresponding connection gene in the new individual)
      connected_nodes=[];
      for index_node_culling=1:size(new_individual.nodegenes,2)
          node_connected_flag=sum(new_individual.connectiongenes(2,:)==new_individual.nodegenes(1,index_node_culling))+sum(new_individual.connectiongenes(3,:)==new_individual.nodegenes(1,index_node_culling));
          if (node_connected_flag>0) | (new_individual.nodegenes(2,index_node_culling)~=3);
              connected_nodes=[connected_nodes,new_individual.nodegenes(:,index_node_culling)];
          end
      end
      new_individual.nodegenes=connected_nodes;
                 
      % Disabled Genes Mutation
      %run through all connection genes in a new_individual, find disabled connection genes, enable again with crossover.probability_gene_reenabled probability
      for index_connection_gene=1:size(new_individual.connectiongenes,2)
         if (new_individual.connectiongenes(5,index_connection_gene)==0)& (rand<mutation.probability_gene_reenabled)
            new_individual.connectiongenes(5,index_connection_gene)=1; 
         end
      end
            
      % Weight Mutation
      %run through all connection genes in a new_individual, decide on mutating or not
      for index_connection_gene=1:size(new_individual.connectiongenes,2)
         if rand<mutation.probability_mutate_weight %*index_connection_gene/size(new_individual.connectiongenes,2) %linearly biased towards higher probability of mutation at end of connection genes
            new_individual.connectiongenes(4,index_connection_gene)=new_individual.connectiongenes(4,index_connection_gene)+mutation.weight_range*(rand-0.5); 
         end
         % weight capping
         new_individual.connectiongenes(4,index_connection_gene)=new_individual.connectiongenes(4,index_connection_gene)*(abs(new_individual.connectiongenes(4,index_connection_gene))<=mutation.weight_cap)+(sign(new_individual.connectiongenes(4,index_connection_gene))*mutation.weight_cap)*(abs(new_individual.connectiongenes(4,index_connection_gene))>mutation.weight_cap);
      end
      
      % IMPORTANT: The checks for duplicate innovations in the following two types of mutation can only check in the current generation
      % Add Connection Mutation
      flag_recurrency_enabled=rand<mutation.probability_recurrency;
      vector_possible_connect_from_nodes=new_individual.nodegenes(1,:); %connections can run from every node
      vector_possible_connect_to_nodes=new_individual.nodegenes(1,find((new_individual.nodegenes(2,:)==2)+(new_individual.nodegenes(2,:)==3))); %connections can only run into hidden and output nodes
      number_possible_connection=length(vector_possible_connect_from_nodes)*length(vector_possible_connect_to_nodes)-size(new_individual.connectiongenes,2);
      
      flag1=(rand<mutation.probability_add_node);
      
      if (rand<mutation.probability_add_connection) & (number_possible_connection>0) & (flag1==0) %check if new connections can be added to genes (if there are any possible connections which are not already existing in genes of new individual)
         % First build matrix containing all possible new connection for nodegene of new individual 

         new_connection_matrix=[];
         for index_connect_from=1:length(vector_possible_connect_from_nodes) 
            for index_connect_to=1:length(vector_possible_connect_to_nodes) 
               possible_connection=[vector_possible_connect_from_nodes(index_connect_from);vector_possible_connect_to_nodes(index_connect_to)];
               if sum((new_individual.connectiongenes(2,:)==possible_connection(1)).*(new_individual.connectiongenes(3,:)==possible_connection(2)))==0 % Check if proposed connection is not already contained in gene
                  new_connection_matrix=[new_connection_matrix,possible_connection];
               end
            end
         end
         % Shuffle possible new connections randomly
         [discard,shuffle]=sort(rand(1,size(new_connection_matrix,2)));
         new_connection_matrix=new_connection_matrix(:,shuffle);
         
         index_new_connection=0;
         flag_connection_ok=0;         
         % check if connection is o.k. (meaning either non-recurrent or recurrent and flag_recurrency_enabled set to 1) if not connection is found which is o.k.,no connection will be added to connection genes of new individual
         while (flag_connection_ok==0) & (index_new_connection<size(new_connection_matrix,2)) 
            index_new_connection=index_new_connection+1;
            new_connection=new_connection_matrix(:,index_new_connection);
             
            % test new connection if it is recurrent (i.e. at least one of the possibles path starting from connect_to node in the network leads back to the connect_from node 
            flag_recurrent=0;            
            if new_connection(1)==new_connection(2) %trivial recurrency
               flag_recurrent=1;
            end
            nodes_current_level=new_connection(2);
            depth=0;
            while flag_recurrent==0 & depth<size(new_individual.connectiongenes,2) & ~isempty(nodes_current_level)
               depth=depth+1;
               nodes_next_level=[];
               for index_check=1:size(nodes_current_level);                  
                  nodes_next_level=[nodes_next_level,new_individual.connectiongenes(3,find(new_individual.connectiongenes(2,:)==nodes_current_level(index_check)))];
               end
               if sum(nodes_next_level(:)==new_connection(1))>0
                  flag_recurrent=1;
               end
               nodes_current_level=nodes_next_level;
            end
            if flag_recurrent==0 
               flag_connection_ok=1;
            elseif flag_recurrency_enabled 
               flag_connection_ok=1;
            end            
         end
                 
         % Now we test if it is a true innovation (i.e. hasn't already happened in this generation) we can only do this if a valid new connection has been found
         if flag_connection_ok
            index_already_happened=find((innovation_record(5,:)==generation).*(innovation_record(2,:)==new_connection(1)).*(innovation_record(3,:)==new_connection(2))); %set flag signifying new innovation (connection not contained in innovation_record of this generation)  
            new_innovation=not(sum(index_already_happened)); 
            if new_innovation==1 % O.K. is new innovation
               new_connection=[max(innovation_record(1,:))+1;new_connection]; %Update the new connection with its innovation number
               % Update connection_genes
               new_individual.connectiongenes=[new_individual.connectiongenes,[new_connection;rand*2-1;1]];
               % Update innovation_record
               innovation_record=[innovation_record,[new_connection;0;generation]];               
            else % connection gene already exists in innovation_record of this generation
               % Update connection_genes
               new_individual.connectiongenes=[new_individual.connectiongenes,[innovation_record(1:3,index_already_happened);rand*2-1;1]];         
            end
         end         
      end
            
      % Add (Insert) Node Mutation
      new_innovation=0;
      if flag1==1
         max_old_innovation_number=max((innovation_record(5,:)<generation).*innovation_record(1,:)); %highest innovation number from last generation (to ensure that only connections from from last generation or older are chosen for add node mutation, otherwise a new connection added in the last mutation might instantly be disabled)
         vector_possible_connections=[new_individual.connectiongenes(2:3,find((new_individual.connectiongenes(5,:)==1) & (new_individual.connectiongenes(1,:)<=max_old_innovation_number)));find((new_individual.connectiongenes(5,:)==1) & (new_individual.connectiongenes(1,:)<=max_old_innovation_number))];  %compute vector of connections into which a new node could be inserted and their positions in the connection_gene matrix. This vector is composed of all nondisabled connections which stem at least from the last generation or older
         insert_node_connection=vector_possible_connections(:,round(rand*size(vector_possible_connections,2)+0.5));
         new_innovation=1; %set provisionally to 1, will be checked
         exist_innovation=find((innovation_record(5,:)==generation).*(innovation_record(4,:)>0).*(innovation_record(2,:)==insert_node_connection(1))); %Beginning of check innovation record to test for real innovation. exist_innovation contains vector of index of elements in innovation record which fulfil three things: current generation, add node mutation and same connect from as current innovation
         if sum(exist_innovation)>0 %if these are fulfilled, we have to test for connect_to node to see if innovation really is the same
            for index_check=1:length(exist_innovation)
               if innovation_record(3,exist_innovation(index_check)+1)==insert_node_connection(2)
                  new_innovation=0;                   
                  index_already_existent_this_generation=exist_innovation(index_check);
               end
            end
         end
         if new_innovation==1 %O.K. is true innovation for current generation
            % Update node_genes
            new_node_number=max(innovation_record(4,:))+1;
            new_individual.nodegenes=[new_individual.nodegenes,[new_node_number;3;0;0]];
            % Update connection_genes
            new_individual.connectiongenes(5,insert_node_connection(3))=0; %disable old connection gene
            new_connections=[[max(innovation_record(1,:))+1;insert_node_connection(1);new_node_number;1;1],[max(innovation_record(1,:))+2;new_node_number;insert_node_connection(2);new_individual.connectiongenes(4,insert_node_connection(3));1]];
            new_individual.connectiongenes=[new_individual.connectiongenes,new_connections]; %extend connection_genes by the two new connections
            % Update innovation_record
            innovation_record=[innovation_record,[new_connections(1:3,:);new_node_number,0;generation,generation]];
         else %no new innovation, has already happened at least once in this generation
            % Update node_genes
            node_number=innovation_record(4,index_already_existent_this_generation);
            new_individual.nodegenes=[new_individual.nodegenes,[node_number;3;0;0]];
            % Update connection_genes
            new_individual.connectiongenes(5,insert_node_connection(3))=0; %disable old connection gene
            new_connections=[innovation_record(1:3,index_already_existent_this_generation:index_already_existent_this_generation+1);1,new_individual.connectiongenes(4,insert_node_connection(3));1,1];        
            length_con_gen=size(new_individual.connectiongenes,2); %length of the connection genes of current new_individual
            if new_individual.connectiongenes(1,length_con_gen)>new_connections(1,2) % check if there was an add_connection_mutation to current new_individual which has a higher innovation number than current add_node_mutation
                new_individual.connectiongenes=[new_individual.connectiongenes(:,1:length_con_gen-1),new_connections,new_individual.connectiongenes(:,length_con_gen)];


            else 
               new_individual.connectiongenes=[new_individual.connectiongenes,new_connections];
            end
         end                 
      end
      
      %% Speciation 
      % Loop through comparison vector
      species_assigned=0;
      index_population_ref=0;
      while species_assigned==0 & index_population_ref<size(population_ref,2)
         %extract reference_individual from reference population
         index_population_ref=index_population_ref+1;
         reference_individual=population_ref(index_population_ref);
         %run through both connection genes, compute disjoint, excess, and average weight difference
         max_num_genes=max([size(new_individual.connectiongenes,2),size(reference_individual.connectiongenes,2)]);
         max_num_innovation=max([new_individual.connectiongenes(1,:),reference_individual.connectiongenes(1,:)]); 
         vector_innovation_new=[zeros(1,max(new_individual.connectiongenes(1,:))),ones(1,max_num_innovation-max(new_individual.connectiongenes(1,:)))];
         vector_innovation_new(new_individual.connectiongenes(1,:))=2;
         vector_weight_new=zeros(1,max_num_innovation);
         vector_weight_new(new_individual.connectiongenes(1,:))=new_individual.connectiongenes(4,:);
         vector_innovation_ref=[4*ones(1,max(reference_individual.connectiongenes(1,:))),8*ones(1,max_num_innovation-max(reference_individual.connectiongenes(1,:)))];
         vector_innovation_ref(reference_individual.connectiongenes(1,:))=16;
         vector_weight_ref=zeros(1,max_num_innovation);
         vector_weight_ref(reference_individual.connectiongenes(1,:))=reference_individual.connectiongenes(4,:);
         vector_lineup=vector_innovation_new+vector_innovation_ref;
         excess=sum(vector_lineup==10)+sum(vector_lineup==17);
         disjoint=sum(vector_lineup==6)+sum(vector_lineup==16);
         vector_matching=find(vector_lineup==18);
         average_weight_difference=sum(abs(vector_weight_new(vector_matching)-vector_weight_ref(vector_matching)))/length(vector_matching);
         max_num_genes=1;
         distance=speciation.c1*excess/max_num_genes+speciation.c2*disjoint/max_num_genes+speciation.c3*average_weight_difference;
         if distance<speciation.threshold
            % assign individual to same species as current reference individual

            new_individual.species=reference_individual.species;
            species_assigned=1; %set flag indicating new_individual has been assigned to species            
         end         
      end      
      % not compatible with any? well, then create new species
      if species_assigned==0
         new_species_ID=size(species_record,2)+1;
		   % assign individual to new species
         new_individual.species=new_species_ID;
         % update species_record
         species_record(new_species_ID).ID=new_species_ID;
         species_record(new_species_ID).number_individuals=1;
         species_record(new_species_ID).generation_record=[];
         % update population reference
         population_ref(size(population_ref,2)+1)=new_individual;
      end
      
      % add new_individual to new_population
      new_population(index_individual)=new_individual;
      
      %Increment species
      matrix_existing_and_propagating_species(3,index_species)=matrix_existing_and_propagating_species(3,index_species)+1;
   end
end

% final update of species_record (can only be done now since old population sizes were needed during reproduction cycle)
for index_species=1:size(species_record,2)
   species_record(index_species).number_individuals=sum([new_population(:).species]==index_species);
end
%assign updated species_record to output
updated_species_record=species_record;
%assign updated innovation_record to output
updated_innovation_record=innovation_record;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -