📄 ga.m
字号:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%popcount=1; % Initialize the generation count, % set it to one, the first populationif SELF_ENTERED == 0 % Make a random initial population for % base-10 operation by specifying the % matrix of initial traitsfor pop_member = 1:POP_SIZE for current_trait = 1:NUM_TRAITS, trait(current_trait,pop_member,popcount)=... (rand-(1/2))*(HIGHTRAIT(current_trait)-LOWTRAIT(current_trait))+... (1/2)*(HIGHTRAIT(current_trait)+LOWTRAIT(current_trait)); % This starts the population off with numbers chosen randomly % on the allowed range of variation, for this example. endend else for pop_member = 1:POP_SIZE for current_trait = 1:NUM_TRAITS, trait(current_trait,pop_member,popcount)=0; % To start with a guess where all the population members are zero endend end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Next, we need to set some values based on the values input by % the user. In particular, we determine the length of the % chromosome and start point of each trait. This information % will be used later in the main algorithm.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CHROM_LENGTH=sum(SIG_FIGS)+NUM_TRAITS; % Length of the chromosome is % the number of sig. figs. plus % the number of sign positions TRAIT_START(1)=1; % Initialize: the first trait % starts at the first digit % (this is the sign digit) for current_trait=1:NUM_TRAITS, % Determine the start point of the % other traits - it is the start of % the last trait plus the no. of sig. % figs. plus one for signTRAIT_START(current_trait+1)=... TRAIT_START(current_trait)+SIG_FIGS(current_trait)+1; % Yes, we compute the TRAIT_START for one extra trait - this % is used for convenience in the code below. end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% In this next loop the fitness is calculated, the children are % created and it repeats until the EPSILON-DELTA termination condition% is satisfied or MAX_GENERATION is reached. This is the main% loop of the GA.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%while popcount <= MAX_GENERATION % First, fix bad traits (i.e., ones that are out of the range % specified by HIGHTRAIT and LOWTRAIT) by saturation at the extremesfor pop_member = 1:POP_SIZEfor current_trait = 1:NUM_TRAITS,if trait(current_trait,pop_member,popcount)>HIGHTRAIT(current_trait) % The trait has went higher than the upper % bound so let the trait equal to the % HIGHTRAIT bound.trait(current_trait,pop_member,popcount)=HIGHTRAIT(current_trait);% Now consider the other case:elseif trait(current_trait,pop_member,popcount)<LOWTRAIT(current_trait) % The trait has went lower than the lower % bound so let the trait equal to the % LOWTRAIT boundtrait(current_trait,pop_member,popcount)=LOWTRAIT(current_trait); end % Now that we have reset the traits to be in range, we must % convert them to the chromosome form for use with the genetic operators.% First, we transfer the sign of the trait into the chromosome if trait(current_trait,pop_member,popcount) < 0 pop(TRAIT_START(current_trait),pop_member)=0; else pop(TRAIT_START(current_trait),pop_member)=9; end% Next, strip off the sign and store the resulting value in a% temporary variable that is used in the construction of poptemp_trait(current_trait,pop_member)=... abs(trait(current_trait,pop_member,popcount)); % temp_trait is trait without the sign of trait % Next, we store the numbers of the trait in the chromosome:% First, set up a temporary trait with at most% one nonzero digit to the left of the decimal point.% This is used to strip off the numbers to put % them into a chromosome. for counter=1:DECIMAL(current_trait)-1, temp_trait(current_trait,pop_member)=... temp_trait(current_trait,pop_member)/10; end% Encode the new trait into chromosome form for make_gene = TRAIT_START(current_trait)+1:TRAIT_START(current_trait+1)-1, % For each gene on the trait make the gene the corresponding digit on % temp_trait (note that rem(x,y)=x-roundtowardszero(x/y)*y or % rem(x,1)=x-roundtowardszero(x) so that rem(x,1) is the fraction part% and x-rem(x,1) is the integer part so the next line makes the location in% pop the same as the digit to the left of the decimal point of temp_trait pop(make_gene,pop_member)=temp_trait(current_trait,pop_member)-... rem(temp_trait(current_trait,pop_member),1);% Next, we take temp_trait and rotate the next digit to the left so that% next time around the loop it will pull that digit into the % chromosome. To do this we strip off the leading digit then shift % in the next one. temp_trait(current_trait,pop_member)=... (temp_trait(current_trait,pop_member)-pop(make_gene,pop_member))*10; end end % Ends "for current_trait=..." loop end % Ends "for pop_member=..." loop %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% USER: Below is where you change the fitness function that is to be% maximized. This may involve changing several lines of code below.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% In the example below we want to *maximize* the function z=f(x,y).% Important: When defining the fitness function you must remember that % it is a function that you are *maximizing* and that it must always be % positive (the selection mechanism depends on this). For our example, % we are maximizing the function f. Below, we include some ideas about% what to do if you seek to minimize a function.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%sumfitness = 0; % Re-initialize for each generation% First, determine the values of the function to be minimized for % each chromosome. for chrom_number = 1:POP_SIZE, % Test fitnessfitness_bar(chrom_number)=...+5*exp(-0.1*((trait(1,chrom_number,popcount)-15)^2+... (trait(2,chrom_number,popcount)-20)^2))...-2*exp(-0.08*((trait(1,chrom_number,popcount)-20)^2+... (trait(2,chrom_number,popcount)-15)^2))...+3*exp(-0.08*((trait(1,chrom_number,popcount)-25)^2+... (trait(2,chrom_number,popcount)-10)^2))...+2*exp(-0.1*((trait(1,chrom_number,popcount)-10)^2+... (trait(2,chrom_number,popcount)-10)^2))...-2*exp(-0.5*((trait(1,chrom_number,popcount)-5)^2+... (trait(2,chrom_number,popcount)-10)^2))...-4*exp(-0.1*((trait(1,chrom_number,popcount)-15)^2+... (trait(2,chrom_number,popcount)-5)^2))...-2*exp(-0.5*((trait(1,chrom_number,popcount)-8)^2+... (trait(2,chrom_number,popcount)-25)^2))...-2*exp(-0.5*((trait(1,chrom_number,popcount)-21)^2+... (trait(2,chrom_number,popcount)-25)^2))...+2*exp(-0.5*((trait(1,chrom_number,popcount)-25)^2+... (trait(2,chrom_number,popcount)-16)^2))...+2*exp(-0.5*((trait(1,chrom_number,popcount)-5)^2+... (trait(2,chrom_number,popcount)-14)^2)); end% Next, compute the fitness function (this loop is only kept % separate from the next one in case you need to implement % some of the options discussed in the comments). for chrom_number = 1:POP_SIZE, % Test fitness% The fitness function must be chosen so that it is always positive.% To ensure this for our example we assume that we know that the value% of f will never be below -5; so we simply add 5 to every fitness_bar value.% Another approach would be to simply find the minimum value % of the fitness_bar function for every element in the population % and then add on its absolute value so that all the resulting % values will be positive fitness(chrom_number)= fitness_bar(chrom_number) + 5; % Notice that when we turn a minimization problem into a maximization% problem we often use % fitness(chrom_number)= -fitness_bar(chrom_number) + max(fitness_bar);% as the above line. Here, the minus sign is% for turning the minimization problem into a maximization problem% and max(fitness_bar) is used to make the fitness function positive.% Another option would be to use the fitness function:% fitness(chrom_number)=(1/(fitness_bar(chrom_number) + .1));% The 1/fitness_bar function switches it to a maximzation problem. % The +.1 is to make sure that there is no divide by zero. Note that you can% tune the GA in this case by changing the 1 in the numerator to another % constant and the .1 to a different value.sumfitness = sumfitness + fitness(chrom_number); % Store this for % use below end% Next, determine the most fit and least fit chromosome and % the chrom_numbers (which we call bestmember and worstmember). [bestfitness(popcount),bestmember]=max(fitness);[worstfitness(popcount),worstmember]=min(fitness);% Next, save these (if want to save worstindividual can too)bestindividual(:,popcount)=trait(:,bestmember,popcount);%worstindividual(:,popcount)=trait(:,worstmember,popcount);% Compute the average fitness in case you want to plot it.avefitness(popcount) = sumfitness / POP_SIZE; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Create the next generation%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% First, form the mating pool. % To do this we select as parents the% chromosomes that are most fit. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for pop_member = 1:POP_SIZE, if ELITISM ==1 & pop_member==bestmember % If elitism on, and have % the elite member parent_chrom(:,pop_member)=pop(:,pop_member); % Makes sure that % the elite member gets into the next % generation. else pointer=rand*sumfitness; % This makes the pointer for the roulette % wheel. member_count=1; % Initialization total=fitness(1); while total < pointer, % This spins the wheel to the % pointer and finds the % chromosome there - which is % identified by member_count
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -