声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2489|回复: 13

[人工智能] 遗传算法解非线性方程组

[复制链接]
发表于 2007-7-3 22:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
下边是用遗传算法解非线性方程组的程序。
程序用MATLAB语言编写。之所以选择MATLB,是因为它简单,但又功能强大。写1行MATLAB程序,相当于写10行C++程序。在编写算法阶段,最好用MATLAB语言,算法验证以后,要进入工程阶段,再把它翻译成C++语言。
本程序的算法很简单,只具有示意性,不能用于实战。
非线性方程组的实例在函数(2)nonLinearSumError1(x)中,你可以用这个实例做样子构造你自己待解的非线性方程组。
%注意:标准遗传算法的一个重要概念是,染色体是可能解的2进制顺序号,由这个序号在可能解的集合(解空间)中找到可能解

%程序的流程如下:
%程序初始化,随机生成一组可能解(第一批染色体)
%1: 由可能解的序号寻找解本身(关键步骤)
%2:把解代入非线性方程计算误差,如果误差符合要求,停止计算
%3:选择最好解对应的最优染色体
%4:保留每次迭代产生的最好的染色体,以防最好染色体丢失
%5: 把保留的最好的染色体holdBestChromosome加入到染色体群中
%6: 为每一条染色体(即可能解的序号)定义一个概率(关键步骤)
%7:按照概率筛选染色体(关键步骤)
%8:染色体杂交(关键步骤)
%9:变异
%10:到1

  1. %这是遗传算法的主程序,它需要调用的函数如下。
  2. %由染色体(可能解的2进制)顺序号找到可能解:
  3. %(1)x=chromosome_x(fatherChromosomeGroup,oneDimensionSet,solutionSum);
  4. %把解代入非线性方程组计算误差函数:(2)functionError=nonLinearSumError1(x);
  5. %判定程是否得解函数:(3)[solution,isTrue]=isSolution(x,funtionError,solutionSumError);
  6. %选择最优染色体函数:
  7. %(4)[bestChromosome,leastFunctionError]=best_worstChromosome(fatherChromosomeGroup,functionError);
  8. %误差比较函数:从两个染色体中,选出误差较小的染色体
  9. %(5)[holdBestChromosome,holdLeastFunctionError]...
  10. % =compareBestChromosome(holdBestChromosome,holdLeastFunctionError,...
  11. % bestChromosome,leastFuntionError)
  12. %为染色体定义概率函数,好的染色体概率高,坏染色体概率低
  13. %(6)p=chromosomeProbability(functionError);
  14. %按概率选择染色体函数:
  15. %(7)slecteChromosomeGroup=selecteChromome(fatherChromosomeGroup,p);
  16. %父代染色体杂交产生子代染色体函数
  17. %(8)sonChrmosomeGroup=crossChromosome(slecteChromosomeGroup,2);
  18. %防止染色体超出解空间的函数
  19. %(9)chromosomeGroup=checkSequence(chromosomeGroup,solutionSum)
  20. %变异函数
  21. %(10)fatherChromosomeGroup=varianceCh(sonChromosomeGroup,0.8,solutionN);
  22. %通过实验有如下结果:
  23. %1。染色体应当多一些
  24. %2。通过概率选择染色体,在迭代早期会有效选出优秀的染色体,使解的误差迅速降低,
  25. %但随着迭代的进行,概率选择也会导致某种染色体在基因池中迅速增加,使染色体趋同,
  26. %这就减少了物种的多样性,反而难以逼近解
  27. %3。不用概率选择,仅采用染色体杂交,采用保留优秀染色体,也可以得到解

  28. %%%%%%%%%%%%%%%%%%%%%%%%程序开始运行

  29. clear,clc;%清理内存,清屏
  30. circleN=200;%迭代次数
  31. format long

  32. %%%%%%%%%%%%%%%构造可能解的空间,确定染色体的个数、长度
  33. solutionSum=4;leftBoundary=-10;rightBoundary=10;
  34. distance=1;chromosomeSum=500;solutionSumError=0.1;
  35. %solutionSum:非线性方程组的元数(待解变量的个数);leftBoundary:可能解的左边界;
  36. %rightBoundary:可能解的右边界;distance:可能解的间隔,也是解的精度
  37. %chromosomeSum:染色体的个数;solveSumError:解的误差
  38. oneDimensionSet=leftBoundary:distance:rightBoundary;
  39. %oneDimensionSet:可能解在一个数轴(维)上的集合
  40. oneDimensionSetN=size(oneDimensionSet,2);%返回oneDimensionSet中的元素个数
  41. solutionN=oneDimensionSetN^solutionSum;%解空间(解集合)中可能解的总数
  42. binSolutionN=dec2bin(solutionN);%把可能解的总数转换成二进制数
  43. chromosomeLength=size(binSolutionN,2);%由解空间中可能解的总数(二进制数)计算染色体的长度

  44. %%%%%%%%%%%%%%%%程序初始化
  45. %随机生成初始可能解的顺序号,+1是为了防止出现0顺序号
  46. solutionSequence=fix(rand(chromosomeSum,1)*solutionN)+1;
  47. for i=1:chromosomeSum%防止解的顺序号超出解的个数
  48. if solutionSequence(i)>solutionN;
  49. solutionSequence(i)=solutionN;
  50. end
  51. end
  52. %染色体是解集合中的序号,它对应一个可能解
  53. %把解的十进制序号转成二进制序号
  54. fatherChromosomeGroup=dec2bin(solutionSequence,chromosomeLength);
  55. holdLeastFunctionError=Inf;%可能解的最小误差的初值
  56. holdBestChromosome=0;%对应最小误差的染色体的初值

  57. %%%%%%%%%%%%%%%%%%开始计算
  58. circle=0;
  59. while circle<circleN%开始迭代求解
  60. circle=circle+1;%记录迭代次数
  61. %%%%%%%%%%%%%1:由可能解的序号寻找解本身(关键步骤)
  62. x=chromosome_x(fatherChromosomeGroup,oneDimensionSet,solutionSum);
  63. %%%%%%%%%%%%%2:把解代入非线性方程计算误差
  64. functionError=nonLinearSumError1(x);%把解代入方程计算误差
  65. [solution,minError,isTrue]=isSolution(x,functionError,solutionSumError);
  66. %isSolution函数根据误差functionError判定方程是否已经解开,isTrue=1,方程得解。solution是方程的解
  67. if isTrue==1
  68. '方程得解'
  69. solution
  70. minError
  71. circle
  72. return%结束程序
  73. end
  74. %%%%%%%%%%%%%3:选择最好解对应的最优染色体
  75. [bestChromosome,leastFunctionError]=best_worstChromosome(fatherChromosomeGroup,functionError);
  76. %%%%%%%%%%%%%4:保留每次迭代产生的最好的染色体
  77. %本次最好解与上次最好解进行比较,如果上次最好解优于本次最好解,保留上次最好解;
  78. %反之,保留本次最好解。保留的最好染色体放在holdBestChromosome中
  79. [holdBestChromosome,holdLeastFunctionError]...
  80. =compareBestChromosome(holdBestChromosome,holdLeastFunctionError,...
  81. bestChromosome,leastFunctionError);
  82. %circle
  83. %minError
  84. %solution
  85. %holdLeastFunctionError

  86. %%%%%%%%%%%%%%5:把保留的最好的染色体holdBestChromosome加入到染色体群中
  87. order=round(rand(1)*chromosomeSum);
  88. if order==0
  89. order=1;
  90. end
  91. fatherChromosomeGroup(order,:)=holdBestChromosome;
  92. functionError(order)=holdLeastFunctionError;

  93. %%%%%%%%%%%%%%%6:为每一条染色体(即可能解的序号)定义一个概率(关键步骤)
  94. %%%%%%%%%%%%%%%好的染色体概率高,坏的概率低。依据误差functionError计算概率
  95. [p,trueP]=chromosomeProbability(functionError);
  96. if trueP =='Fail'
  97. '可能解严重不适应方程,请重新开始'
  98. return%结束程序
  99. end
  100. %%%%%%%%%%%%%%%7:按照概率筛选染色体(关键步骤)
  101. %fa=bin2dec(fatherChromosomeGroup)%显示父染色体
  102. %从父染体中选择优秀染色体
  103. %selecteChromosomeGroup=selecteChromosome(fatherChromosomeGroup,p);
  104. %%%%%%%%%%%%%%%8:染色体杂交(关键步骤)
  105. %sle=bin2dec(selecteChromosomeGroup)%显示选择出来的解的序号(染色体)
  106. %用概率筛选出的染色体selecteChromosomeGroup进行杂交,产生子代染色体
  107. %sonChromosomeGroup=crossChromosome(selecteChromosomeGroup,2);
  108. %不用概率筛选出的染色体selecteChromosomeGroup进行杂交,而直接用上一代(父代)的
  109. sonChromosomeGroup=crossChromosome(fatherChromosomeGroup,2);
  110. %cro=bin2dec(sonChromosomeGroup)%显示杂交后的子代染色体
  111. sonChromosomeGroup=checkSequence(sonChromosomeGroup,solutionN);%检查杂交后的染色体是否越界
  112. %%%%%%%%%%%%%%%9:变异
  113. %不杂交直接变异
  114. %fatherChromosomeGroup=varianceCh(fatherChromosomeGroup,0.1,solutionN);
  115. %杂交后变异
  116. fatherChromosomeGroup=varianceCh(sonChromosomeGroup,0.1,solutionN);
  117. fatherChromosomeGroup=checkSequence(fatherChromosomeGroup,solutionN);%检查变异后的染色体是否越界
  118. end
复制代码

评分

1

查看全部评分

回复
分享到:

使用道具 举报

 楼主| 发表于 2007-7-3 22:22 | 显示全部楼层
函数(1):由染色体(可能解的2进制)顺序号找到可能解
  1. %这个函数找出染色体(可能解的序号)对应的可能解x
  2. function x=chromosome_x(chromosomeGroup,oneDimensionSet,solutionSum)
  3. %chromosomeGroup:染色体,也是可能解的二进制序号
  4. %oneDimensionSet:一维数轴上的可能解
  5. %solutionSum:非线性方程组的元数,也就是待解方程中未知变量的个数
  6. [row oneDimensionSetN]=size(oneDimensionSet);
  7. %oneDimensionSetN:一维数轴上可能解的个数
  8. chromosomeSum=size(chromosomeGroup);%chromosomeSum:染色体的个数
  9. xSequence=bin2dec(chromosomeGroup);%把可能解的二进制序号(染色体)转换成十进制序号
  10. for i=1:chromosomeSum%i:染色体的编号
  11. remainder=xSequence(i);
  12. for j=1:solutionSum
  13. dProduct=oneDimensionSetN^(solutionSum-j);%sNproduct:
  14. quotient=remainder/dProduct;
  15. remainder=mod(remainder,dProduct);%mod:取余函数
  16. if remainder==0
  17. oneDimensionSetOrder=quotient;
  18. %oneDimensionSetOrder:可能解在数轴上的序号
  19. else
  20. oneDimensionSetOrder=fix(quotient)+1;%fix:取整函数
  21. end
  22. if oneDimensionSetOrder==0
  23. oneDimensionSetOrder=oneDimensionSetN;
  24. end
  25. x(i,j)=oneDimensionSet(oneDimensionSetOrder);
  26. end
  27. end
复制代码
 楼主| 发表于 2007-7-3 22:22 | 显示全部楼层
函数(2):把解代入非线性方程组计算绝对误差函数:
  1. function funtionError=nonLinearSumError1(X)%方程的解是-7,5,1,-3
  2. funtionError=...
  3. [
  4. abs(X(:,1).^2-sin(X(:,2).^3)+X(:,3).^2-exp(X(:,4))-50.566253390821)+...
  5. abs(X(:,1).^3+X(:,2).^2-X(:,4).^2+327)+...
  6. abs(cos(X(:,1).^4)+X(:,2).^4-X(:,3).^3-624.679868769613)+...
  7. abs(X(:,1).^4-X(:,2).^3+2.^X(:,3)-X(:,4).^4-2197)
  8. ];
复制代码
 楼主| 发表于 2007-7-3 22:22 | 显示全部楼层
函数(3):判定程是否得解函数:
  1. %判断方程是否解开
  2. function [solution,minError,isTrue]=isSolution(x,functionError,precision)
  3. [minError,xi]=min(functionError);%找到最小误差,最小误差所对应的行号
  4. solution=x(xi,:);
  5. if minError<precision
  6. isTrue=1;
  7. else
  8. isTrue=0;
  9. end
复制代码
 楼主| 发表于 2007-7-3 22:23 | 显示全部楼层
%函数(4):选择最优染色体函数:
%找出最小误差所对应的最好染色体,最大误差所对应的最坏染色体
  1. function [bestChromosome,leastFunctionError]=best_worstChromosome(chromosomeGroup,functionError)
  2. [leastFunctionError minErrorOrder]=min(functionError);
  3. %[maxFunctionError maxErrorOrder]=max(functionError);
  4. bestChromosome=chromosomeGroup(minErrorOrder,:);
  5. %worstChromosome=chromosomeGroup(maxErrorOrder,:);
复制代码
 楼主| 发表于 2007-7-3 22:23 | 显示全部楼层
函数(5):误差比较函数:从两个染色体中,选出误差较小的染色体
%选择最好的基因保留下来
  1. function [newBestChromosome,newLeastFunctionError]...
  2. =compareBestChromosome(oldBestChromosome,oldLeastFunctionError,...
  3. bestChromosome,leastFunctionError)
  4. if oldLeastFunctionError>leastFunctionError
  5. newLeastFunctionError=leastFunctionError;
  6. newBestChromosome=bestChromosome;
  7. else
  8. newLeastFunctionError=oldLeastFunctionError;
  9. newBestChromosome=oldBestChromosome;
  10. end
复制代码
 楼主| 发表于 2007-7-3 22:23 | 显示全部楼层
函数(6):为染色体定义概率函数,好的染色体概率高,坏染色体概率低
%根据待解的非线性函数的误差计算染色体的概率
  1. function [p,isP]=chromosomeProbability(x_Error)
  2. InfN=sum(isinf(x_Error));%估计非线性方程计算的结果
  3. NaNN=sum(isnan(x_Error));
  4. if InfN>0 || NaNN>0
  5. isP='Fail';
  6. p=0;
  7. return
  8. else
  9. isP='True';
  10. errorReciprocal=1./x_Error;
  11. sumReciprocal=sum(errorReciprocal);
  12. p=errorReciprocal/sumReciprocal;%p:可能解所对应的染色体的概率
  13. end
复制代码
 楼主| 发表于 2007-7-3 22:24 | 显示全部楼层
函数(7):按概率选择染色体函数:
  1. function chromosome=selecteChromosome(chromosomeGroup,p)
  2. cumuP=cumsum(p);%累积概率,也就是把每个染色体的概率映射到0~1的区间
  3. [chromosomeSum,chromosomeLength]=size(chromosomeGroup);
  4. for i=1:chromosomeSum%这个循环产生概率值
  5. rN=rand(1);
  6. if rN==1
  7. chromosome(i,:)=chromosomeGroup(chromosomeSum,:);
  8. elseif (0<=rN) && (rN<cumuP(1))
  9. chromosome(i,:)=chromosomeGroup(1,:);%第1条染色体被选中
  10. else
  11. for j=2:chromosomeSum%这个循环确定第1条以后的哪一条染色体被选中
  12. if (cumuP(j-1)<=rN) && (rN<cumuP(j))
  13. chromosome(i,:)=chromosomeGroup(j,:);
  14. break
  15. end
  16. end
  17. end
  18. end
复制代码
 楼主| 发表于 2007-7-3 22:24 | 显示全部楼层
函数(8):父代染色体杂交产生子代染色体函数
  1. function sonChromosome=crossChromosome(fatherChromosome,parameter)
  2. [chromosomeSum,chromosomeLength]=size(fatherChromosome);
  3. %chromosomeSum:染色体的条数;chromosomeLength:染色体的长度
  4. switch parameter
  5. case 1%随机选择父染色体进行交叉重组
  6. for i=1:chromosomeSum/2
  7. crossDot=fix(rand(1)*chromosomeLength);%随机选择染色体的交叉点位
  8. randChromosomeSequence1=round(rand(1)*chromosomeSum);
  9. %随机产生第1条染色体的序号
  10. randChromosomeSequence2=round(rand(1)*chromosomeSum);
  11. %随机产生第2条染色体的序号,这两条染色体要进行杂交
  12. if randChromosomeSequence1==0%防止产生0序号
  13. randChromosomeSequence1=1;
  14. end
  15. if randChromosomeSequence2==0%防止产生0序号
  16. randChromosomeSequence2=1;
  17. end
  18. if crossDot==0 || crossDot==1
  19. sonChromosome(i*2-1,:)=fatherChromosome(randChromosomeSequence1,:);
  20. sonChromosome(i*2,:)=fatherChromosome(randChromosomeSequence2,:);
  21. else
  22. %执行两条染色体的交叉
  23. sonChromosome(i*2-1,:)=fatherChromosome(randChromosomeSequence1,:);
  24. %把父染色体整条传给子染色体
  25. sonChromosome(i*2-1,crossDot:chromosomeLength)=...
  26. fatherChromosome(randChromosomeSequence2,crossDot:chromosomeLength)
  27. %下一条父染色体上交叉点crossDot后的基因传给子染色体,完成前一条染色体的交叉
  28. sonChromosome(i*2,:)=fatherChromosome(randChromosomeSequence2,:);
  29. sonChromosome(i*2,crossDot:chromosomeLength)...
  30. =fatherChromosome(randChromosomeSequence1,crossDot:chromosomeLength)
  31. end
  32. end
  33. case 2 %父染色体的第i号与第chromosomeSum+1-i号交叉
  34. for i=1:chromosomeSum/2
  35. crossDot=fix(rand(1)*chromosomeLength);%随机选择染色体的交叉点位
  36. if crossDot==0 || crossDot==1
  37. sonChromosome(i*2-1,:)=fatherChromosome(i,:);
  38. sonChromosome(i*2,:)=fatherChromosome(chromosomeSum+1-i,:);
  39. else
  40. %执行两条染色体的交叉
  41. sonChromosome(i*2-1,:)=fatherChromosome(i,:);%把父染色体整条传给子染色体
  42. sonChromosome(i*2-1,crossDot:chromosomeLength)...
  43. =fatherChromosome(chromosomeSum+1-i,crossDot:chromosomeLength);
  44. %下一条父染色体上交叉点crossDot后的基因传给子染色体,完成前一条染色体的交叉
  45. sonChromosome(i*2,:)=fatherChromosome(chromosomeSum+1-i,:);
  46. sonChromosome(i*2,crossDot:chromosomeLength)...
  47. =fatherChromosome(i,crossDot:chromosomeLength);
  48. end
  49. end
  50. case 3 %父染色体的第i号与第i+chromosomeSum/2号交叉
  51. for i=1:chromosomeSum/2
  52. crossDot=fix(rand(1)*chromosomeLength);%随机选择染色体的交叉点位
  53. if crossDot==0 || crossDot==1
  54. sonChromosome(i*2-1,:)=fatherChromosome(i,:);
  55. sonChromosome(i*2,:)=fatherChromosome(i+chromosomeSum/2,:);
  56. else
  57. %执行两条染色体的交叉
  58. sonChromosome(i*2-1,:)=fatherChromosome(i,:);%把父染色体整条传给子染色体
  59. sonChromosome(i*2-1,crossDot:chromosomeLength)...
  60. =fatherChromosome(i+chromosomeSum/2,crossDot:chromosomeLength);
  61. %下一条父染色体上交叉点crossDot后的基因传给子染色体,完成前一条染色体的交叉
  62. sonChromosome(i*2,:)=fatherChromosome(i+chromosomeSum/2,:);
  63. sonChromosome(i*2,crossDot:chromosomeLength)...
  64. =fatherChromosome(i,crossDot:chromosomeLength);
  65. end
  66. end
  67. end
复制代码
 楼主| 发表于 2007-7-3 22:25 | 显示全部楼层
函数(9):防止染色体超出解空间的函数
%检测染色体(序号)是否超出解空间的函数
  1. function chromosome=checkSequence(chromosomeGroup,solutionSum)
  2. [chromosomeSum,chromosomeLength]=size(chromosomeGroup);
  3. decimalChromosomeSequence=bin2dec(chromosomeGroup);
  4. for i=1:chromosomeSum %检测变异后的染色体是否超出解空间
  5. if decimalChromosomeSequence(i)>solutionSum
  6. chRs=round(rand(1)*solutionSum);
  7. if chRs==0
  8. chRs=1;
  9. end
  10. decimalChromosomeSequence(i)=chRs;
  11. end
  12. end
  13. chromosome=dec2bin(decimalChromosomeSequence,chromosomeLength);
复制代码
 楼主| 发表于 2007-7-3 22:25 | 显示全部楼层
函数(10):变异函数
  1. %基因变异.染色体群中的1/10变异。vR是变异概率。solutionN是解空间中全部可能解的个数
  2. function aberranceChromosomeGroup=varianceCh(chromosomeGroup,vR,solutionN)
  3. [chromosomeSum,chromosomeLength]=size(chromosomeGroup);
  4. if chromosomeSum<10
  5. N=1;
  6. else
  7. N=round(chromosomeSum/10);
  8. end

  9. if rand(1)>vR %变异操作
  10. for i=1:N
  11. chromosomeOrder=round(rand(1)*chromosomeSum);%产生变异染色体序号
  12. if chromosomeOrder==0
  13. chromosomeOrder=1;
  14. end
  15. aberrancePosition=round(rand(1)*chromosomeLength);%产生变异位置
  16. if aberrancePosition==0
  17. aberrancePosition=1;
  18. end
  19. if chromosomeGroup(chromosomeOrder,aberrancePosition)=='1'
  20. chromosomeGroup(chromosomeOrder,aberrancePosition)='0';%变异
  21. else
  22. chromosomeGroup(chromosomeOrder,aberrancePosition)='1';%变异
  23. end
  24. end
  25. aberranceChromosomeGroup=chromosomeGroup;
  26. else
  27. aberranceChromosomeGroup=chromosomeGroup;
  28. end
复制代码


来自搜狐博客=〉人工智能
发表于 2008-3-22 11:24 | 显示全部楼层
谢谢楼主分享
发表于 2008-5-6 09:19 | 显示全部楼层
Thanks a lot.~~~~~~~~~~~~~
发表于 2008-6-27 11:15 | 显示全部楼层
谢谢楼主分享,敢问楼主有没有关于非线性二阶微分方程组的程序?
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-6-3 02:01 , Processed in 0.112248 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表