缩水版遗传算法 学习笔记
来源:互联网 发布:mysql删除数据恢复 编辑:程序博客网 时间:2024/04/26 07:02
遗传算法是在随机的初始数据下,经过一段时间的变化,最后收敛得到针对某类特定问题的一个或者多个解。
主要步骤有编码 选择 交叉 变异
这里以一个极其简单的探索迷宫出路的代码为例 增加对遗传算法的感性认识。
编码
2,3,4,1,1,1,1,1,1,1,1,1,1,1,1,
1,8,1,0,0,0,0,0,0,0,1,0,0,1,1,
1,0,1,0,1,0,1,1,1,0,0,0,0,0,1,
1,0,1,0,1,0,1,1,1,1,0,1,0,1,1,
1,0,0,0,1,0,0,0,0,0,0,1,0,5,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
我们定义这样一个迷宫
1表示为不可到达地点
0表示可通过区域
5是起点 8是终点
我们再定义一系列行走出迷宫的行走方向数组 walk[TestStep](walk[50]).这个数组记录了走50步的方向
方向使用0-3来代替 0 表示向上走,1表示向下走,2表示向左走,3表示向右走。然后测试这一系列走法在迷宫能达到的坐标,以达到的位置和终点的X\Y的差值的倒数作为这个走法的评分
price = 1/(1.0+(abs(exitIndex.x-vMethods[i].currentPosIndex.x)+abs(exitIndex.y-vMethods[i].currentPosIndex.y)));
考虑到X\Y的差值可能为零,所以额外加了一个1.0;以上就是编码的步骤;
选择
作为进化演变下一代的元素,我们需要选择评分比较高的走法
通常的办法是轮盘赌选择 根据评分的高低 决定其被选中的几率
各个个体被选中的概率与其适应度函数值大小成正比。设群体大小为n ,个体i 的适应度为 Fi,则个体i 被选中遗传到下一代群体的概率为:
比如说
走法A 评分0.5
走法B 评分0.2
走法C 评分0.3
那么根据一个随机范围为0-99的随机数
如果数目在0-49之间 则选择走法A
如果数目在50-69之间则选择走法B
如果数目在70-99之间则选择走法C
我的代码中 写的比较简单 直接选择评分在前一半的作为进化演变的元素
int index1 = rand()%(TrySize/2);
int index2 = rand()%(TrySize/2);
缺点是可能逐步演化中 族群的走法都慢慢接近 甚至编程一样 从未导致没有变化 得不到正确结果
优点是 代码简单
交叉
2个元素交换部分结构,来构造下一代新的元素
例如
走法A 01230123 0123
走法B 12301230 1230
构造下一代走法
01230123 1230
代码中为
Method m = CrossOver(vMethods[index1],vMethods[index2]);
突变
对元素数据进行小概率的调整 以调整进化的集中性 避免所有元素同一化
代码中是以25%的概率 对某一步的走法进行调整
if((rand()%100)>75)
{
int index = rand()%TestStep;
m.walk[index] = direction(rand()%4);
}
本节代码属于实验性代码 对具体参数和一些算法都做了简化 只是加深对算法的理解 方便入门
至于算法的选择 参数优化调整的理论依据 均未涉及 需要学习理论教程书籍
代码如下
1 #include <iostream> 2 #include <ctime> 3 #include <cstdlib> 4 #include <vector> 5 #include <algorithm> 6 7 using namespace std; 8 9 int mapArray[6][15] = { 2,3,4,1,1,1,1,1,1,1,1,1,1,1,1, 10 1,8,1,0,0,0,0,0,0,0,1,0,0,1,1, 11 1,0,1,0,1,0,1,1,1,0,0,0,0,0,1, 12 1,0,1,0,1,0,1,1,1,1,0,1,0,1,1, 13 1,0,0,0,1,0,0,0,0,0,0,1,0,5,1, 14 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 15 struct Point{ 16 int x; 17 int y; 18 }; 19 20 Point startIndex = {4,13}; 21 Point exitIndex = {1,1}; 22 23 enum direction{ 24 Mup =0, 25 Mdown , 26 Mleft , 27 Mright }; 28 29 #define TestStep 50 30 #define TrySize 50 31 32 33 struct Method{ 34 direction walk[TestStep]; 35 Point currentPosIndex; 36 double price; 37 }; 38 39 vector<Method> vMethods; 40 vector<Method> vNewMethods; 41 42 43 bool SortByPrice(const Method& obj1,const Method& obj2) 44 { 45 return obj1.price>obj2.price; 46 } 47 48 void InitRandomWalk(direction walk[]){ 49 for(int i = 0;i< TestStep;++i){ 50 walk[i] = direction(rand()%4); 51 } 52 } 53 54 bool Walk(Point& currentPosIndex,direction walk[],int length){ 55 for(int i = 0;i< TestStep;++i){ 56 if(walk[i] == Mup){ 57 if( (currentPosIndex.x-1)>=0 && 58 mapArray[currentPosIndex.x-1][currentPosIndex.y] != 1){ 59 currentPosIndex.x -= 1; 60 } 61 }else if(walk[i] == Mdown){ 62 if( (currentPosIndex.x+1)<=5 && 63 mapArray[currentPosIndex.x+1][currentPosIndex.y] != 1){ 64 currentPosIndex.x += 1; 65 } 66 }else if(walk[i] == Mleft){ 67 if( (currentPosIndex.y-1)>=0 && 68 mapArray[currentPosIndex.x][currentPosIndex.y-1] != 1){ 69 currentPosIndex.y -= 1; 70 } 71 }else if(walk[i] == Mright){ 72 if( (currentPosIndex.y+1)<=14 && 73 mapArray[currentPosIndex.x][currentPosIndex.y+1] != 1){ 74 currentPosIndex.y += 1; 75 } 76 } 77 if(currentPosIndex.x == exitIndex.x && currentPosIndex.y == exitIndex.y){ 78 return true; 79 } 80 } 81 82 return false; 83 } 84 85 Method CrossOver(const Method& m1,const Method& m2){ 86 int i = rand()%TestStep; 87 Method m; 88 89 for(int j = 0; j <= i ;++j){ 90 m.walk[j] = m1.walk[j]; 91 } 92 93 for(int k =i;k < TestStep;++k){ 94 m.walk[k] = m2.walk[k]; 95 } 96 return m; 97 } 98 99 bool run(){100 101 for(int i = 0;i < TrySize;++i){102 vMethods[i].currentPosIndex.x = startIndex.x;103 vMethods[i].currentPosIndex.y = startIndex.y;104 if(Walk(vMethods[i].currentPosIndex, vMethods[i].walk,TestStep)){105 cout << "walk to exit!!!" << endl;106 return true;107 }108 vMethods[i].price = 1/(1.0+(abs(exitIndex.x-vMethods[i].currentPosIndex.x)+abs(exitIndex.y-vMethods[i].currentPosIndex.y)));109 cout << "current pos:\t" << vMethods[i].currentPosIndex.x <<" " << vMethods[i].currentPosIndex.y <<"\tprice:"<< vMethods[i].price<< endl;110 }111 112 sort(vMethods.begin(),vMethods.end(),SortByPrice);113 for(int i = 0 ; i <TrySize;i++){114 int index1 = rand()%(TrySize/2);115 int index2 = rand()%(TrySize/2);116 117 // for(int k = 0 ;k<TestStep;++k){118 // cout << vMethods[index1].walk[k];119 // }120 // cout << endl;121 122 Method m = CrossOver(vMethods[index1],vMethods[index2]);123 if((rand()%100)>75)124 {125 int index = rand()%TestStep;126 m.walk[index] = direction(rand()%4);127 128 }129 vNewMethods.push_back(m);130 // for(int k = 0 ;k<TestStep;++k){131 // cout << vMethods[index1].walk[k];132 // }133 // cout << endl;134 }135 vMethods = vNewMethods;136 vNewMethods.clear();137 return false;138 }139 140 141 142 143 144 int main(int argc, char *argv[])145 {146 vMethods.clear();147 srand( (unsigned)time( NULL ) );148 for(int i = 0;i < TrySize;++i){149 Method m;150 InitRandomWalk( m.walk);151 vMethods.push_back(m);152 }153 154 int64_t count = 0;155 while(!run()){156 count++;157 }158 cout << "run " << count << " times." << endl;159 160 161 return 0;162 }
- 缩水版遗传算法 学习笔记
- 遗传算法学习笔记
- 机器学习笔记之遗传算法(GA)
- 【神经网络学习笔记】遗传算法初探
- 遗传算法笔记备忘录(整理版)
- 遗传算法--笔记
- 【神经网络学习笔记】粒子群算法和遗传算法比较
- 遗传算法与直接搜索工具箱学习笔记 八-----遗传算法概述
- 遗传算法与直接搜索工具箱学习笔记 九-----遗传算法举例
- 遗传算法与直接搜索工具箱学习笔记 十-----遗传算法的工作原理
- 遗传算法与直接搜索工具箱学习笔记 八-----遗传算法概述
- 遗传算法与直接搜索工具箱学习笔记 九-----遗传算法举例
- 遗传算法与直接搜索工具箱学习笔记 十-----遗传算法的工作原理
- 遗传算法学习总结
- 遗传算法学习
- 遗传算法学习材料
- 遗传算法与直接搜索工具箱学习笔记 一-----概述
- 遗传算法与直接搜索工具箱学习笔记 一-----概述
- 每日一练之Roman to integer & integer to Roman【LeetCode No.12,13】
- npm镜像安装和使用方法
- 解决ThinkPHP部署时Access denied.
- 二分法常用模板
- 令人惊讶!索尼宣布关闭PS VR游戏《RIGS》工作室
- 缩水版遗传算法 学习笔记
- Java中的“抽象接口”
- spring4 ActiveMQ
- 树莓派通过邮件发送IP地址
- oracle--分组函数
- web.js.数组操作之sort()
- 冒泡排序法的理解
- CCNA图文笔记(六)NAT协议实例详解
- 软键盘弹出与消失的方法