主要内容

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

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

旅行商问题

旅行商问题是一个优化问题有有限数量的城市,每个城市之间旅行的费用。我们的目标是找到一个有序集合的所有城市推销员拜访,这样成本最小化。解决旅行商问题,我们需要一个城市的位置和距离的列表,或成本,他们每个人之间。

我们的销售员是到访的城市在美国。该文件usborder.mat包含了一个美国地图变量xy和几何简化版本相同的映射的变量xxyy

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

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

城市= 40;位置= 0(城市,2);n = 1;(n < =城市)xp =兰特* 1.5;yp =兰德;如果inpolygon (xp, yp, xx和yy)地点(n - 1) = xp;位置(n, 2) = yp;n = n + 1;结束结束情节(位置(:1)、位置(:,2),“波”);

蓝色的圆圈代表城市的位置,销售员需要旅行和交付货物或皮卡。鉴于城市位置的列表,我们可以计算距离矩阵的所有城市。

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

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

默认情况下,遗传算法解算器解决优化问题的基于双和二进制字符串数据类型。函数创建、交叉和变异假设double类型的人口是一个矩阵,或逻辑的二进制字符串。遗传算法解算器还可以工作涉及任意数据类型的优化问题上。你可以使用任何你喜欢的数据结构。例如,一个自定义的数据类型可以指定使用MATLAB®单元阵列。为了使用遗传算法人口类型单元阵列必须提供一个创建函数,一个转换函数,和一个变异函数,将你的数据类型,例如,一个细胞数组。

旅行商问题所需的功能

本节将展示如何创建和注册所需的三个功能。人群中个体的旅行商问题是一个有序集合,所以人口可以很容易地使用单元阵列来表示。旅行商问题的自定义创建函数将创建一个单元阵列,说P,其中每个元素表示一组有序的城市作为一个排列向量。也就是说,销售员将旅行中指定的顺序P{我}。创建函数将返回一个细胞大小的数组PopulationSize

类型create_permutations.m
函数流行= create_permutations(据nvar、FitnessFcn选项)% create_permutations创建一个人口排列。%流行= CREATE_PERMUTATION(据nvar、FITNESSFCN选项)创建一个人口%排列每个据nvar长度的流行。% % %据nvar函数的参数:数量的变量% FITNESSFCN:适应度函数%选择:选择结构使用的GA % 2004 - 2007版权MathWorks, inc . totalPopulationSize =总和(options.PopulationSize);n =据nvar;流行=细胞(totalPopulationSize, 1);因为我= 1:totalPopulationSize流行{我}= randperm (n);结束

自定义交叉功能单元阵列,人口,并返回一个单元阵列,孩子们从交叉结果。

类型crossover_permutation.m
函数xoverKids = crossover_permutation(父母、选项、据nvar……FitnessFcn thisScore thisPopulation) % CROSSOVER_PERMUTATION定制旅行推销员的交叉功能。% XOVERKIDS = CROSSOVER_PERMUTATION(父母、选项、据nvar…% FITNESSFCN, THISSCORE THISPOPULATION)跨界车父母产生%孩子XOVERKIDS。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:矩阵的个体在当前人口% 2004 - 2015版权MathWorks公司nKids =长度(父母)/ 2;xoverKids =细胞(nKids, 1);通常% 0 (nKids,据nvar);指数= 1;i = 1: nKids %这里人口是一个细胞的特殊知识%使用数组。通常情况下,这将是thisPopulation(家长(指数):); 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
函数mutationChildren = mutate_permutation(父母、选项、据nvar……FitnessFcn、州thisScore, thisPopulation mutationRate) % MUTATE_PERMUTATION定制旅行推销员变异函数。% MUTATIONCHILDREN = MUTATE_PERMUTATION(父母、选项、据nvar…% FITNESSFCN,状态、THISSCORE THISPOPULATION MUTATIONRATE) %父母产生变异的孩子MUTATIONCHILDREN变异。% %的参数函数%父母:父母选择的选择函数%选择:选择从OPTIMOPTIONS %据nvar:创建的变量% FITNESSFCN:适应度函数%状态:状态结构使用的遗传算法解算器% THISSCORE:向量的当前人口% THISPOPULATION:矩阵的个体在当前人口% MUTATIONRATE:变异率% 2004 - 2015版权MathWorks, Inc . %我们交换两个元素的排列mutationChildren =细胞(长度(父母),1);通常% 0(长度(父母),据nvar);i = 1:长度(父母)父母= thisPopulation{父母(i)};%通常thisPopulation(父母(我):)p =装天花板(长度(父)*兰德(1、2);孩子=父母;儿童(p(1)) =父(p (2));儿童(p(2)) =父(p (1)); mutationChildren{i} = child; % Normally mutationChildren(i,:) end

我们还需要一个旅行商问题的适应度函数。个人的健康是一个有序的总距离的城市。适应度函数也需要距离矩阵计算的总距离。

类型traveling_salesman_fitness.m
函数的分数= traveling_salesman_fitness (x,距离)%为TSP traveling_salesman_fitness定义适应度函数。%分数= TRAVELING_SALESMAN_FITNESS (X,距离)计算个体的适应度%。健身是总距离x %有序集的城市距离(A, B)是距离城市%的B . % 2004 - 2007版权MathWorks公司得分= 0(大小(x, 1), 1);j = 1:尺寸(x, 1) %这里人口是一个细胞的特殊知识%使用数组。通常情况下,这将是流行(j:);p = x {j};f =距离(p(结束)、p (1));因为我= 2:长度(p) = f +距离(p(张)、p (i));最终成绩(j) = f;结束

遗传算法会叫我们的适应度函数只有一个参数x,但是我们的适应度函数有两个参数:x,距离。我们可以使用一个匿名函数来获取额外的参数的值,距离矩阵。我们创建一个函数处理FitnessFcn一个匿名函数,需要一个输入x电话,但traveling_salesman_fitnessx,距离。变量、函数处理时距离有一个值FitnessFcn创建,所以这些值被匿名函数。

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

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

类型traveling_salesman_plot.m
功能状态= traveling_salesman_plot(选项,状态,国旗,位置)% traveling_salesman_plot定制旅行推销员情节函数。% = TRAVELING_SALESMAN_PLOT状态(选择,国家,国旗,位置)情节城市%的位置和它们之间的连接线路。这个函数是特定%旅行推销员问题。% 2004 - 2006版权MathWorks公司持久x y xx yy如果strcmpi(国旗,“init”)负载(‘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(选项,国家,国旗,位置);

遗传算法选项设置

首先,我们将创建一个选项容器显示一个自定义的数据类型和人口范围。

选择= optimoptions (@ga,“PopulationType”,“自定义”,“InitialPopulationRange”,(1;城市));

我们选择自定义创建、交叉、变异,我们创造了和情节功能,以及设置一些停止条件。

选择= optimoptions(选项,“CreationFcn”@create_permutations,“CrossoverFcn”@crossover_permutation,“MutationFcn”@mutate_permutation,“PlotFcn”my_plot,“MaxGenerations”,500,“PopulationSize”现年60岁的“MaxStallGenerations”,200,“UseVectorized”,真正的);

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

numberOfVariables =城市;[x, fval原因,输出]=ga (FitnessFcn numberOfVariables,[][],[],[],[],[],[],选项)
优化终止:超过了一代又一代的最大数目。x = 1 x1单元阵列{[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原因= = 0输出结构体字段:problemtype:“无约束”rngstate: [1 x1 struct]代:500 funccount: 28563信息:优化终止:超过了一代又一代的最大数目。“maxconstraint: [] hybridflag: []

情节显示蓝色的圆圈的位置城市以及路径发现的遗传算法,销售员将旅行。路线的推销员可以从两端开始和结束时,返回到开始回家。

相关的话题