《MATLAB遗传算法工具箱及应用》课件第8章_第1页
《MATLAB遗传算法工具箱及应用》课件第8章_第2页
《MATLAB遗传算法工具箱及应用》课件第8章_第3页
《MATLAB遗传算法工具箱及应用》课件第8章_第4页
《MATLAB遗传算法工具箱及应用》课件第8章_第5页
已阅读5页,还剩331页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八章使用MATLAB遗传算法工具8.1遗传算法与直接搜索工具箱概述8.1.1工具箱的特点遗传算法(GeneticAlgorithm)与直接搜索(DirectSearch)优化工具是一系列函数的集合,它们扩展了优化工具箱和MATLAB数值计算环境的性能。遗传算法与直接搜索工具箱包含了要使用遗传算法和直接搜索算法来求解优化问题的一些例程。这些算法使我们能够求解那些标准优化工具箱范围之外的各种优化问题。所有工具箱函数都是MATLAB的M文件,这些文件由实现特定优化算法的MATLAB语句所写成。使用语句

typefunction

name

就可以看到这些函数的MATLAB代码。我们也可以通过编写自己的M文件来实现来扩展遗传算法和直接搜索工具箱的性能,也可以将该工具箱与MATLAB的其他工具箱或Simulink结合使用,来求解优化问题。

工具箱函数可以通过图形界面或MATLAB命令行来访问,它们是用MATLAB语言编写的,对用户开放,因此可以查看算法、修改源代码或生成用户函数。遗传算法与直接搜索工具箱可以帮助我们求解那些不易用传统方法解决的问题,譬如表查找问题等。

遗传算法与直接搜索工具箱有一个精心设计的图形用户界面,可以帮助我们直观、方便、快速地求解最优化问题。

1.功能特点

遗传算法与直接搜索工具箱的功能特点如下:

(1) 图形用户界面和命令行函数可用来快速地描述问题、设置算法选项以及监控进程。

(2) 具有多个选项的遗传算法工具可用于问题创建、适应度计算、选择、交叉和变异。

(3) 直接搜索工具实现了一种模式搜索方法,其选项可用于定义网格尺寸、表决方法和搜索方法。

(4) 遗传算法与直接搜索工具箱函数可与MATLAB的优化工具箱或其他的MATLAB程序结合使用。

(5) 支持自动的M代码生成。2.图形用户界面和命令行函数〖MZ)〗

遗传算法工具函数可以通过命令行和图形用户界面来使用遗传算法。直接搜索工具函数也可以通过命令行和图形用户界面来进行访问。图形用户界面可用来快速地定义问题、设置算法选项、对优化问题进行详细定义。

遗传算法与直接搜索工具箱还同时提供了用于优化管理、性能监控及终止准则定义的工具,同时还提供大量标准算法选项。

在优化运行的过程中,可以通过修改选项来细化最优解,更新性能结果。用户也可以提供自己的算法选项来定制工具箱。

3.使用其他函数和求解器

遗传算法与直接搜索工具箱与MATLAB及优化工具箱是紧密结合在一起的。用户可以用遗传算法或直接搜索算法来寻找最佳起始点,然后利用优化工具箱或用MATLAB程序来进一步寻找最优解。通过结合不同的算法,可以充分地发挥MATLAB和工具箱的功能以提高求解的质量。对于某些特定问题,使用这种方法还可以得到全局(最优)解。

4.显示、监控和输出结果

遗传算法与直接搜索工具箱还包括一系列绘图函数用来可视化优化结果。这些可视化功能直观地显示了优化的过程,并且允许在执行过程中进行修改。

工具箱还包括一系列绘图函数用来可视化优化结果。这些可视化功能直观地显示了优化的过程,并且允许在执行过程中进行修改。该工具箱还提供了一些特殊绘图函数,它们不仅适用于遗传算法,还适用于直接搜索算法。适用于遗传算法的函数包括函数值、适应度值和函数估计。适用于直接搜索算法的函数包括函数值、分值直方图、系谱、适应度值、网格尺寸和函数估计。这些函数可以将多个绘图一并显示,可直观方便地选取最优曲线。另外,用户也可以添加自己的绘图函数。

使用输出函数可以将结果写入文件,产生用户自己的终止准则,也可以写入用户自己的图形界面来运行工具箱求解器。除此之外,还可以将问题的算法选项导出,以便日后再将它们导入到图形界面中去。

5.所需的产品支持

遗传算法与直接搜索工具箱作为其他优化方法的补充,可以用来寻找最佳起始点,然后可以再通过使用传统的优化技术来进一步寻找最优解。工具箱需要如下产品支持:

(1)MATLAB;

(2)优化工具箱。

6.相关产品

与遗传算法与直接搜索工具箱相关的产品有:

(1) 统计工具箱——应用统计算法和概率模式。

(2) 神经网络工具箱——设计和仿真神经网络。

(3) 模糊逻辑工具箱——设计和仿真基于模糊逻辑的系统。

(4) 金融工具箱——分析金融数据和开发金融算法。

7.所需的系统及平台

MATLAB7.x所需的最低配置是:Windows系列操作系统,PentiumIII500CPU、64MBRAM,空闲硬盘空间600MB以上。

MATLAB8.x所需最低配置是:Windows系列操作系统,Intel或者AMDx86系列处理器(需支持SSE2指令集),1GB内存,空闲硬盘空间1GB以上。

8.1.2编写待优化函数的M文件

1.编写M文件举例

假定我们想要计算下面函数的最小值:

M文件确定这个函数必须接受一个长度为2的行向量X,分别与变量x1和x2相对应,并且返回一个标量X,其值等于该函数的值。为了编写这个M文件,执行如下步骤:

MATLAB8.x版本,界面与MATLAB7.x版本略有不同,其步骤如下:

(1)在MATLAB的Home栏中选择New菜单项。

(2)选择Script文件,将在编辑器中打开一个新的M文件。(3)在该M文件中,输入下面两行代码:functionz=my_fun(x)z=x(1)^2-2*x(1)*x(2)+6*x(1)+x(2)^2-6*x(2);(4)在MATLAB路径指定的目录中保存该M文件。为了查看该M文件是否返回正确的值,可键入my

fun([23])ans=-5使用MATLAB7.x版本编写这个M文件的步骤如下:

(1)在MATLAB的File菜单中选择New菜单项。

(2)选择M-File,将在编辑器中打开一个新的M文件。

(3)在该M文件中,输入下面两行代码:

functionz=my_fun(x)

z=x(1)^2-2*x(1)*x(2)+6*x(1)+x(2)^2-6*x(2);(4)在MATLAB路径指定的目录中保存该M文件。

为了查看该M文件是否返回正确的值,可输入

my_fun([23])

ans=

-5

注意:在运行遗传算法工具或模式搜索工具时,不要使用编辑器或调试器来调试目标函数的

M文件,否则会导致在命令窗口出现Java异常消息,并且使调试更加困难。

2.最大化与最小化

遗传算法和直接搜索工具箱中的优化函数总是使目标函数或适应度函数最小化。也就是说,它们求解如下形式的问题:

如果想要求出函数f(x)的最大值,可以转而求取函数g(x)=-f(x)的最小值,因为函数g(x)最小值出现的地方与函数f(x)最大值出现的地方相同。例如,要求前面所描述的函数的最大值时,我们应当编写一个M文件求函数的最小值。

3.自动代码生成

遗传算法和直接搜索工具箱具有自动代码生成特性,可以自动生成求解优化问题所需要的M文件。图8.1所示的就是使用遗传算法工具的自动代码生成特性所产生的M文件。

另外,图形用户界面所输出的优化结果可以作为对命令行调用代码的一种解释,这些代码还可用于使例程和保护工作自动化。图8.1

MATLAB的遗传算法工具 8.2使用遗传算法工具初步

8.2.1遗传算法使用规则遗传算法是一种基于自然选择、生物进化过程来求解问题的方法。遗传算法可以反复修改对于个体解决方案的种群。在每一步,遗传算法随机地从当前种群中选择若干个体作为父辈,并且使用它们产生下一代的子种群。在连续若干代之后,种群朝着优化解的方向进化。在每一步,遗传算法都可使用下列三类规则来创建下一代的子种群:

(1)选择规则(Selectionrules),选择对下一代种群有贡献的个体,称为父辈。

(2)交叉规则(Crossoverrules),将两个父辈结合起来构成下一代的子辈种群。

(3)变异规则(Mutationrules),施加随机变化给父辈个体来构成子辈。表8.1遗传算法与标准优化算法比较8.2.2遗传算法使用方式

遗传算法工具有两种使用方式:

(1)以命令行方式调用遗传算法函数ga。

(2)通过图形用户界面(GUI)使用遗传算法工具。

1.以命令行方式调用遗传算法函数ga

在命令行使用遗传算法时,可以用下列语法调用遗传算法函数ga:

[xfval]=ga(@fitnessfun,nvars,options)

其中,@fitnessfun是适应度函数句柄;nvars是适应度函数的独立变量的个数;options是一个包含遗传算法选项参数的结构。如果不传递选项参数,则ga使用缺省的选项值。

函数所给出的结果:fval是适应度函数的最终值;x是最终值到达的点。

我们可以十分方便地把遗传算法工具输出的结果直接返回到MATLAB的workspace(工作空间),或以不同的选项从M文件中多次调用函数ga来运行遗传算法。

调用函数ga时,需要提供一个选项结构options。后面的有关章节详细地描述了在命令行使用函数ga和创建选项结构options的方法。

2.通过GUI使用遗传算法

为了打开遗传算法工具,可输入

gatool

在MATLAB7.x中,遗传算法工具的图形用户界面如图8.2(a)所示。

需要说明的是,在MATLAB8.x中,要打开遗传算法工具箱,可输入:optimtool(′ga′),初启时的界面显示如图8.2(b)所示。也可以输入optimtool,然后在Solver菜单中选择遗传算法。图8.2

MATLAB的遗传算法工具图8.2

MATLAB的遗传算法工具使用遗传算法工具时,必须输入下列信息:

(1)Fitnessfunction(适应度函数)——欲求最小值的目标函数。输入适应度函数的形式为@fitnessfun,其中fitnessfun.m是计算适应度函数的M文件。符号@产生一个对于函数fitnessfun的函数句柄。

(2)Numberofvariables(变量个数)——适应度函数输入向量的长度。

在MATLAB7.x版本中,单击Start按钮,运行遗传算法,将在Statusandresults(状态与结果)窗格中显示出相应的运行结果。

在MATLAB8.x版本中,单击Start按钮,运行遗传算法,将在Runsolveandviewresults(运行与结果)窗格中显示出相应的运行结果。

在Options窗格中可以改变遗传算法的选项。为了查看窗格中所列出的各类选项,可单击与之相连的符号“+”。8.2.3举例:Rastrigin函数

Rastrigin函数是最常用来测试遗传算法的典型函数。Rastrigin函数的可视化图形显示具有多个局部最小值和一个全局最小值,遗传算法可以帮助我们确定这种具有多个局部最小值函数的最优解。

1.Rastrigin函数

具有两个独立变量的Rastrigin函数定义为Rastrigin函数的图形如图8.3所示。图8.3

Rastrigin函数图形工具箱中包含的M文件rastriginsfcn.m是用来计算Rastrigin函数值的。

如图8.3所示,Rastrigin函数有许多局部最小值——在图上显示为“谷底(valleys)”。然而,该函数只有一个全局最小值,出现在x[CD*2]y平面上的点[0,0]处(图8.3中竖直线指示处),其函数的值为0。在任何不同于点[0,0]的局部最小值处,Rastrigin函数的值均大于0。局部最小值距原点越远,该点的Rastrigin函数的值越大。

Rastrigin函数之所以最常用来测试遗传算法,是因为它有许多局部最小值,使得用标准的、基于梯度的查找全局最小值的方法十分困难。

图8.4所示是Rastrigin函数的轮廓线,它显示出最大、最小值交替变化的情形。图8.4

Rastrigin函数的轮廓线

2.寻找Rastrigin函数的最小值

本节介绍如何使用遗传算法来寻找Rastrigin函数的最小值。

注意:因为遗传算法可使用随机数据来进行搜索,所以该算法每一次运行时所返回的结果会稍微有些不同。

为了查找最小值,进行下列步骤:

(1)在命令行中输入gatool,打开遗传算法工具(在MATLAB8.x版本中应输入optimtool(′ga′))。

(2)在遗传算法工具的相应栏目中,输入适应度函数和变量个数。在“Fitnessfunction(适应度函数)”文本框中,输入:@rastriginsfcn;在“Numberofvariables(变量个数)”文本框中,输入2,这就是Rastrigin函数独立变量的个数,如图8.5所示。图8.5输入适应度函数与变量个数的界面

(3)在“Runsolver(运行求解器)”窗格中,单击Start按钮,如图8.6所示。(MATLAB8.x版本中为“Runsolverandviewresults”窗格。)图8.6单击运行求解器“Start”按钮在算法运行的同时,“Currentgeneration(当前代数)”文本框中显示出当前的代数。

“Pause(暂停)”按钮,可用于暂停/恢复算法的运行。在MATLAB7.x中,当算法完成时,“Statusandresults”窗格中出现如图8.7(a)所示的情形。

在MATLAB8.x中,当算法完成时,“Runsolveandviewresults”窗格中出现如图8.7(b)所示的情形,由于ga是随机的,所以数值运行结果会与图表中有差异。图8.7状态与结果显示图8.7(b)中的窗格显示下列信息:

(1)算法终止时适应度函数的最终值:

Objectivefunctionvalue:0.05531602101322264

注意:所显示的值非常接近于Rastrigin函数的实际最小值0。“遗传算法举例”一节描述了一些方法,可以用来得到更接近实际最小值的结果。

(2)算法终止的原因:

Optimizationterminated:

averagechangeinthefitnessvaluelessthanoptions.TolFun.

在MATLAB7.x中,终止的原因是:超过最大代数而导致优化终止。

在MATLAB8.x中,终止的原因是:适应度函数值的平均变化小于TolFun这个参数。

在本例中,算法在100代后结束,这是“Generations(代数)”选项的缺省值,此选项规定了算法计算的最大代数。

(3)最终点,在本例中是[0.001-0.017]。

3.从命令行查找最小值

从命令行查找Rastrigin函数的最小值时,可键入:

[xfvalreason]=ga(@rastriginsfcn,2)

在MATLAB7.x中,将返回:

x=

0.0027-0.0052

fval=

0.0068

reason=

Optimizationterminated:

maximumnumberofgenerationsexceeded.

其中,x是算法返回的最终点;fval是该最终点处适应度函数的值;reason是算法终止的原因。在MATLAB8.x中,将返回:

Optimizationterminated:

averagechangeinthefitnessvaluelessthanoptions.TolFun

x=

0.001

-0.017

fval=

0.1058

exitflag=

1

其中,x是算法返回的最终点;fval是该最终点处适应度函数的值;exitflag是算法终止原因对应的整数值。

4.显示绘制图形

“Plots(绘图)”对话框可以显示遗传算法运行时所提供的有关信息的各种图形。这些信息可以帮助我们改变算法的选项,改进算法的性能。例如,为了绘制每一代适应度函数的最佳值和平均值,可以选中复选框“Bestfitness(最佳适应度)”,如图8.8所示。(在MATLAB8.x中绘图对话框为“Plotfunctions”。)图8.8绘图对话框当单击Start按钮时,遗传算法工具显示了每一代适应度函数的最佳值和平均值的绘制图形。当算法停止时,所显示的图形如图8.9所示。

图8.9底部的点表示每一代的最佳适应度值,而其上的点表示平均适应度值。图的顶部还显示了当前一代的最佳值0.0067796和平均值0.014788。

为了得到更直观图形,可以减少最佳适应度,即将图中Y轴的刻度改变为对数刻度。为此,需进行如下操作:图8.9各代适应度函数的最佳值和平均值

(1)从绘图窗格的Edit(编辑)菜单中选择“AxesProperties(坐标轴属性)”,打开属性编辑器,如图8.10所示。

(2)单击Y表项。

(3)在“Scale(刻度)”窗格中,选择“Log(对数)”。

绘制的图形如图8.11所示。

在早期各代中,当个体离理想值较远时,最佳值会迅速得到改进。在后来各代中,种群越接近最佳点,最佳值改进得越慢。图8.10绘图属性编辑器8.2.4遗传算法的一些术语

1.适应度函数

所谓适应度函数,就是要优化的函数。对于标准优化算法而言,这个函数称为目标函数。该工具箱总是试图寻找适应度函数的最小值。

我们可以将适应度函数编写为一个M文件,作为输入参数传递给遗传算法函数。

2.个体

个体是可以施加适应度函数的任意一点。一个个体的适应度函数值就是它的得分或评价。例如,如果适应度函数是则向量(2,-3,1)就是一个个体,向量的长度就是问题中变量的个数。个体(2,-3,1)的得分是f(2,-3,1)=51。个体有时又称为基因组或染色体组(genome),个体的向量项称为基因(genes)。

3.种群与代

所谓种群,是指由个体组成的一个数组或矩阵。如果个体的长度是100,适应度函数中变量的个数为3,我们就可以将这个种群表示为一个100×3的矩阵。相同的个体在种群中可以出现不止一次。例如,个体(2,-3,1)就可以在数组的行中出现多次。

每一次迭代,遗传算法都对当前种群执行一系列的计算,产生一个新的种群。每一个后继的种群称为新的一代。图8.12种群多样性比较

4.多样性

多样性或差异(Diversity)涉及一个种群的各个个体之间的平均距离。若平均距离大,则种群具有高的多样性;否则,其多样性低。在图8.12中,左面的种群多样性高,亦即差异大;而右面的种群多样性低,亦即差异小。

多样性是遗传算法必不可少的本质属性,这是因为它能使遗传算法搜索一个比较大的解的空间区域。

5.适应度值和最佳适应度值

个体的适应度值就是该个体的适应度函数的值。由于该工具箱总是查找适应度函数的最小值,

所以一个种群的最佳适应度值就是该种群中任何个体的最小适应度值。

6.父辈和子辈

为了生成下一代,遗传算法在当前种群中选择某些个体,称为父辈,并且使用它们来生成下一代中的个体,称为子辈。典型情况下,该算法更可能选择那些具有较佳适应度值的父辈。8.2.5遗传算法如何工作

1.算法要点

下面给出了遗传算法的工作方法:

(1)利用算法创建一个随机种群。

(2)利用算法生成一个新的种群序列,即新的一代。在每一步,该算法都使用当前一代中的个体来生成下一代。为了生成新一代,算法执行下列步骤:

①通过计算其适应度值,给当前种群的每一个成员打分。

②确定原来的适应度值的比例尺度,将其转换为更便于使用的范围内的值。

③根据它们的适应度选择父辈。④当前种群中的一些个体具有较低的适应度值,它们将会被选作为“精英”传递到下一代(此为MATLAB8.x中新增的步骤)。

⑤由父辈产生子辈。子辈的产生可以通过随机改变一个单个父辈,亦即变异(mutation)来进行,也可以通过组合一对父辈的向量项,亦即交叉(crossover)来进行。

⑥用子辈替换当前种群,形成下一代。

(3)若停止准则之一得到满足,则该算法停止。

2.初始种群

遗传算法总是以产生一个随机的初始种群开始,如图8.13所示。图8.13初始种群在本例中,初始种群包含20个个体,这恰好是“Population(种群)”选项中的“Populationsize(种群尺度)”的缺省值。

注意:初始种群中的所有个体均处于图8.13中右上角的那个象限,也就是说,它们的坐标处于0和1之间,这是因为“Population”选项中的“Initialrange(初始范围)”的缺省值是[0;1]。

如果已知函数的最小点大约位于何处,就可以设置一个适当的“Initialrange”,以便使该点处于那个范围的中间附近。例如,如果确信Rastrigin函数的最小值在点[0,0]附近,那么就可以直接设置“Initialrange”为[-1;1]。然而,正如本例所显示的那样,即使没有给“Initialrange”设置一个理想的值,遗传算法也还是能够找到那个最小值的。

3.产生下一代

在每一步,遗传算法都可使用当前种群来产生子辈,即获得下一代。算法在当前种群中选择一组个体,称为父辈,这些父辈将其genes(其向量中的项)贡献给它们的子辈。遗传算法通常选择那些具有较好适应度值的个体作为父辈。我们可以在“Selection(选择)”选项的“Selectionfunction(选择函数)”文本框中指定遗传算法用来选择父辈的函数。图8.14三类子辈遗传算法可以对下一代产生三类子辈:

(1)优良子辈(Elitechildren):在当前代中具有最佳适应度值的那些个体。这些个体子辈存活到下一代。

(2)交叉子辈(Crossoverchildren):由一对父辈向量组合产生。

(3)变异子辈(Mutationchildren):由一个单个父辈引入随机改变即变异产生。

图8.14示出了这三个类型的子辈。

在8.3.3节“遗传算法举例”的“变异与交叉”部分解释如何指定遗传算法产生的每一类子辈的数目,以及用来执行完成交叉和变异的函数。

4.交叉子辈

算法通过组合当前种群中的父辈对(Pair)来产生交叉子辈。在子辈向量的每一个相同位置处,缺省的交叉函数在两个父辈之一的相同位置处随机选择一项,即基因,并将它指派给其子辈。

5.变异子辈

算法通过随机改变个体父辈中的基因而产生变异子辈。按照缺省,算法给父辈增加一个高斯分布的随机向量。

图8.15示出了初始种群的子辈,也即第二代种群,并且指出它们是否为优良子辈、交叉子辈或变异子辈。图8.15初始种群的子辈

6.后代图形绘制

图8.16示出了在迭代60次、80次、95次、100次时的种群的图形。图8.16在迭代60、80、95、100次时的种群

7.算法的停止条件

遗传算法使用下列5个条件作为停止条件:

(1)Generations(代数)——当产生的代的数目达到规定的代数的值时,算法停止。

(2)Timelimit(时限)——当运行时间的秒数等于时限时,算法停止。

(3)Fitnesslimit(适应度限)——当适应度函数的值对于当前种群的最佳点小于或等于适应度限时,算法停止。

(4)Stallgenerations(停滞代数)——在连续繁殖的时间序列中,若长时间不繁殖新代,亦即目标函数无改进,到达停滞代数规定的代数值时,则算法停止。

(5)Stalltimelimit(停滞时限)——在秒数等于停滞时限的时间间隔期间,若目标函数无改进,则算法停止。

在MATLAB8.x中,新增了下面两个条件来作为停止条件:

(1)Functiontolerance(函数容限)——指明当目标函数变化值小于函数容限时,算法停止。

(2)Nonlinearconstrainttolerance(非线性约束容限)——非线性约束容限并不作为一个终止条件,它通常用来判断是否满足非线性约束条件。

若以上7个条件中任何一个条件一旦满足,则该算法停止。我们可以在遗传算法工具的“Stoppingcriteria(停止标准)”选项中指定这些标准的值。停止标准的缺省值如图8.17所示。图8.17停止标准的缺省值当运行遗传算法时,“Status(状态)”面板将显示导致算法停止的标准。

“Timelimit(时限)”选项与“Stalltimelimit”选项是用来防止算法运行过长的时间。

如果算法满足这两个条件之一而停止,则可以通过增加“Timelimit”或“Stalltimelimit”的值来改善运行的结果。

8.3使用遗传算法工具求解问题

8.3.1使用遗传算法工具

本节将介绍使用遗传算法工具GUI来求解优化问题的一般步骤,内容包括:打开遗传算法工具、在遗传算法工具中定义问题、运行遗传算法、暂停和停止运算、图形显示、创建用户绘图函数、复现运行结果、设置选项参数、输入/输出参数和问题、从最后种群继续运行遗传算法。

1.打开遗传算法工具

在MATLAB7.x中,输入gatool,打开遗传算法工具,初启时的界面显示如图8.18(a)所示。

在MATLAB8.x版本中,输入optimtool(′ga′)初启

时的界面显示如图8.18(b)所示。或者输入optimtool,然后在Solver菜单中选择遗传算法。还可从MATLAB的APPS界面中启动工具箱,其初始化界面如图8.18(c)所示。图8.18遗传算法工具初启时的界面

2.在遗传算法工具中定义问题

在下列两个文本框中定义所要解决的问题:

(1)适应度函数——求解的问题是求目标函数的最小值。输入一个计算适应度函数的M文件函数的句柄。

(2)变量个数——适应度函数的独立变量个数。

注意:当运行遗传算法工具时不要用“Editor/Debugger(编辑/调试)”功能来调试目标函数的M文件,而要从命令行中直接调用目标函数或把M文件输入到遗传算法函数ga中。为了方便调试,可以在遗传算法工具中把问题输出到MATLAB工作窗中。

如图8.19所示,输入前面章节所介绍的Rastrigin函数或my_fun函数作为适应度函数,它们的变量个数为2。图8.19输入适应度函数与变量个数

3.运行遗传算法

若要运行遗传算法,则在“Runsolverandviewresults(运行求解器和结果显示)”栏中单击“Start”按钮,如图8.20所示。(MATLAB7.x中,为“Runsolver”栏)图8.20单击“Start”按钮[这时,在“Currentiteration(当前代)”文本框中显示当前代的数目。

通过单击“Pause”按钮可以暂停算法,同时该按钮上的文字变为“Resume(恢复)。单击“Resume”按钮,遗传算法恢复运行。

由于遗传算法的随机性,算法运行完成后运算结果可能与图8.21的显示结果不太一致。

图8.21显示了运行例子“Rastrigin函数”遗传算法停止时的信息。图8.21当前代数和状态与结果窗格图8.21中还显示了遗传算法运行时的相关信息:

(1)算法停止的原因:

Optimizationterminated:averagechangeinthefitnessvalue

lessthanoptions.TolFun.

(2)算法终止时,适应度函数的最后取值:

Objectivefunctionvalue:0.05531602101322264[HT]

注意:图8.21中所示的实际函数值已经非常接近Rastrigin函数的理想最小值0,通过设置初始范围、设置变异概率及设置最大遗传代数可以使结果更接近理想最小值。图8.21当前代数和状态与结果窗格

(1)算法停止的原因:

Optimizationterminated:averagechangeinthefitnessvalue

lessthanoptions.TolFun.

(2)算法终止时,适应度函数的最后取值:

Objectivefunctionvalue:0.05531602101322264

注意:图8.21中所示的实际函数值已经非常接近Rastrigin函数的理想最小值0,通过设置初始范围、

设置变异概率及设置最大遗传代数可以使结果更接近理想最小值。

(3)最终点的坐标,本例中最终点的坐标为[0.001

-0.017]。

在遗传算法工具中,当遗传算法运行时可以更改多个参数设置。所做的改变将被应用到下一代,即在下一代将按照新设置的参数运行。在下一代开始但尚未应用改变的参数之前,在“Statusandresults”窗格中显示信息“Changespending”。而在下一代开始且应用了改变的参数时,在“Statusandresults”窗格中显示信息“Changesapplied”。这样在遗传算法运行时更改了参数设置产生的输出信息如图8.22所示。图8.22遗传算法运行时更改了参数设置

4.暂停和停止运算

遗传算法暂停和停止运行时,可以通过下面操作继续运行:

(1)单击“Pause(暂停)”按钮,算法暂停运行。该按钮上的文字变为“Resume(恢复)”。单击“Resume”按钮,遗传算法恢复运行。

(2)单击“Stop”按钮,算法停止运行。“Statusandresults”窗口中将显示停止运行时当前代最佳点的适应度函数值。

注意:如果单击“Stop”按钮,然后再单击“Start”按钮,遗传算法将以新的随机初始种群或在“Initialpopulation(初始种群)”文本框中专门指定的种群运行。如果需要在算法停止后能再次恢复运行,则可以通过交替地单击“Pause”和“Resume”按钮来控制算法暂停或继续运行。如果想使算法一直运行到按下“Pause”或“Stop”按钮时才停下来,可以改变这些停止准则的参数值:

(1)设置“Generations(代数)”为Inf。

(2)设置“Time”为Inf。

(3)设置“Fitnesslimit”为-Inf。

(4)设置“Stallgenerations”为Inf。

(5)设置“Stalltimelimit”为Inf。

图8.23显示了停止准则参数更改后的设置。图8.23改变停止准则参数

5.图形显示

优化工具箱的绘图窗格可以不同种类的图形展示算法运行结果。通过这些图形信息可以改变参数设置来提升算法的性能。例如,要描绘算法每一代适应度函数的最优值和平均值,勾选“Bestfitness”选项即可,如图8.24所示。图8.24在绘图窗格选择输出项图8.25每一代函数最佳适应度与平均适应度图8.25中下部离散点为每一代的最佳适应度值,上部离散点为每一代的平均适应度值。图中的顶部也用数值描述了当前代的最佳适应度值和平均适应度值。

在MATLAB8.x中,为了更好地描述最佳适应度值是怎么下降的,我们可以改变图中Y轴的缩放比例为对数级缩放比例。其步骤如下:

(1)选择绘图窗口“Edit”菜单栏下的“AxesProperties”选项,即可打开属性编辑栏,如图8.26所示。图8.26属性编辑栏(2)单击“YAxis”栏。

(3)在“YScale”栏,选择“Log”选项。

重新生成的图如图8.27所示。图8.27对数刻度显示的最佳适应度值下降过程

6.创建用户绘图函数

如果工具箱中没有符合需求的绘图函数,用户可以自己编写绘图函数。这样遗传算法在每次运行时就会调用这个函数,画出所需的图形。这里举例说明怎样创建一个用户绘图函数来显示从前一代到当前代最佳适应度值的变化情形,内容包括:创建绘图函数,使用绘图函数,绘图函数如何作用。

1)创建绘图函数

在MATLAB编辑器中复制、粘贴下列代码到一个新的M文件,可以创建绘图函数。

Functionstate=gaplotchange(options,state,flag)

%绘图函数gaplotchange画出前一代个体最佳值变化的图形

persistentlast_best

%前一代个体的最佳值

if(strcmp(flag,′init′))

%绘图

set(gca,′xlim′,[1,options.Generations],′Yscale′,′log′);

holdon;

xlabelGeneration

title(′ChangeinBestFitnessValue′)

endbest=min(state.Score);%当前代个体的最佳值

ifstate.Generation==0

%设置last_best为最佳

last_best=best;

else

change=last_best-best;%改变个体的最佳值

last_best=best;

plot(state.Generation,change,′.r′);

title([′ChangeinBestFitnessValue′])

然后在MATLAB路径下将其保存为M文件gaplotchange.m。

2)使用绘图函数

在“Plots(绘图)”窗格中选择“Customfunction(定制函数)”,

并且在其右边的文本框中输入函数名@gaplotchange,就可使用绘图函数。为了对用户绘图函数输出的最佳适应度

值图形进行比较,在这里也可选择“Bestfitness”。如果运行例子函数Rastrigin,显示出来的图形如图8.28所示。图8.28用户绘图函数输出的Rastrigin函数运行结果注意:因为图8.28中下半部的Y轴为对数刻度,所以图形中的离散点仅仅显示大于零的点。对数刻度能显示适应度函数的微小变化,而上面的图形则不能显示出微小变化。

3)绘图函数如何作用

如果绘图函数使用如下结构体中的信息,那么这些信息将由遗传算法传递给绘图函数作为输入参数:

(1)options(参数):当前参数设置。

(2)state(状态):关于当前代的信息。

(3)flag(曲线标志):曲线表示为对数等的当前状态。绘图函数的主要作用描述如下:

persistentlast_best

生成永久变量last_best,即前一代的最佳值。永久变量保存着多种图形函数调用类型。

set(gca,′xlim′,[1,options.Generations],′Yscale′,′log′);

在遗传算法运行前建立图形。options.Generation为代数的最大值。

best=min(state.Score)

state.Score包含当前代中所有个体的得分值,变量best是其中最小的得分值。结构体状态文本框的完整描述可参见8.4.1节“遗传算法参数”的“图形参数”部分。

change=last_best-best

变量change是前一代的最佳值减去当前代的最佳值。

plot(state.Generation,change,′.r′)

画出当前代的变化曲线,变量维数包含在state.Generation中。

函数gaplotchange的代码包含了函数gaplotbestf代码中许多相同成分,函数gaplotbestf生成最佳适应度图形。

7.复现运行结果

为了复现遗传算法前一次的运行结果,可选择“Userandomstatesfrompreviousrun(使用前一次运行的随机状态)”复选框,这样就把遗传算法所用的随机数发生器的状态重新设置为前一次的值。如果遗传算法工具中的所有设置没有改变,那么遗传算法在下一次运行时返回的结果与前一次运行的结果一致。

正常情况下,不用选择“Userandomstatesfrompreviousrun”这个复选框,可以充分利用遗传算法随机搜索的优点,在需要分析特定的运行结果或者显示相对个体的精确结果的,再选择“Userandomstatesfrompreviousrun”复选框。图8.29选项参数窗口

8.设置选项参数

设置遗传算法的选项参数有两种方法:一种是在遗传算法工具GUI的“Options”窗格中直接进行设置,另一种是在MATLAB工作窗口中通过命令行方式进行设置。

在参数“Options”窗格中设置遗传算法的各种运行参数,如图8.29所示。每一类参数对应有一个窗格,单击该类参数时,对应窗格展开。例如,单击“Population”参数选项,种群窗格展开,可以逐一设置其中的参数项,如Populationtype(种群类型)、Populationsize(种群尺度)、Creationfunction(创建函数)、Initialpopulation、Initialscore(初始得分)、Initialrange(初始范围)等。此外,其他选项参数类还有:Fitnessscaling(适应度测量)、Selection、Reproduction、Mutation、Crossover、Migration(迁移)、Hybridfunction(混合函数)、Stoppingcriteria、Outputfunction(输出函数)、Displaytocommandwindow(显示到命令窗口)、Vectorize

(向量化)等。这些参数类各自对应一个参数窗格,单击后相应窗格随即展开,可以逐一进行参数项的设置。

所有变量参数的含义及详细描述可参见8.4.1节“遗传算法参数”。在MATLAB工作窗口中,可以将遗传算法的运行参数设置为变量。

对于数值参数的设置,可以直接在相应编辑框中输入该参数的值,或者在包含该参数值的MATLAB工作窗口中输入相应变量的名字,就可以完成设置。例如,可以利用下面两种方法之一设置“Initialpoint(初始点)”为[2.11.7]:

(1)在“Initialpoint”文本框输入[2.11.7]。

(2)在MATLAB工作区输入变量x0=[2.11.7],然后在“Initialpoint”文本框输入变量的名字x0。

因为选项参数是比较大的矩阵或向量,所以在MATLAB工作窗口中把参数的值定义为变量一般是比较方便的,也就是说,如果需要,很容易改变矩阵或向量的项。

9.输入/输出参数和问题

参数和问题结构可以从遗传算法工具中输出到MATLAB的工作窗口,也可以在以后的某个时间再反过来把它们从MATLAB的工作窗口输入给遗传算法工具。这样就可以保存对问题的当前设置,并可以随时恢复这些设置。参数结构也可以被输出到MATLAB工作窗口,并且可以再把它们用于命令行方式的遗传算法函数ga。

输入/输出信息通常包含下列各项:

(1)问题定义,包括“Fitnessfunction”和“Numberofvariables(变量个数)”。

(2)当前指定的选项参数。

(3)算法运行的结果。

1)输出参数和问题

为了输出参数和问题,单击“ExportToWorkspace(输出到工作空间)”按钮或从File菜单中选择“ExportToWorkspace”菜单项,打开如图8.30所示的对话框。图8.30输出对话框对话框提供下列参数:

(1)为了保存问题的定义和当前参数的设置,选择“ExportproblemandoptionstoaMATLAB

structurenamed(输出问题与参数到已命名的MATLAB结构)”,并为这个结构体输入一个名字。单击OK按钮,即把这个信息保存到MATLAB工作空间的一个结构体。如果以后要把这个结构体输入到遗传算法工具,那么当输出这个结构时,所设置的“Fitnessfunction”和“Numberofvariables”,以及所有的参数设置都被恢复到原来值。注意:输出问题之前,如果在“Runsolver(运行求解器)”窗格选中“Userandomstates

frompreviousrun(使用前一次运行的随机状态)”选项,则遗传算法工具将保存上一次运行开始时随机数产生函数rand和randn的状态。在选择该选项的同时输入问题且运行遗传算法,那么输出问题之前的运行结果就被准确地复现了。(2)如果要遗传算法在输出问题之前从上一次运行的最后种群恢复运行,可选择“Include

informationneededtoresumethisrun(包括所需信息以恢复本次运行)”。然后,在输入问题结构体并单击Start按钮时,算法就从前次运行的最后种群继续运行。为了恢复遗传算法产生随机初始种群的缺省行为,可删除在“Initialpopulation”字段所设置的种群。

注意:若选择了“Includeinformationneededtoresumethisrun”选项,则“Userandom

statesfrompreviousrun”选项对于输入问题和运行遗传算法时创建的初始种群将不再有任何作用。后者的选项只是指定从新的一次运行开始时再一次复现结果,而不是为了恢复算法的继续运行。(3)如果只是为了保存参数设置,可选择“ExportoptionstoaMATLABstructurenamed

(输出参数到已命名的MATLAB结构)”选项,并为这个参数结构体输入一个名字。

(4)为了保存遗传算法最近一次运行的结果,可选择“ExportresultstoaMATLABstructure

named”,并为这个结果结构体输入一个名字。

2)举例:用输出问题运行函数ga

输出一个问题(可参见8.2.3节“举例:Rastrigin函数”),在命令行运行遗传算法函数ga,其步骤如下:

(1)单击“ExportToWorkspace”按钮,打开相应对话框。(2)在“ExportToWorkspace”对话框的“ExportproblemandoptionstoaMATLAB

structurenamed”右面的文本框中,输入问题结构体的名称,假设为my_gaproblem。

(3)在MATLAB窗口中,以my_gaproblem为参数调用函数ga:

[xfval]=ga(my_gaproblem)

则返回结果:

x=

0.0027-0.0052

fval=

0.0068

调用函数ga可参见8.3.2节“从命令行使用遗传算法”。

3)输入参数

为了从MATLAB工作窗中输入一个参数结构体,可从“File”菜单选择“ImportOptions(输入参数)”菜单项。在MATLAB工作窗中打开一个对话框,列出遗传算法参数结构体的一系列选项。当选择参数结构体并单击“Import(输入)”按钮时,在遗传算法工具中的参数域就被更新,且显示所输入参数的值。创建参数结构体有两种方法:

(1)调用函数gaoptimset,以参数结构options作为输出。

(2)在遗传算法工具中,从“ExportToWorkspace(输出到工作空间)”对话框中可保存当前参数。

4)输入问题

为了从遗传算法工具输入一个以前输出的问题,可从“File”菜单选择“ImportProblem(输入问题)”菜单项。在MATLAB工作窗中,打开一个对话框,显示遗传算法问题结构体的一个列表。当选择了问题结构体并单击OK按钮时,遗传算法工具中的下列文本框被更新:

(1)适应度函数。

(2)变量个数。

(3)参数域。

10.举例:从最后种群中继续运行遗传算法

下面的例子显示如何输出一个问题,以便当输入问题并按下Start按钮时,遗传算法能从该输出问题所保存的最后种群继续运行。现在运行一个例子,在遗传算法工具中输入下面的信息:

(1)设置适应度函数为@ackleyfcn,它是计算函数Ackley,是工具箱提供的一个测试函数。

(2)设置“Numberofvariables”为10。

(3)在“Plots”窗格中选择“Bestfitness”。

(4)单击“Start”按钮。图8.31函数ackleyfcn的最佳适应度假定需要利用其他的参数运行遗传算法,接着利用当前参数设置,此后再从最后种群重新运行算法。其具体步骤如下:

(1)单击“ExportToWorkspace”按钮。

(2)在出现的对话框中:

选择“ExportproblemandoptionstoaMATLABstructurenamed:”。

在文本框中输入问题和参数的名称,例如ackley_uniform。选择“Includeinformationneededtoresumethisrun(包括所需信息以恢复本次运行)”。

选择后的对话框如图8.32所示。图8.32在输出窗口对话框中做适当选择

(3)单击“OK”按钮。

问题和参数被输出到MATLAB工作空间的一个结构体中。在MATLAB命令窗口输入下面的信息就可以观察这个结构体:

ackley_uniform

ackley_uniform=

fitnessfcn:@ackleyfcn

genomelength:10

options:[1x1struct]图8.33

GA问题输入窗口利用不同的参数设置,甚至是不同的适应度函数,在运行遗传算法之后,都能够按照如下步骤来恢复问题:

(1)从“File”菜单选择“ImportProblem”菜单项。打开的对话框如图8.33所示。

(2)选择ackley_uniform。

(3)单击“Import”按钮。

这样就把“Population”选项中的“Initialpopulation”字段设置成输出问题之前运行的最后种群。在运行期间,所有其他参数恢复它们的设置。当单击“Start”按钮时,遗传算法从

被保存的最后种群重新运行。图8.34所示为初始运行和重新运行的最佳适应度图形。图8.34初始运行和重新运行的最佳适应度

11.生成M文件

在遗传算法工具中,要利用特定的适应度函数和参数生成运行遗传算法的M文件,可从“File”菜单选择“GenerateM-File(生成M文件)”菜单项,并把生成的M文件保存到MATLAB路径的一个目录中。

在命令行调用这个M文件时,返回的结果与利用在遗传算法工具中生成M文件时的适应度函数和参数所得到的结果一致。8.3.2从命令行使用遗传算法

从命令行运行遗传算法函数ga的内容主要包括:利用缺省参

数运行ga;在命令行中设置ga的参数;使用遗传算法工具的参数和问题结构;复现运行结果;以前一次运行的最后种群重新调用函数ga;从M文件中运行ga。

1.利用缺省参数运行ga

利用缺省参数运行遗传算法,可以下面语句调用ga:

[xfval]=ga(@fitnessfun,nvars)

其中:

@fitnessfun——计算适应度函数值的M文件的函数句柄。

nvars——适应度函数中独立变量的个数。

x——返回的最终点。

fval——返回的适应度函数在x点的值。

例如,运行例子Rastrigin函数,从命令行输入MATLAB7.x语句为

[xfval]=ga(@rastriginsfcn,2)

MATLAB8.x语句为

rng(1,′twister′)%forreproducibility

[xfval]=ga(@rastriginsfcn,2)

这将返回

Optimizationterminated:

averagechangeinthefitnessvaluelessthanoptions.TolFun.

x=

0.0071

0.0220

fval=

0.1058为了得到遗传算法更多的输出结果,可以用下面语句调用ga:

[xfvalreasonoutputpopulationscores]=ga(@fitnessfcn,nvars)

除了输出变量x和fval之外,增加了以下输出变量:

(1)“exitflag(停止标识)”:算法停止的原因对应的数字代码。(该参数为MATLAB8.x版本修改后参数。)

“reason(原因)”:算法停止的原因。(该参数为MATLAB7.x版本参数。)

(2)“output(输出)”——包含关于算法在每一代性能的结构体。

(3)“population(种群)”——最后种群。

(4)“scores(得分)”——最终得分值。[xfval]=ga(@fitnessfun,nvars,options)

[xfval]=ga(@fitnessfun,nvars,[],[],[],[],[],[],[],options)

该句法并不指定任何线性等式、线性不等式或是非线性约束。使用函数gaoptimset生成一个参数结构体:

Options=gaoptimset

返回带有缺省值的参数结构体:

options=

PopulationType:′doubleVector′

PopInitRange:[2x1double]

PopulationSize:20

EliteCount:2

CrossoverFraction:0.8000

MigrationDirection:′forward′

MigrationInterval:20

MigrationFraction:0.2000

Generations:100

TimeLimit:Inf

FitnessLimit:-Inf

StallLimitG:50

StallLimitS:20

InitialPopulation:[]

InitialScores:[]

PlotInterval:1

CreationFcn:@gacreationuniform

FitnessScalingFcn:@fitscalingrank

SelectionFcn:@selectionstochunif

CrossoverFcn:@crossoverscattered

MutationFcn:@mutationgaussian

HybridFcn:[]

Display:′final′

PlotFcns:[]

OutputFcns:[]

Vectorized:′off′

UseParallel:′never′如果没有给某一参数项输入新的值,则函数ga使用其缺省值。

每一个参数的值都存放在参数结构体中,例如options.PopulationSize。可以通过输入参数的名称显示参数的值。例如,显示遗传算法种群的大小,可输入:

options.PopulationSize

ans=

20

改变参数结构体中成员值,例如,设置PopulationSize值等于100,代替它的缺省值20,可输入:

options=gaoptimset(′PopulationSize′,100)

参数结构体中,PopulationSize为100,其他值都为缺省值或当前值。

这时,再输入:MATLAB7.x语句为

ga(@fitnessfun,nvars,options)

MATLAB8.x语句为

ga(@fitnessfun,nvars,[],[],[],[],[],[],[],options)

函数ga将以种群中个体为100运行遗传算法。

如果想接着改变参数结构体其他成员的值,例如设置PlotFcns为@gaplotbestf,画出每一代

最佳适应度函数值的图形,则可用下面语句调用函数gaoptimset:

options=gaoptimset(options,′PlotFcns′,@plotbestf)这里保持了参数的所有当前值,只有PlotFcns改变为@plotbestf。注意,如果省略输入自变量参数options,那么函数gaoptimset重新将PopulationSize设置为它的缺省值20。

也可以利用一个语句来同时设置两个参数PopulationSize和PlotFcns:

options=gaoptimset(′PopulationSize′,100,′PlotFcns′,@plotbestf)

3.输入/输出参数和问题结构

利用函数gaoptimset可创建一个参数结构体,在优化算法工具中设置参数的值,然后在MATLAB工作窗中输出参数给结构体。如果想在优化算法工具中输出缺省值,则导出的结构体的参数与由命令行得到的缺省结构体的参数一致。

MATLAB7.x语句为

options=gaoptimset

MATLAB8.x语句为

options=gaoptimset(@ga)

参数“Display”在输出结构中默认为“off”,而在命令行中默认为“final”。如果想从优化算法工具输出一个问题结构体ga_problem,可用下面的语句调用函数ga:

[xfval]=ga(ga_problem)

问题结构体包含:

(1)fitnessfcn——适应度函数。

(2)nvars——问题的变量数。

(3)options——参数结构体。

(4)Aineq——不等式约束矩阵(MATLAB8.x新增参数)

(5)Bineq——不等式约束向量(MATLAB8.x新增参数)

(6)Aeq——等式约束矩阵(MATLAB8.x新增参数)

(7)Beq——等式约束向量(MATLAB8.x新增参数)

(8)LB——x的下限值(MATLAB8.x新增参数)

(9)UB——x的上限值(MATLAB8.x新增参数)

(10)nonlcon——非线性约束函数(MATLAB8.x新增参数)

4.复现运行结果

遗传算法是随机性方法,每次运行遗传算法得到的结果都

会略有不同。算法利用MATLAB8.x默认的伪随机数流(在MATLAB7.x中为随机数产生器函数rand和randn)。每一次函数ga在调用伪随机数流时,它们的状态都可能发生改变,这样在一次再被调用时,它们将返回不同的随机数。

如果需要准确复现运行结果,可以在调用函数ga时默认stream(在MATLAB7.x中为rand和randn)的当前状态。在又一次运行ga之前,重新设置这些值的状态。例如,要复现Rastrigin函数的ga的输出,可以利用下面的语句调用ga:

MATLAB7.x语句为

[xfvalreasonoutput]=ga(@rastriginsfcn,2);

假设某次运行的返回结果为

x=

0.0027-0.0052

fval=

0.0068

则随机函数rand和randn两者的状态被保存在output结构中。则随机函数rand和randn两者的状态被保存在output结构中。

Output=

randstate:[35x1double]

randnstate:[2x1double]

generations:100

funccount:2000

message:[1x64char]

然后,重新设置状态,输入:

rand(′state′,output.randstate);

randn(′state′,output.randnstate);如果现在再次运行ga,就会得到如下相同的结果:

MATLAB8.x语句为

rng(1,′twister′)%forreproducibility

[xfvalexitflagoutput]=ga(@rastriginsfcn,2);

假设某次运行的返回结果为

x,fval

x=

0.0071

0.0220

fval=

0.1058

则stream的状态被保存在“output.rngstate”中。Output=

problemtype:′unconstrained′

rngstate:[1x1struct]

generations:55

funccount:1120

message:[1x86char]然后,重新设置状态,输入:

stream=RandStream.getGlobalStream;

stream.State=output.rngstate.state;如果现在再次运行ga,就会得到如下相同的结果:

[xfvalexitflagoutput]=ga(@rastriginsfcn,2)

Optimizationterminated:averagechangeinthefitnessvaluelessthanoptions.TolFun.

x=

0.0071

0.0220

fval=

0.1058

exitflag=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论