主要内容

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

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

旅行推销员问题

旅行推销员问题是优化问题,其中有一个有限数量的城市,每个城市之间的旅行成本都是已知的。目标是找到一个有序的所有城市的推销员访问,使成本最小化。为了解决旅行推销员问题,我们需要一张城市地点和距离或成本之间的成本。

我们的推销员正在访问美国的城市。文件usborder.mat.包含在变量中的美国地图Xy,以及变量中相同地图的几何简化版本XX.yy.

加载('usborder.mat''X''是'“xx”“yy”);绘图(x,y,“颜色”'红色的');抓住;

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

城市= 40;位置=零(城市,2);n = 1;尽管(n <=城市)XP = RAND * 1.5;yp = rand;如果INPOLYGON(XP,YP,XX,YY)位置(N,1)= XP;位置(n,2)= yp;n = n + 1;结尾结尾情节(位置(:1)、位置(:,2),“波”);

蓝色圆圈代表推销员需要旅行和交付或拾取商品的城市的位置。鉴于城市地点列表,我们可以计算所有城市的距离矩阵。

距离=零(城市);为了count1 = 1:城市,为了count2 = 1:count1,x1 =位置(count1,1);y1 =位置(count1,2);x2 =位置(count2,1);Y2 =位置(Count2,2);距离(count1,count2)= sqrt((x1-x2)^ 2 +(y1-y2)^ 2);距离(Count2,Count1)=距离(Count1,Count2);结尾;结尾;

自定义自定义数据类型的遗传算法

缺省情况下,遗传算法求解器基于双重和二进制字符串数据类型解决优化问题。创建,交叉和突变的功能假设群体是双字符串的逻辑类型的矩阵或逻辑。遗传算法求解器还可以解决涉及任意数据类型的优化问题。您可以使用您喜欢的任何数据结构。例如,可以使用MATLAB®单元格数组指定自定义数据类型。为了使用GA.使用类型单元格数组的群体,您必须提供创建功能,交叉功能和将在数据类型上工作的突变函数,例如单元格数组。

旅行商问题所需函数

本节将展示如何创建和注册三个必需的函数。旅行商问题总体中的个体是一个有序集,因此可以很容易地用单元阵列表示总体。例如,用于旅行推销员问题的自定义创建函数将创建一个单元数组P.,其中每个元素表示作为排列矢量的有序的城市集。也就是说,推销员将按规定的顺序旅行p {i}。创建函数将返回一个单元格数组人群化

类型create_permutations.m.
函数pop = create_permutations(nvars,fitnessfcn,选项)%create_permutations创建了一种排列群体。%pop = create_permition(nvars,fitnessfcn,选项)创建一个人口%的排放量,每个排放量都有一段nvars。函数的参数%%%% nvars:变量数量fitnessfcn:fitness函数%选项:ga%copyright 2004-2007使用的选项结构MathWorks,Inc。TotalPupulationsization = Sum(选项.Population);n = nvars;pop = cell(totalpopulationsize,1);对于i = 1:TotalPopulationsizationSize Pop {i} = randperm(n);结尾

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

类型Crossover_Permight.m.
xoverKids = crosover_permutation (parents,options,NVARS,…)适用于旅行推销员的自定义交叉函数。% xoverkids = crosover_permutation (parents, options, nvars,…%适合度fcn,这个分数,这个人口)与父母交叉产生%的孩子XOVERKIDS。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:版权所有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_permigute.m
函数mutationchildren = mutate_permolge(父母,选项,nvars,... fitnessfcn,state,thispoporation,mutationrate)%变异_permutation自定义突变函数用于旅行推销员。%mutationchildren = mutate_permolge(父母,选项,nvars,...%Fitnessfcn,状态,陈述,utationmulation,umatationrate)突变%父母以产生突变的儿童变异umationchildren。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:Matrix of individuals in the current population % MUTATIONRATE: Rate of mutation % Copyright 2004-2015 The MathWorks, Inc. % Here we swap two elements of the permutation mutationChildren = cell(length(parents),1);% Normally zeros(length(parents),NVARS); for i=1:length(parents) parent = thisPopulation{parents(i)}; % Normally thisPopulation(parents(i),:) p = ceil(length(parent) * rand(1,2)); child = parent; child(p(1)) = parent(p(2)); child(p(2)) = parent(p(1)); mutationChildren{i} = child; % Normally mutationChildren(i,:) end

我们还需要一个适用于旅行推销员问题的健身功能。个人的健身是针对有序城市行驶的总距离。健身功能还需要距离矩阵来计算总距离。

类型traveling_salesman_fitness.m.
traveling_salesman_fitness(x,距离)%% SCORES = TRAVELING_SALESMAN_FITNESS(X, distance)计算个体的适合度%。适应度是x中一个%有序城市集合的总距离。distance (A,B)是从城市% A到城市B的距离。对于j = 1:size(x,1) %,这里使用了特殊的知识,即总体是一个单元格%数组。通常,这将是pop(j,:);p = x {j};f =距离(p(结束)、p (1));对于I = 2:length(p) f = f + distance (p(I -1),p(I));终点得分(j) = f;结尾

GA.将用一个争论称我们的健身功能呼叫X,但我们的健身函数有两个论点:X距离。我们可以使用匿名功能来捕获附加参数的值,距离矩阵。我们创建功能句柄FitnessFcn匿名函数,需要一个输入X电话,但traveling_salesman_fitnessX和距离。变量,距离具有函数句柄时的值FitnessFcn,因此这些值将被匿名函数捕获。

百分比较早定义fitnessfcn = @(x)traveling_salesman_fitness(x,距离);

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

类型traveling_salesman_plot.m.
函数状态= traveling_salesman_plot(选项,状态,标志,位置)%traveling_salesman_plot旅行推销员的自定义绘图功能。%state = traveling_salesman_plot(选项,状态,标志,位置)绘图城市%位置和它们之间的连接路由。此功能是Traveling Salesman问题的特定%。%Copyright 2004-2006 Mathworks,Inc.持久性x y xx yy如果strcmpi(标志,'init')load('usbordmat','x','y','xx','yy');结束绘图(x,y,'颜色','红色');轴([ -  0.1 1.5-0.2 1.2]);坚持,稍等;[未使用,i] = min(state.score);Genotype = State.Population {i};绘图(位置(:,1),位置(:,2),'bo'); plot(locations(genotype,1),locations(genotype,2)); hold off

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

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

遗传算法选项设置

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

选项= Optimoptions(@ga,'人民型''风俗''initialpopulationrange'......(1;城市));

我们选择我们创建的自定义创建,交叉,突变和绘图函数,以及设置一些停止条件。

选项= Optimoptions(选项,'creationfcn',@ create_permutations,......“CrossoverFcn”,@ crossover_permolge,......'mutationfcn',@ mutate_permolge,......'plotfcn'my_plot,......'maxgenerations',500,'人口化'60,......'maxstallgenerations',200,'undervectorized',真的);

最后,我们用问题信息称之为遗传算法。

Numberofvariables =城市;[x,fval,原因,输出] =......ga(fitnessfcn,numberofvariables,[],[],[],[],[],[],[],选项)
优化终止:超出了最大几代数。x = 1x1单元阵列{1x40 double} fval = 5.3846原因= 0输出= struct with字段:问题rype:'不受约束'rngstate:[1x1 struct]代:500 funccount:28563消息:'优化终止:超出了最大几代数量。'MaxConstraint:[] HybridFlag:[]

该地块显示了蓝色圆圈中城市的位置,以及推销员将旅行的遗传算法发现的路径。推销员可以在路线的任一端开始,最后回到起始城市回家。

相关的话题