function [best_fit, params] = pga(pop_size, generations, p_ranges, num_xovers, mut_prob) % This function is meant to implement a simple genetic algorithm I % intend to make it in such a way that it is easy for it to turn % it into a parrellel program. pop = makepop(pop_size, p_ranges); fits = zeros(pop_size,1); changed_members = ones(pop_size,1); fits = popfit(pop, fits, changed_members); changed_members = zeros(pop_size,1); best_fit = 0; params = 0; for gen = 1 : generations, [pop, fits] = selection(pop, fits); [changed_members, pop] = mutation(pop, changed_members, mut_prob, p_ranges); [changed_members, pop] = crosover(pop, changed_members, num_xovers); fits = popfit(pop, fits, changed_members); changed_members = zeros(pop_size,1); for i = 1 : pop_size, if fits(i) > best_fit best_fit = fits(i); params = pop(i, :); disp([best_fit, params]) end end end function [newly_changed_members, new_pop] = mutation(old_pop, prev_changed_members, ... mut_prob, p_ranges) [pop_size, num_params] = size(old_pop); mutate = rand(pop_size, num_params) < mut_prob; newly_changed_members = any(mutate,2) | prev_changed_members; new_pop = rand(pop_size, num_params); for i = 1 : pop_size, for j = 1 : num_params, if mutate(i, j) new_pop(i, j) = new_pop(i, j) * (p_ranges(j,2) - p_ranges(j,1)); new_pop(i, j) = new_pop(i, j) + p_ranges(j,1); else new_pop(i, j) = old_pop(i, j); end end end function [newly_changed_members, new_pop] = crosover(old_pop, prev_changed_members, num_xovers) [pop_size, num_params] = size(old_pop); newly_changed_members = prev_changed_members; for i = 1 : num_xovers, parent_a = round(rand * (pop_size - 1) + 1); parent_b = round(rand * (pop_size - 1) + 1); cut_point = round(rand * (num_params - 2)) + 1; child_a = [old_pop(parent_a,1:cut_point) old_pop(parent_b,cut_point+1:num_params)]; child_b = [old_pop(parent_b,1:cut_point) old_pop(parent_a,cut_point+1:num_params)]; old_pop(parent_a, :) = child_a; old_pop(parent_b, :) = child_b; newly_changed_members(parent_a) = 1; newly_changed_members(parent_b) = 1; end; new_pop = old_pop; function [new_pop, new_fits] = selection(old_pop, old_fits) [pop_size, num_params] = size(old_pop); total_fit = sum(old_fits); prob = old_fits / total_fit; prob = cumsum(prob); rand_nums = sort(rand(pop_size, 1)); fitIn=1; newIn=1; while newIn <= pop_size if(rand_nums(newIn) < prob(fitIn)) new_pop(newIn, :) = old_pop(fitIn, :); new_fits(newIn, :) = old_fits(fitIn, :); newIn = newIn + 1; else fitIn = fitIn + 1; end end function new_pop = makepop(pop_size, p_ranges) % make an initial population randomly num_params = size(p_ranges,1); new_pop = rand(pop_size, num_params); for i = 1 : pop_size, for j = 1 : num_params, new_pop(i, j) = new_pop(i, j) * (p_ranges(j,2) - p_ranges(j,1)); new_pop(i, j) = new_pop(i, j) + p_ranges(j,1); end end function new_fits = popfit(pop, old_fits, changed_members) % stub for calculating fitnesses of the population % this is the part that must become parrellel global count num_changed = sum(changed_members); [pop_size, num_params] = size(pop); target = 5 * ones(1,num_params); new_fits = old_fits; for i = 1 : pop_size, if changed_members(i), new_fits(i) = 1 / norm(target - pop(i, :)); count = count + 1; end end