人工智能实验报告

人工智能第二次实验报告

一.实验题目:

遗传算法的设计与实现

二.实验目的:

通过人工智能课程的学习,熟悉遗传算法的简单应用。

三.实验内容

用遗传算法求解f (x) = x2 的最大值,x∈

[0,31],x取整数。

可以看出该函数比较简单,只要是为了体现遗传算法的思想,在问题选择上,选了一个比较容易实现的,把主要精力放在遗传算法的实现,以及核心思想体会上。

四. 实验过程:

1. 实现过程

(1)编码

使用二进制编码,随机产生一个初始种群。L 表示编码长度,通常由对问题的求解精度决定,编码长度L 越长,可期望的最优解的精度也就越高,过大的L 会增大运算量。针对该问题进行了简化,因为题设中x∈ [0,31],所以将二进制长度定为5就够用了;

(2)生成初始群体

种群规模表示每一代种群中所含个体数目。随机产生N个初始串结构数据,每个串结构数据成为一个个体,N个个体组成一个初始群体,N表示种群规模的大小。当N取值较小时,可提高遗传算法的运算速度,但却降低种群的多样性,容易引起遗传算法早熟,出现假收敛;而N当取值较大时,又会使得遗传算法效率降低。一般建议的取值范围是20—100。

(3)适应度检测

根据实际标准计算个体的适应度,评判个体的优劣,即该个体所代表的可行解的优劣。本例中适应度即为所求的目标函数;

(4)选择

从当前群体中选择优良(适应度高的)个体,使它们有机会被选中进入下一次迭代过程,舍弃适应度低的个体。本例中采用轮盘赌的选择方法,即个体被选择的几率与其适应度值大小成正比;

(5)交叉

遗传操作,根据设置的交叉概率对交配池中个体进行基因交叉操作,形成新一代的种群,新一代中间个体的信息来自父辈个体,体现了信息交换的原则。交叉概率控制着交叉操作的频率,由于交叉操作是遗传算法中产生新个体的主要方法,所以交叉概率通常应取较大值;但若过大的话,又可能破坏群体的优良模式。一般取0.4到0.99。

(6)变异

随机选择中间群体中的某个个体,以变异概率大小改变个体某位基因的值。变异为产生新个体提供了机会。变异概率也是影响新个体产生的一个因素,变异概率小,产生新个体少;变异概率太大,又会使遗传算法变成随机搜索。一般取变异概率为0.0001—0.1。

(7)结束条件

当得到的解大于等于900时,结束。从而观看遗传的效率问题。

五. 代码及结果:

/*遗传算法设计最大值*/

#include

#include

#include

#include

#define C 0 //测试

#define CFLAG 4 //测试标记

#define JIAOCHA_RATE 0.5 //交叉概率一般取0.4到0.99

#define BIANYI_RATE 0.09 //变异概率为0.0001-0.1

#define ITER_NUM 1000 //迭代次数

#define POP_NUM 20 //染色体个数

#define GENE_NUM 5 //基因位数

#define FEXP(x) ((x)*(x)) //y=x^2

typedef unsigned int UINT;

//染色体

typedef struct{

char geneBit[GENE_NUM]; //基因位

UINT fitValue; //适应值

}Chromosome;

//将二进制的基因位转化为十进制

UINT toDec(Chromosome pop){

UINT i;

UINT radix = 1;

UINT result = 0;

for(i=0; i

{

result += (pop.geneBit[i]-'0')*radix;

radix *= 2;

}

return result;

}

UINT calcFitValue(UINT x) {

return FEXP(x);

void test(Chromosome *pop) {

int i;

int j;

for(i=0; i

{

printf("%d: ", i+1);

for(j=0; j

printf("%c", pop[i].geneBit[j]);

printf(" %4d", toDec(pop[i]));

printf(" fixValue=%d\n", calcFitValue(toDec(pop[i])));

}

}

//变异得到新个体:随机改变基因

void mutation(Chromosome *pop) {

UINT randRow, randCol;

UINT randValue;

randValue=rand()%100;

if(randValue >= (int)(BIANYI_RATE*100))

{

#if (C==1) && (CFLAG==4)

#endif

return ;

}

randCol = rand()%GENE_NUM; // 随机产生将要变异的基因位

randRow = rand()%POP_NUM; // 随机产生将要变异的染色体位 #if (C==1) && (CFLAG==4)

printf("\n变异前\n");

test(pop);

printf("\n变异的位置为:染色体号=%d 基因位号=%d\n", randRow+1, randCol); #endif

pop[randRow].geneBit[randCol] = (pop[randRow].geneBit[randCol]=='0') ? '1':'0'; //1变为0, 0变为1

pop[randRow].fitValue = calcFitValue( toDec(pop[randRow]) );

#if (C==1) && (CFLAG==4)

printf("\n变异后\n");

test(pop);

#endif

}

//创建初始群体

void createPop(Chromosome *pop){

UINT i,j;

UINT randValue;

UINT value;

srand((unsigned)time(NULL));

for(i=0; i

{

for(j=0; j

{

randValue = rand()%2;

pop[i].geneBit[j] = randValue+'0'; // 将随机数0或1赋给基因

}

value= toDec(pop[i]);

pop[i].fitValue = calcFitValue(value);

}

#if (C==1) && (CFLAG==1)

printf("\n随机分配的种群如下:\n");

test(pop);

#endif

}

//更新种群

void updatePop(Chromosome *newPop, Chromosome *oldPop){

UINT i;

for(i=0; i

oldPop[i]=newPop[i];

}

}

//选择优良个体:根据适应度选择最优解,即最优个体

void select(Chromosome *pop){

UINT i,j;

UINT sumFitValue; //总适应值

UINT aFitValue; //平均适应值

float choice[POP_NUM]; //选择

Chromosome tempPop; //交换变量

#if (C==1) && (CFLAG==2) //测试

printf("\n没有选择前的种群如下:\n");

test(pop);

#endif

// 根据个体适应度冒泡降序排序

for(i=POP_NUM; i>0; i--)

{

for(j=0; j

{

if(pop[j+1].fitValue > pop[j].fitValue)

{

tempPop = pop[j+1];

pop[j+1] = pop[j];

pop[j] = tempPop;

}

}

}

//计算总适应值

sumFitValue = 0;

for(i=0; i

{

sumFitValue += pop[i].fitValue;

}

aFitValue = (UINT)(((float)sumFitValue/POP_NUM)+0.5); //计算平均适应值 //计算出每个群体选择机会,群体的概率=群体适应值/总适应值,平均概率= 平均适应值/总适应值,群体选择机会 = (群体的概率/平均概率)

for(i=0; i

{

choice[i] = ((float)pop[i].fitValue/sumFitValue)/((float)aFitValue/sumFitValue); choice[i] = (float)((int)(choice[i]*100+0.5)/100.0);//保留到小数点后2位 }

//根据选择概率来繁殖优良个体,并淘汰较差个体

for(i=0; i

{

if(((int)(choice[i]+0.55)) == 0) //如果choice[i]==0淘汰繁殖一次最优的群体 pop[POP_NUM-1] = pop[0];

}

#if (C==1) && (CFLAG==2)

printf("\n经过选择以后的种群:\n");

test(pop);

#endif

}

//交叉:基因交换

void cross(Chromosome *pop) {

char tmpStr[GENE_NUM]="";

UINT i;

UINT randPos;

UINT randValue;

randValue=rand()%100;

if(randValue >= (int)(JIAOCHA_RATE*100)) {

#if (C==1) && (CFLAG==3)

printf("\n种群没有进行交叉.\n");

#endif

return ; }

#if (C==1) && (CFLAG==3)

printf("\n交叉前,种群如下:\n");

test(pop);

printf("\n交叉的位置依次为:");

#endif

//染色体两两交叉

for(i=0; i

randPos = (rand()%(GENE_NUM-1)+1); // 产生随机交叉点,范围是1到GENE_NUM-1

strncpy(tmpStr, pop[i].geneBit+randPos, GENE_NUM-randPos);

strncpy(pop[i].geneBit+randPos,

GENE_NUM-randPos);

strncpy(pop[i+1].geneBit+randPos, tmpStr, GENE_NUM-randPos); #if (C==1) && (CFLAG==3)

printf(" %d", randPos);

#endif

}

// 对个体计算适应度

for(i=0; i

pop[i].fitValue = calcFitValue(toDec(pop[i]) );

}

#if (C==1) && (CFLAG==3)

printf("\n交叉后,种群如下:\n");

test(pop); pop[i+1].geneBit+randPos,

#endif

}

//输出结果

void result(Chromosome *pop){

UINT i;

UINT x = 0;

UINT maxValue = 0; // 函数的最大值

for(i=0; i

{

if(pop[i].fitValue > maxValue) {

maxValue = pop[i].fitValue;

x = toDec(pop[i]);

}

}

printf("\n当x=%d时,函数得到最大值为:%d\n\n", x, maxValue);

}

int main(int argc, char *argv[]){

int count; //迭代次数

Chromosome curPop[POP_NUM]; //初始种群或者当前总群

Chromosome nextPop[POP_NUM]; //变异后种群

createPop(curPop);

for(count=1; count

updatePop(curPop, nextPop); // 更新种群

select(nextPop); //选择

cross(nextPop); //交叉

mutation(nextPop); //变异

updatePop(nextPop, curPop); //更新

printf("\n第%d次迭代:\n", count);

test(curPop);

}

result(curPop);

return 0;

}

实验结果:

实验小结:

经过本次实验对遗传算法有了深刻的了解,充分体会到遗传算法对优缺点 ,了解了演化算法的基本思想,虽然过程中出现了很多小问题,比如大小写什么的还有就是逻辑错误,但是最终在理解的基础上成功实现了功能,认真分析后,提高了解决问题的能力。

人工智能第二次实验报告

一.实验题目:

遗传算法的设计与实现

二.实验目的:

通过人工智能课程的学习,熟悉遗传算法的简单应用。

三.实验内容

用遗传算法求解f (x) = x2 的最大值,x∈

[0,31],x取整数。

可以看出该函数比较简单,只要是为了体现遗传算法的思想,在问题选择上,选了一个比较容易实现的,把主要精力放在遗传算法的实现,以及核心思想体会上。

四. 实验过程:

1. 实现过程

(1)编码

使用二进制编码,随机产生一个初始种群。L 表示编码长度,通常由对问题的求解精度决定,编码长度L 越长,可期望的最优解的精度也就越高,过大的L 会增大运算量。针对该问题进行了简化,因为题设中x∈ [0,31],所以将二进制长度定为5就够用了;

(2)生成初始群体

种群规模表示每一代种群中所含个体数目。随机产生N个初始串结构数据,每个串结构数据成为一个个体,N个个体组成一个初始群体,N表示种群规模的大小。当N取值较小时,可提高遗传算法的运算速度,但却降低种群的多样性,容易引起遗传算法早熟,出现假收敛;而N当取值较大时,又会使得遗传算法效率降低。一般建议的取值范围是20—100。

(3)适应度检测

根据实际标准计算个体的适应度,评判个体的优劣,即该个体所代表的可行解的优劣。本例中适应度即为所求的目标函数;

(4)选择

从当前群体中选择优良(适应度高的)个体,使它们有机会被选中进入下一次迭代过程,舍弃适应度低的个体。本例中采用轮盘赌的选择方法,即个体被选择的几率与其适应度值大小成正比;

(5)交叉

遗传操作,根据设置的交叉概率对交配池中个体进行基因交叉操作,形成新一代的种群,新一代中间个体的信息来自父辈个体,体现了信息交换的原则。交叉概率控制着交叉操作的频率,由于交叉操作是遗传算法中产生新个体的主要方法,所以交叉概率通常应取较大值;但若过大的话,又可能破坏群体的优良模式。一般取0.4到0.99。

(6)变异

随机选择中间群体中的某个个体,以变异概率大小改变个体某位基因的值。变异为产生新个体提供了机会。变异概率也是影响新个体产生的一个因素,变异概率小,产生新个体少;变异概率太大,又会使遗传算法变成随机搜索。一般取变异概率为0.0001—0.1。

(7)结束条件

当得到的解大于等于900时,结束。从而观看遗传的效率问题。

五. 代码及结果:

/*遗传算法设计最大值*/

#include

#include

#include

#include

#define C 0 //测试

#define CFLAG 4 //测试标记

#define JIAOCHA_RATE 0.5 //交叉概率一般取0.4到0.99

#define BIANYI_RATE 0.09 //变异概率为0.0001-0.1

#define ITER_NUM 1000 //迭代次数

#define POP_NUM 20 //染色体个数

#define GENE_NUM 5 //基因位数

#define FEXP(x) ((x)*(x)) //y=x^2

typedef unsigned int UINT;

//染色体

typedef struct{

char geneBit[GENE_NUM]; //基因位

UINT fitValue; //适应值

}Chromosome;

//将二进制的基因位转化为十进制

UINT toDec(Chromosome pop){

UINT i;

UINT radix = 1;

UINT result = 0;

for(i=0; i

{

result += (pop.geneBit[i]-'0')*radix;

radix *= 2;

}

return result;

}

UINT calcFitValue(UINT x) {

return FEXP(x);

void test(Chromosome *pop) {

int i;

int j;

for(i=0; i

{

printf("%d: ", i+1);

for(j=0; j

printf("%c", pop[i].geneBit[j]);

printf(" %4d", toDec(pop[i]));

printf(" fixValue=%d\n", calcFitValue(toDec(pop[i])));

}

}

//变异得到新个体:随机改变基因

void mutation(Chromosome *pop) {

UINT randRow, randCol;

UINT randValue;

randValue=rand()%100;

if(randValue >= (int)(BIANYI_RATE*100))

{

#if (C==1) && (CFLAG==4)

#endif

return ;

}

randCol = rand()%GENE_NUM; // 随机产生将要变异的基因位

randRow = rand()%POP_NUM; // 随机产生将要变异的染色体位 #if (C==1) && (CFLAG==4)

printf("\n变异前\n");

test(pop);

printf("\n变异的位置为:染色体号=%d 基因位号=%d\n", randRow+1, randCol); #endif

pop[randRow].geneBit[randCol] = (pop[randRow].geneBit[randCol]=='0') ? '1':'0'; //1变为0, 0变为1

pop[randRow].fitValue = calcFitValue( toDec(pop[randRow]) );

#if (C==1) && (CFLAG==4)

printf("\n变异后\n");

test(pop);

#endif

}

//创建初始群体

void createPop(Chromosome *pop){

UINT i,j;

UINT randValue;

UINT value;

srand((unsigned)time(NULL));

for(i=0; i

{

for(j=0; j

{

randValue = rand()%2;

pop[i].geneBit[j] = randValue+'0'; // 将随机数0或1赋给基因

}

value= toDec(pop[i]);

pop[i].fitValue = calcFitValue(value);

}

#if (C==1) && (CFLAG==1)

printf("\n随机分配的种群如下:\n");

test(pop);

#endif

}

//更新种群

void updatePop(Chromosome *newPop, Chromosome *oldPop){

UINT i;

for(i=0; i

oldPop[i]=newPop[i];

}

}

//选择优良个体:根据适应度选择最优解,即最优个体

void select(Chromosome *pop){

UINT i,j;

UINT sumFitValue; //总适应值

UINT aFitValue; //平均适应值

float choice[POP_NUM]; //选择

Chromosome tempPop; //交换变量

#if (C==1) && (CFLAG==2) //测试

printf("\n没有选择前的种群如下:\n");

test(pop);

#endif

// 根据个体适应度冒泡降序排序

for(i=POP_NUM; i>0; i--)

{

for(j=0; j

{

if(pop[j+1].fitValue > pop[j].fitValue)

{

tempPop = pop[j+1];

pop[j+1] = pop[j];

pop[j] = tempPop;

}

}

}

//计算总适应值

sumFitValue = 0;

for(i=0; i

{

sumFitValue += pop[i].fitValue;

}

aFitValue = (UINT)(((float)sumFitValue/POP_NUM)+0.5); //计算平均适应值 //计算出每个群体选择机会,群体的概率=群体适应值/总适应值,平均概率= 平均适应值/总适应值,群体选择机会 = (群体的概率/平均概率)

for(i=0; i

{

choice[i] = ((float)pop[i].fitValue/sumFitValue)/((float)aFitValue/sumFitValue); choice[i] = (float)((int)(choice[i]*100+0.5)/100.0);//保留到小数点后2位 }

//根据选择概率来繁殖优良个体,并淘汰较差个体

for(i=0; i

{

if(((int)(choice[i]+0.55)) == 0) //如果choice[i]==0淘汰繁殖一次最优的群体 pop[POP_NUM-1] = pop[0];

}

#if (C==1) && (CFLAG==2)

printf("\n经过选择以后的种群:\n");

test(pop);

#endif

}

//交叉:基因交换

void cross(Chromosome *pop) {

char tmpStr[GENE_NUM]="";

UINT i;

UINT randPos;

UINT randValue;

randValue=rand()%100;

if(randValue >= (int)(JIAOCHA_RATE*100)) {

#if (C==1) && (CFLAG==3)

printf("\n种群没有进行交叉.\n");

#endif

return ; }

#if (C==1) && (CFLAG==3)

printf("\n交叉前,种群如下:\n");

test(pop);

printf("\n交叉的位置依次为:");

#endif

//染色体两两交叉

for(i=0; i

randPos = (rand()%(GENE_NUM-1)+1); // 产生随机交叉点,范围是1到GENE_NUM-1

strncpy(tmpStr, pop[i].geneBit+randPos, GENE_NUM-randPos);

strncpy(pop[i].geneBit+randPos,

GENE_NUM-randPos);

strncpy(pop[i+1].geneBit+randPos, tmpStr, GENE_NUM-randPos); #if (C==1) && (CFLAG==3)

printf(" %d", randPos);

#endif

}

// 对个体计算适应度

for(i=0; i

pop[i].fitValue = calcFitValue(toDec(pop[i]) );

}

#if (C==1) && (CFLAG==3)

printf("\n交叉后,种群如下:\n");

test(pop); pop[i+1].geneBit+randPos,

#endif

}

//输出结果

void result(Chromosome *pop){

UINT i;

UINT x = 0;

UINT maxValue = 0; // 函数的最大值

for(i=0; i

{

if(pop[i].fitValue > maxValue) {

maxValue = pop[i].fitValue;

x = toDec(pop[i]);

}

}

printf("\n当x=%d时,函数得到最大值为:%d\n\n", x, maxValue);

}

int main(int argc, char *argv[]){

int count; //迭代次数

Chromosome curPop[POP_NUM]; //初始种群或者当前总群

Chromosome nextPop[POP_NUM]; //变异后种群

createPop(curPop);

for(count=1; count

updatePop(curPop, nextPop); // 更新种群

select(nextPop); //选择

cross(nextPop); //交叉

mutation(nextPop); //变异

updatePop(nextPop, curPop); //更新

printf("\n第%d次迭代:\n", count);

test(curPop);

}

result(curPop);

return 0;

}

实验结果:

实验小结:

经过本次实验对遗传算法有了深刻的了解,充分体会到遗传算法对优缺点 ,了解了演化算法的基本思想,虽然过程中出现了很多小问题,比如大小写什么的还有就是逻辑错误,但是最终在理解的基础上成功实现了功能,认真分析后,提高了解决问题的能力。


相关内容

  • 智能家居报告
  • 东莞理工学院城市学院 实验报告 实验1 智慧家居系统需求分析 实验课时 课内:2课时:课外:2课时 实验类型 验证性实验 实验目的和要求 1. 目的:通过本次实验,训练学生撰写"物联网工程需求分析说明书"的能力. 2. 要求:要求每位同学上交一份完整的<智慧家居系统需求分析 ...

  • "特殊家庭学生情感优势智能开发的研究"实验研究开题报告
  • 一 .课题的提出 关于特殊家庭学生情感优势智能的开发,在国内外曾有专家学者进行过探索研究,已取得较好的成效.1983年,美国哈佛大学心理学教授霍华德·加德纳博士提出"多元智能理论",引起了教育学界.心理学界的关注乃至名扬全球.20世纪90年代,在北京.上海.山东等地相继开展了这方 ...

  • 人工智能第三章井字棋实验报告
  • 实验报告 计算机科学学院工业中心204 实验室 二〇一六年六月二十三日 1.总体要求: 1.1总体功能要求: 利用不同的方法,实现人机对战过程中呈现出不同程度的智能特征: (1) 利用极大极小算法.α-β剪枝来提高算法的效率. (2) 使用高级语言,编写一个智能井字棋游戏. (3) 结合极大极小算法 ...

  • 人工智能实验报告八数码难题
  • 昆明理工大学信息工程与自动化学院学生实验报告 ( 201 - 201 学年 第 一 学期 ) 课程名称: 开课实验室: 年 月 日 一.实验内容 八数码难题,问题描述:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的 八张牌,初始状态S0,目标状态S1如图所示,可以使用的操作有 ...

  • 图解新教材:人教实验B版.高中数学.2:必修
  • 基本资料 图解新教材:人教实验B版.高中数学.2:必修 作者: 钟山主编 出版社: 出版年: 2009.09 页数: 定价: CNY18.80 装帧: ISAN: 书  目: 举报失效目录 超星 第一章 立体几何初步 1.1 空间几何体 1.1.1 构成空间几何体的基本元素 知识方法能力图解 多元智 ...

  • 我国智能科学技术教育的现状与思考
  • "卜-i而蒜重羹蠢l 文章编号:1672.5913(2009)11-0010-05 王万森1,钟义信2 韩力群3,刘 一 岩1 ・・・ 我国智能科学技术教育的现状与思考 宏4,王志良5,彭 (1.首都师范大学信息工程学院,北京100048:2.北京邮电大学计算机学院,北京100876:3. ...

  • 工业生产过程控制实验报告
  • 南昌大学实验报告 学生姓名: 费梦娟 学号: 专业班级: 自动化102班 实验类型:□ 验证 □ 综合 □ 设计 □ 创新 实验日期: 实验成绩: 实验一 单容自衡水箱液位特性测试实验 一.实验目的 1.掌握单容水箱的阶跃响应测试方法,并记录相应液位的响应曲线: 2.根据实验得到的液位阶跃响应曲线, ...

  • 农业机械化工程
  • 吉林大学"十五""211工程"重点学科建设项目论证报告 农业机械化工程 一.项目定义 项目名称:农业机械化工程 项目所属领域:农学 涉及的主要学科:农业机械化工程(国家重点学科).农业 生物环境与能源工程.农业经济管理.农产品加工及储 藏工程.食品科学 项目主 ...

  • 小学语文课堂教学生活化研究小课题结题报告
  • "小学语文课堂教学生活化研究"小课题结题报告 一.课题的提出 提出<小学语文课堂教学生活化研究>这一课题,基于以下几个方面思考: 1.语言来源于生活,在生活中学语文,这是"大语文教学观"的需要.美国教育家华特指出:"语言的外延与生活的外延 ...