赞
踩
function nsga_2(pop,gen) % 函数名字叫nsga_2,参数是pop=种群大小,gen遍历的代数 %% 检测输入的各种问题 if nargin < 2 % nargin是MATLAB中管参数数量的 % 要是参数数量小于2说明少输入了 error('NSGA-II: Please enter the population size and number of generations as input arguments.'); end % 两个输入参数都需要为整数数据类型 if isnumeric(pop) == 0 || isnumeric(gen) == 0 error('Both input arguments pop and gen should be integer datatype'); end % 最小人口数必须为20个人,最小代数为5 if pop < 20 error('Minimum population for running this function is 20'); end if gen < 5 error('Minimum number of generations is 5'); end % 确保pop和gen是整数 % round函数用于舍入到最接近的整数 pop = round(pop); gen = round(gen); %% 目标函数 %M是目标空间的维数,V是决策变量空间的维数。min_range和max_range是决策变量空间中变量的范围 %用户必须使用决策变量定义目标函数。确保编辑函数“ evaluate_objective”以适合您的需求。 [M, V, min_range, max_range] = objective_description_function();
截止到这里,nsga_2.m文件没有完----1
objective_description_function()是另一个.m文件,在下边
1----接nsga_2.m文件
%% 初始化种群 %在特定范围内的随机值来进行种群的初始化,每个染色体都是由决策变量组成,同时目标函数,rank等级和拥挤距离信息的值也被添加到染色体向量中 %但是只有当中含有函数决策变量的向量元素才会进行遗传的操作,比如交叉变异(这一步不是全部都要执行的) chromosome = initialize_variables(pop, M, V, min_range, max_range); %% 初始化种群的排序 %使用非支配排序对总体进行排序。 会为每个个体返回两列,这两列的内容是所处位置对应的rank等级和拥挤度距离 %对每条染色体来说,添加rank等级和拥挤度距离到染色体向量中,以便于计算 chromosome = non_domination_sort_mod(chromosome, M, V); %% 开始进化过程 % 在每一代中执行以下操作 % * 选择适合繁殖的父代 % * 对选定的父代执行交叉和变异的操作 % * 从父代和其后代中进行选择 % * 用适合的个体替换不适合的个体,以维持恒定的人口规模。 for i = 1 : gen % 选取父代,产生子代,原始的NSGA-II是基于拥挤度比较算子通过binary tournament selection二进制竞标赛选择 % The arguments are % pool - 交配池的大小,通常来说是种群数量的一半 % tour - 竞标赛大小. 二级制竞标赛选择,但是要查看这个竞标赛大小的影响,这个是任意的,是由用户决定的 pool = round(pop/2); tour = 2; % 选择过程 %二进制随机数和它们的适应度进行比较,适应度高的个体被选为作为父代,比赛选择一直到交配池满为止, %一般来说池的大小就是被选择作为父代的个数 %函数tournament_selection输入的参数是 染色体、交配池大小、竞标赛大小 %该函数仅使用来自染色体向量中最后两个元素的信息。最后一个元素具有拥挤距离信息,而倒数第二个元素rank等级的信息。 %选择基于rank等级,如果遇到具有相同等级的个人,则比较拥挤距离。 较低的等级和较高的拥挤距离是选择标准。 parent_chromosome = tournament_selection(chromosome, pool, tour); % 进行交叉和变异操作 %原始的NSGA-II算法使用模拟二进制交叉(SBX)和多项式变异。 交叉概率pc = 0.9,变异概率为pm = 1 / n, %其中n是决策变量的数量。 在原始算法中同时实现了实编码GA和二进制编码GA,而在此程序中,仅考虑了实编码GA。 %交叉算子和变异算子的分布指数分别为mu = 20和mum = 20。 % The original NSGA-II algorithm uses Simulated Binary Crossover (SBX) and % Polynomial mutation. Crossover probability pc = 0.9 and mutation % probability is pm = 1/n, where n is the number of decision variables. % Both real-coded GA and binary-coded GA are implemented in the original % algorithm, while in this program only the real-coded GA is considered. % The distribution indeices for crossover and mutation operators as mu = 20 % and mum = 20 respectively. mu = 20; mum = 20; offspring_chromosome = ... genetic_operator(parent_chromosome, ... M, V, mu, mum, min_range, max_range); % Intermediate population(中间种群) %中间种群是当前这一代父母和后代的总人口。 人口规模是初始人口的两倍。 [main_pop,temp] = size(chromosome); [offspring_pop,temp] = size(offspring_chromosome); % temp 是一个虚拟变量. clear temp % intermediate_chromosome 是当前种群和后代种群的串联(中间种群) intermediate_chromosome(1:main_pop,:) = chromosome; intermediate_chromosome(main_pop + 1 : main_pop + offspring_pop,1 : M+V) = ... offspring_chromosome; % 中间种群的非支配排序 %在对中间种群进行替换操作之前,中间种群再一次进行排序,这次的排序是基于非支配排序的 intermediate_chromosome = ... non_domination_sort_mod(intermediate_chromosome, M, V); % 执行选择 %一旦对中间种群进行排序,根据rank等级和拥挤度距离来进行选优的 %每个前沿都以升序填充,直到达到人口总数为止。 %种群的最后一层,是根据拥挤度距离判断的 %(这个注意,在填充最后一层的时候,一般都是在一个同一个大的等级中去选择,这时候比较的就是拥挤度距离了,这也是这个算法拥挤度距离的使用之处) % The last front is included in the population based on the individuals with % least crowding distance chromosome = replace_chromosome(intermediate_chromosome, M, V, pop); if ~mod(i,100) clc fprintf('%d generations completed\n',i); end end %% Result结果 % Save the result in ASCII text format.将结果保存为ASCII文本格式。 save solution.txt chromosome -ASCII %% Visualize可视化 % 如果目标空间的尺寸是可视的,则以下内容用于可视化结果。 if M == 2 plot(chromosome(:,V + 1),chromosome(:,V + 2),'*'); elseif M ==3 plot3(chromosome(:,V + 1),chromosome(:,V + 2),chromosome(:,V + 3),'*'); end
function [number_of_objectives, number_of_decision_variables, min_range_of_decesion_variable, max_range_of_decesion_variable] = objective_description_function() % 四个返回的值是:目标函数个数、决策变量个数、决策变量最小范围、最大范围 % %sprintf函数将数据格式化为字符串或字符向量。估计意思就是提醒用户输入目标函数维度 g = sprintf('Input the number of objective: '); % 获得目标函数数 % Obtain the number of objective function % %input输入的东西当成数字或者矩阵;就是把字符串的g转化成数字 number_of_objectives = input(g); if number_of_objectives < 2 error('This is a multi-objective optimization function hence the minimum number of objectives is two'); end g = sprintf('\nInput the number of decision variables: '); % 获取决策变量的数量 % Obtain the number of decision variables number_of_decision_variables = input(g); clc for i = 1 : number_of_decision_variables clc g = sprintf('\nInput the minimum value for decision variable %d : ', i); % 获得每个决策变量的最小可能值 % Obtain the minimum possible value for each decision variable min_range_of_decesion_variable(i) = input(g); g = sprintf('\nInput the maximum value for decision variable %d : ', i); % 获得每个决策变量的最大可能值 % Obtain the maximum possible value for each decision variable max_range_of_decesion_variable(i) = input(g); clc end g = sprintf('\n Now edit the function named "evaluate_objective" appropriately to match your needs.\n Make sure that the number of objective functions and decision variables match your numerical input. \n Make each objective function as a corresponding array element. \n After editing do not forget to save. \n Press "c" and enter to continue... '); %提示用户编辑evaluate_objective函数,并等待直到按下“ c”。 % Prompt the user to edit the evaluate_objective function and wait until % 'c' is pressed. x = input(g, 's');%输入的东西当成字符串存起来; if isempty(x) x = 'x'; end while x ~= 'c'% ~=是不等于的意思 clc x = input(g, 's'); if isempty(x) x = 'x'; end end
function f = initialize_variables(N, M, V, min_range, max_range) %% function f = initialize_variables(N, M, V, min_tange, max_range) %这个函数来初始化种群的,每个染色体都有着如下的步骤 % This function initializes the chromosomes. Each chromosome has the % following at this stage % * set of decision variables 设定决策变量 % * objective function values 目标函数值 % % where, % N - Population size 种群的大小 % M - Number of objective functions 目标函数的数量 % V - Number of decision variables 决策变量的数量 % min_range - A vector of decimal values which indicate the minimum value % for each decision variable.十进制值的向量,指示每个决策变量的最小值 % max_range - Vector of maximum possible values for decision % variables.决策变量的最大值 min = min_range; max = max_range; %K是数组元素的总数。为了便于计算,将决策变量和目标函数连接 %在一起以形成单个数组。 对于交叉和变异,仅使用决策变量,而对于选择,仅使用目标变量。 % K is the total number of array elements. For ease of computation decision % variables and objective functions are concatenated to form a single % array. For crossover and mutation only the decision variables are used % while for selection, only the objective variable are utilized. K = M + V; %% Initialize each chromosome 初始化每条染色体 %每条染色体都会执行以下操作 % For each chromosome perform the following (N is the population size) for i = 1 : N %根据最小值和最大值初始化决策变量可能的值。 %V是决策变量的数量。 在每个决策变量的最小和最大值之间选择一个随机数。 % Initialize the decision variables based on the minimum and maximum % possible values. V is the number of decision variable. A random % number is picked between the minimum and maximum possible values for % the each decision variable. for j = 1 : V f(i,j) = min(j) + (max(j) - min(j))*rand(1); end %为了方便计算,染色体最后连接了目标函数的值,元素V + 1 到 K是具有目标函数值的 % For ease of computation and handling data the chromosome also has the % vlaue of the objective function concatenated at the end. The elements % V + 1 to K has the objective function valued. %函数evaluate_objective每次只获取一条染色体 %实际上,只有决策变量与有关已处理目标函数数目的信息一起传递给函数,并返回目标函数的值。 这些 %值现在存储在染色体本身的末尾。 % The function evaluate_objective takes one chromosome at a time, % infact only the decision variables are passed to the function along % with information about the number of objective functions which are % processed and returns the value for the objective functions. These % values are now stored at the end of the chromosome itself. f(i,V + 1: K) = evaluate_objective(f(i,:), M, V); end
function f = non_domination_sort_mod(x, M, V) %% function f = non_domination_sort_mod(x, M, V) %这个函数进行非支配排序,所有个体在第一层的rank等级是1,在第二层的rank等级是2,以此类推 %等级分配完成后,计算每个前沿的拥挤度 [N, m] = size(x); clear m %初始化当前的层级号为1 % Initialize the front number to 1. front = 1; %此作业没有任何内容,仅用于轻松操作的MATLAB % There is nothing to this assignment, used only to manipulate easily in % MATLAB. F(front).f = []; individual = []; %% Non-Dominated sort. 非支配排序 %初始化的种群基于非支配性进行排序。 快速排序算法[1]如下所述 % The initialized population is sorted based on non-domination. The fast % sort algorithm [1] is described as below for each %对于每个种群P当中的个体p都有着如下的操作 % ? for each individual p in main population P do the following % Sp是一个集合,代表着你在支配着谁,这个[]里面写的是种群的个体 % 该集合包含着所有由p支配的个体 % ? Initialize Sp = []. This set would contain all the individuals that is % being dominated by p. % np是一个数,代表着有多少人支配着你 % 这就是支配p的个体数量。 % ? Initialize np = 0. This would be the number of individuals that domi- % nate p. % 对于P种群的个体q来说(种群的另一个个体) % ? for each individual q in P % 如果p支配q,那么就把q放进Sp的集合中 % * if p dominated q then % ? add q to the set Sp i.e. Sp = Sp ? {q} % 如果q支配p,那么np的数量就加一了 % * else if q dominates p then % ? increment the domination counter for p i.e. np = np + 1 % 如果np为0,说明没有个体支配p,那么p就是属于第一层级 %把个体p放入当rank=1的层级,更新层级 % ? if np = 0 i.e. no individuals dominate p then p belongs to the first % front; Set rank of individual p to one i.e prank = 1. Update the first % front set by adding p to front one i.e F1 = F1 ? {p} % 这是对种群P中所有个体进行执行的 % 初始化层级的计数为1 % ? This is carried out for all the individuals in main population P. % ? Initialize the front counter to one. i = 1 % 接下来是当第i层Fi不等于空的时候执行的 %Q = []这个集合是用来储存在第i+1层的个体 %对于每个在Fi层的Sp(受p支配的个体的集合)集合的p中 %nq。。。减少个体的支配数 %nq=0 没有个体在随后接下来的前沿中支配q,因此设置q的等级为i+1,更新Q %前沿计数加一,集合Q就是下一层,因此Fi=Q % ? following is carried out while the ith front is nonempty i.e. Fi != [] % ? Q = []. The set for storing the individuals for (i + 1)th front. % ? for each individual p in front Fi % * for each individual q in Sp (Sp is the set of individuals % dominated by p) % ? nq = nq?1, decrement the domination count for individual q. % ? if nq = 0 then none of the individuals in the subsequent % fronts would dominate q. Hence set qrank = i + 1. Update % the set Q with individual q i.e. Q = Q ? q. % ? Increment the front counter by one. % ? Now the set Q is the next front and hence Fi = Q. % % This algorithm is better than the original NSGA ([2]) since it utilize % the informatoion about the set that an individual dominate (Sp) and % number of individuals that dominate the individual (np). % for i = 1 : N %支配这个个体的个体数 % Number of individuals that dominate this individual individual(i).n = 0; %站主导地位的个体(支配别人的个体) % Individuals which this individual dominate individual(i).p = []; for j = 1 : N dom_less = 0; dom_equal = 0; dom_more = 0; for k = 1 : M if (x(i,V + k) < x(j,V + k)) dom_less = dom_less + 1; elseif (x(i,V + k) == x(j,V + k)) dom_equal = dom_equal + 1; else dom_more = dom_more + 1; end end if dom_less == 0 && dom_equal ~= M individual(i).n = individual(i).n + 1; elseif dom_more == 0 && dom_equal ~= M individual(i).p = [individual(i).p j]; end end if individual(i).n == 0 x(i,M + V + 1) = 1; F(front).f = [F(front).f i]; end end %找到之后的前沿 % Find the subsequent fronts while ~isempty(F(front).f) Q = []; for i = 1 : length(F(front).f) if ~isempty(individual(F(front).f(i)).p) for j = 1 : length(individual(F(front).f(i)).p) individual(individual(F(front).f(i)).p(j)).n = ... individual(individual(F(front).f(i)).p(j)).n - 1; if individual(individual(F(front).f(i)).p(j)).n == 0 x(individual(F(front).f(i)).p(j),M + V + 1) = ... front + 1; Q = [Q individual(F(front).f(i)).p(j)]; end end end end front = front + 1; F(front).f = Q; end [temp,index_of_fronts] = sort(x(:,M + V + 1)); for i = 1 : length(index_of_fronts) sorted_based_on_front(i,:) = x(index_of_fronts(i),:); end current_index = 0; %% Crowding distance拥挤度距离 %The crowing distance is calculated as below计算方式如下 %对于每一个前沿Fi来说,n是个体的数量 % ? For each front Fi, n is the number of individuals. %对于所有的个体来说,初始化距离是0 %j对应的是在前沿Fi上 的第j个个体 % ? initialize the distance to be zero for all the individuals i.e. Fi(dj ) = 0, % where j corresponds to the jth individual in front Fi. %对于每一个目标函数m来说 % ? for each objective function m % 是基于目标函数m来对Fi上的个体进行排序 % * Sort the individuals in front Fi based on objective m i.e. I = % sort(Fi,m). % 为每个个体的边界值分配无限距离(距离为无穷大) % * Assign infinite distance to boundary values for each individual % in Fi i.e. I(d1) = ? and I(dn) = ? % * for k = 2 to (n ? 1) % ? I(dk) = I(dk) + (I(k + 1).m ? I(k ? 1).m)/fmax(m) - fmin(m) % ? I(k).m is the value of the mth objective function of the kth % individual in I 第I前沿中,第k个个体的第m个目标函数值 %在每个前沿中为每个个体找出它的拥挤度距离 % Find the crowding distance for each individual in each front for front = 1 : (length(F) - 1) % objective = []; distance = 0; y = []; previous_index = current_index + 1; for i = 1 : length(F(front).f) y(i,:) = sorted_based_on_front(current_index + i,:); end current_index = current_index + i; %对每个个体基于它的目标函数进行排序 % Sort each individual based on the objective sorted_based_on_objective = []; for i = 1 : M [sorted_based_on_objective, index_of_objectives] = ... sort(y(:,V + i)); sorted_based_on_objective = []; for j = 1 : length(index_of_objectives) sorted_based_on_objective(j,:) = y(index_of_objectives(j),:); end f_max = ... sorted_based_on_objective(length(index_of_objectives), V + i); f_min = sorted_based_on_objective(1, V + i); y(index_of_objectives(length(index_of_objectives)),M + V + 1 + i)... = Inf; y(index_of_objectives(1),M + V + 1 + i) = Inf; for j = 2 : length(index_of_objectives) - 1 next_obj = sorted_based_on_objective(j + 1,V + i); previous_obj = sorted_based_on_objective(j - 1,V + i); if (f_max - f_min == 0) y(index_of_objectives(j),M + V + 1 + i) = Inf; else y(index_of_objectives(j),M + V + 1 + i) = ... (next_obj - previous_obj)/(f_max - f_min); end end end distance = []; distance(:,1) = zeros(length(F(front).f),1); for i = 1 : M distance(:,1) = distance(:,1) + y(:,M + V + 1 + i); end y(:,M + V + 2) = distance; y = y(:,1 : M + V + 2); z(previous_index:current_index,:) = y; end f = z();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。