主要内容

使用遗传算法的自定义数据类型优化

这个例子展示了如何使用遗传算法来最小化使用自定义数据类型的函数。采用遗传算法求解旅行商问题。

旅行商问题

旅行商问题是一个优化问题,其中有城市的数量有限,且每个城市之间的旅行费用是已知的。我们的目标是要找到一个有序集合中的所有城市的业务员拜访使得成本最小化。为了解决旅行商问题,我们需要城市的位置和距离,或费用的清单,他们每个人之间。

我们的销售人员在访问美国城市。文件usborder.mat在变量中包含美国地图Xy和几何简化在变量的相同地图的版本xxyy

加载('usborder.mat'“x”“y”“xx”“yy”);情节(x, y,“颜色”'红色的');持有;

我们将随机生成美国境内城市的位置。我们可以使用inpolygon功能,以确保所有的城市都在里面或非常接近美国的边界。

城市= 40;位置= 0(城市,2);n = 1;(n <= cities) xp = rand*1.5;yp =兰德;如果inpolygon(XP,YP,XX,YY)位置(N,1)= XP;位置(N,2)= YP;N = N + 1;结尾结尾情节(位置(:1)、位置(:,2),“波”);

蓝圆表示业务员需要旅行和交付或皮卡货城市的位置。鉴于城市位置的列表中,我们可以计算出所有城市的距离矩阵。

距离= 0(城市);为了COUNT1 = 1:城市,为了Count2 =1:count1, x1 = locations(count1,1);日元=位置(count1, 2);x2 =位置(是从1);y2 =位置(是从2);距离(count1是从=√(x1, x2)) ^ 2 + (y1 y2) ^ 2);距离(是从count1) =距离(count1,是从);结尾;结尾;

为自定义数据类型定制遗传算法

默认情况下,遗传算法求解求解优化问题基于双和二进制字符串数据类型。突变假定人口创造,交叉的功能,并且是类型的矩阵双,或逻辑以二进制字符串的情况下。遗传算法求解器还可以对涉及任意数据类型优化问题的工作。你可以使用任何你喜欢的数据结构的人口。例如,自定义数据类型可以通过使用MATLAB®单元阵列被指定。为了使用GA.对于单元格数组类型的填充,您必须提供一个创建函数、一个交叉函数和一个突变函数,这些函数将用于您的数据类型,例如单元格数组。

旅行推销员问题所需函数

本节展示如何创建和注册三个必需的函数。旅行推销员问题的种群中的个体是一个有序集,因此可以很容易地使用单元阵列来表示种群。例如,用于旅行推销员问题的自定义创建函数将创建一个单元格数组P.,其中每个元素代表一组有序的城市作为置换矢量的。也就是说,销售员将在指定的顺序行进p {I}.创建函数将返回尺寸的单元阵列族群大小

类型create_permutations.m
功能弹出= create_permutations(NVARS,FitnessFcn,选项)%CREATE_PERMUTATIONS创建排列的群体。%POP = CREATE_PERMUTATION(NVARS,FITNESSFCN,OPTIONS)创建排列的群体%POP每个NVARS的长度。%%到函数的参数是%NVARS:数变量%FITNESSFCN:健身功能%OPTIONS:由GA%版权使用选项结构2004  -  2007年MathWorks公司totalPopulationSize =总和(options.PopulationSize);N = NVARS;弹出=细胞(totalPopulationSize,1);对于i = 1:totalPopulationSize弹出{I} = randperm(N);结尾

自定义交叉函数接受单元格数组(填充),并返回单元格数组(由交叉产生的子元素)。

类型crossover_permutation.m
function xoverKids = crossover_permutation(parent,options,NVARS,…)为旅行推销员定制的交叉函数。% xoverkids = crossover_permutation (parents, options, nvars,…)% FITNESSFCN,THISSCORE,THISPOPULATION)交叉父母产生% XOVERKIDS。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:Copyright 2004-2015 the MathWorks, Inc. nKids = length(parents)/2;xoverKids =细胞(nKids, 1);通常% 0 (nKids,据nvar);指数= 1;for i=1:nKids %在这里使用了人口是单元格%数组的特殊知识。 Normally, this would be thisPopulation(parents(index),:); parent = thisPopulation{parents(index)}; index = index + 2; % Flip a section of parent1. p1 = ceil((length(parent) -1) * rand); p2 = p1 + ceil((length(parent) - p1- 1) * rand); child = parent; child(p1:p2) = fliplr(child(p1:p2)); xoverKids{i} = child; % Normally, xoverKids(i,:); end

自定义功能的突变发生的个体,这是一组有序的城市,并返回一个突变的有序集合。

类型mutate_permutation.m
function mutationChildren = mutate_permutation(parent,options,NVARS,…)% MUTATE_PERMUTATION旅行推销员的自定义突变函数。% mutationchildren = mutate_permutation (parent, options, nvars,…)% FITNESSFCN,STATE,THISSCORE,THISPOPULATION,MUTATIONRATE)突变% PARENTS产生突变的孩子。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:这里我们交换了排列的两个元素mutationChildren = cell(length(parents),1);% normal zero (length(parents),NVARS);for i=1:length(parents) parent = thisPopulation{parents(i)};% normal thisPopulation(parents(i),:) p = cell (length(parent) * rand(1,2));孩子=父母;儿童(p(1)) =父(p (2)); child(p(2)) = parent(p(1)); mutationChildren{i} = child; % Normally mutationChildren(i,:) end

我们还需要为旅行商问题健身功能。一个人的健康是走过了一组有序的城市的总距离。健身功能也需要距离矩阵计算的总距离。

类型traveling_salesman_fitness.m
自定义TSP的适应度函数。计算个体的适合度%。距离(A,B)是从城市% A到城市B的距离。%对于j = 1:size(x,1) %,这里使用了填充是单元格%数组的特殊知识。通常,这将是pop(j,:);p = x {j};f =距离(p(结束)、p (1));For I = 2:length(p) f = f + distance (p(I -1),p(I));End scores(j) = f;结尾

GA.将调用我们的健身功能,只用一个参数X,但适应度函数有两个参数:X距离.我们可以使用匿名函数来捕获附加参数的值,即距离矩阵。我们创建一个函数句柄FitnessFcn到一个匿名函数,它有一个输入X电话,但traveling_salesman_fitnessX,和距离。变量,距离有一个值时,函数句柄FitnessFcn创建,因此这些值由匿名函数捕获。

%的距离前面定义FitnessFcn = @(X)traveling_salesman_fitness(X,距离);

我们可以添加自定义plot功能来绘制城市的位置和当前的最佳路线。红色的圆圈表示一个城市,蓝色的线表示两个城市之间的有效路径。

类型traveling_salesman_plot.m
function state = traveling_salesman_plot(options,state,flag,locations) % traveling_salesman_plot旅行推销员的自定义plot函数。% STATE = TRAVELING_SALESMAN_PLOT(OPTIONS,STATE,FLAG,LOCATIONS) Plot城市% LOCATIONS以及它们之间的连接路线。这个函数是针对旅行推销员问题的。% Copyright 2004-2006 The MathWorks, Inc. persistent x y xx yy if strcmpi(flag,'init') load('usborder.mat','x','y','xx','yy');情节(x, y,“颜色”,“红色”);轴([-0.1 1.5 -0.2 1.2]);抓住;(未使用,我)= min (state.Score);基因型= state.Population {};情节(位置(:1)、位置(:,2),“bo”); plot(locations(genotype,1),locations(genotype,2)); hold off

同样,我们将使用匿名函数来创建一个匿名函数句柄traveling_salesman_plot加上额外的参数位置

%的位置前面定义my_plot = @(选项,状态,标志)traveling_salesman_plot(选项,......国家,国旗,位置);

遗传算法的选项设置

首先,我们将创建一个options容器来指示自定义数据类型和填充范围。

选项= optimoptions(@ga,'PopulationType''风俗'“InitialPopulationRange”......(1;城市));

我们选择自定义创建,交叉,变异,和剧情的功能,我们已经创建,以及设置一些停止状况。

选项= optimoptions(选项,'CreationFcn'@create_permutations,......“CrossoverFcn”@ crossover_permutation,......“MutationFcn”@ mutate_permutation,......“PlotFcn”my_plot,......'MaxGenerations',500,“族群大小”现年60岁的......“MaxStallGenerations”,200,'UseVectorized',真的);

最后,我们调用遗传算法与我们的问题的信息。

numberOfVariables =城市;[X,FVAL,因此,输出] =......ga (FitnessFcn numberOfVariables ,[],[],[],[],[],[],[], 选项)
优化终止:超过了最大代数。X = 1x1 cell array{[14 12 36 3 5 11 40 25 38 37 7 30 28 10 23 21 27 4 1 29 26 31 9 24…]} fval = 5.3846 reason = 0 output = struct with fields: problemtype: 'unconstrained' rngstate: [1x1 struct] generations: 500 funccount: 28563 message: '优化终止:最大代数超过。' maxconstraint: [] hybridflag: []

这个图用蓝色圆圈显示了城市的位置,以及通过遗传算法找到的销售人员将要走的路线。推销员可以从路线的任意一端出发,然后返回出发地回家。

相关的话题