[笔记]遗传算法 genetic algorithm
来源:互联网 发布:数据化决策 编辑:程序博客网 时间:2024/05/23 05:09
引言
遗传算法是最优化问题的常用方法,尤其是组合优化,常常可以得到近似最优解。
从物种的进化历史来看,物种的进化正是自我优化的过程。
从种群上来看,进化这一过程中,目标函数正是物种对环境的适应能力,限制条件就是严酷的自然环境,而状态表征量正是物种的遗传物质,基因,DNA,RNA等。
假设环境不变的话,每一代物种都比上一代物种更加适应这个环境,因为不能适应环境的基因已经被淘汰。这一代代的淘汰与繁衍,正是一代代的优化过程。很可惜,自然环境是变化的,是与物种相互作用的,所以恐龙灭绝了。:(
但是,作为数学假设,遗传算法的限制条件一般是不变的,当然这也可以使变化的。
遗传算法的求解步骤
1.设定求解框架
种群数量是有限的,所以要设置种群的数量 population
进化过程用种群繁殖的代数表示,同样,种群的代数也是有限值 generation number
作为基因,在繁殖的时候要交换染色体,一般设定交换概率P = 1,可以保证充分进化,较快得到优化的结果。
繁殖过程中存在变异。将变异的概率设定为P = 0.1,符合实际中变异发生率低的事实。
2.状态变量
遗传算法一般用来求解组合问题的优化结果。
用随机序列
比如, n = 9时,随机序列为 [0.23, 0.82, 0.45, 0.74,0.87,0.11, 0.56, 0.69, 0.78] ,解码方法一般是排序操作,对随机序列进行升序排列,得到序列由小到大的元素的索引值 [5, 0, 2, 6, 7, 3, 8, 1, 4]。
3. 确定目标函数
map(target_function, state_variable)
4.初始化种群
一般采用改良圈法得到。对随机序列
交换
如果新的序列使目标函数减小,那么就覆盖原序列。直到,找到一个局部最优解。
5. 基因交叉
对种群随机两两匹配。交叉的方式有很多,这里只提及一种。
假设其中一组的两个序列分别为:
随机选取
那么子代
同样,子代基因
6. 基因变异
基因变异的方式有很多,记得生物学上DNA于RNA的变异不同。DNA的变异相对RNA的变异而言,与本体相比,差异小。而RNA变异则是大段基因的重组,所以RNA作为遗传物质的病毒,如HIV病毒,变异很快,适应环境的速度快。
这里为了快速得到最优解,可以选取类似RNA变异的算法。当然,还有许多其他方法。
已知,基因
将
7.进化
在得到的父代以及子代和变异的的种群后,按状态序列对应的目标函数值进行排序,最后选取最大的或是最小的固定种群数个基因,进行迭代,直到达到最大迭代次数,也就是generation number。
举例
一架飞机的起飞地点的经纬度分别是(70,40)。飞机速度为1000km/h。飞机从基地出发侦查完所有目标后返回基地。侦查时间不计,最短要花费多长时间回到基地。
目标的经纬度在文件”sj.txt”中。
这个问题需要求解起点和终点之间的序列。
应用上面的步骤可以利用numpy实现近似最优化解。
注意:遗传算法每次运行得到的结果可能并不相同,应多次运行后,再根据局部最优解得到近似解。本例中,并未多次运行,实现算法只为了学习、理解。
#!/usr/bin/env python3# -*- coding: utf-8 -*-import numpy as npimport mathdef load_txt(filename): """ return the [[x1,y1],[x2,y2]....] """ data = [] with open(filename) as f: for line in f: print(line) line = line.strip() first, second = line.split(' ') data.append([float(first),float(second)]) return datadef init_pop(population_num, distance_mat): """ return array shape (population_num, 102) """ population = np.zeros((population_num, 102)) for row in range(population_num): init_one = list(range(1,101)) np.random.shuffle(init_one) init_one = [0] + init_one + [101] for t in range(102): quit_flag = 0 for m in range(100): for n in range(m+2, 101): if distance_mat[init_one[m], init_one[n]] + distance_mat[init_one[m+1],init_one[n+1]] \ < distance_mat[init_one[m], init_one[m+1]] + distance_mat[init_one[n],init_one[n+1]]: temp = init_one[:] init_one = temp[:m+1] + temp[m+1:n+1][::-1] + temp[n+1:] quit_flag = 1 if quit_flag == 0: for idx, val in enumerate(init_one): population[row,val] = idx break population /= 101.0 # encoding return populationdef product(parent, distance_mat): """ parent numpy array (population_num, 102) distance_mat numpy array (102,102) return new population """ child = np.copy(parent) row = parent.shape[0] c = list(range(row)) np.random.shuffle(c) # exchange gene for i in range(0,row,2): position = math.floor(np.random.random() * 102) temp = np.copy(child[c[i], position:]) # ###### copy child[c[i], position:] = child[c[i+1], position:] child[c[i+1], position:] = temp # mutation gene change_row = np.array(range(row))[np.random.random(row)<0.1] B = np.copy(child[change_row,:]) for i in range(len(change_row)): mutation_pos = np.sort(np.floor(np.random.random(3)*102)) temp = np.copy(B[i,:]) B[i,:] = np.hstack((temp[:mutation_pos[0]], temp[mutation_pos[1]+1:mutation_pos[2]+1],\ temp[mutation_pos[0]:mutation_pos[1]+1],temp[mutation_pos[2]+1:])) family = np.vstack((parent, child, B)) family_idx = np.argsort(family, axis = 1) # decoding row_num = family.shape[0] length = np.zeros(row_num) for j in range(row_num): for i in range(101): length[j] += distance_mat[family_idx[j,i],family_idx[j,i+1]] idx = np.argsort(length) population = family[idx[:row],:] return populationif __name__ == '__main__': sj = load_txt('sj.txt') #length is 100 start_point = [[70,40]] sj = start_point + sj + start_point # the path is circular sj = np.array(sj) # change to array sj = sj * np.pi/180 # change to rads distance_mat = np.zeros((102,102)) # initialize the distance matrix for i in range(101): for j in range(i+1,102): point1 = np.array([np.cos(sj[i,0])*np.cos(sj[i,1]), np.sin(sj[i,0])*np.cos(sj[i,1]), np.sin(sj[i,1])]) point2 = np.array([np.cos(sj[j,0])*np.cos(sj[j,1]), np.sin(sj[j,0])*np.cos(sj[j,1]), np.sin(sj[j,1])]) distance_mat[i,j] = 6370 * math.acos(np.dot(point1, point2)\ /np.sqrt(np.dot(point1,point1) * np.dot(point2,point2))) distance_mat = distance_mat + distance_mat.T # build the systematic matrix# set the algorithm parameter population_num = 50 generation_num = 100 population = init_pop(population_num, distance_mat) # find the sectional optimize value# iterations for _ in range(generation_num): population = product(population, distance_mat)# population is the final group of genes# find the best gene num = population.shape[0] population_idx = np.argsort(population, axis=1) length = np.zeros(num) for j in range(num): for i in range(101): length[j] += distance_mat[population_idx[j,i],population_idx[j,i+1]] idx = np.argsort(length)[0] path = population_idx[idx] print(length[idx])
- [笔记]遗传算法 genetic algorithm
- 遗传算法 Genetic Algorithm
- 遗传算法--genetic algorithm
- 遗传算法(Genetic Algorithm)
- 遗传算法Genetic Algorithm
- 遗传算法(Genetic Algorithm)
- 遗传算法(Genetic Algorithm,GA)
- Genetic Algorithm遗传算法学习
- Genetic Algorithm遗传算法学习
- 遗传算法(Genetic Algorithm)
- 遗传算法(genetic algorithm, GA)
- GA遗传算法(Genetic Algorithm)
- 简单的遗传算法(Genetic Algorithm)源代码
- 遗传算法入门(Genetic Algorithm)
- 遗传算法(Genetic Algorithm)解决迷宫寻路问题
- 基因算法 Genetic Algorithm
- 算法理解-遗传算法(Genetic Algorithm)(一个带计算过程的例子)
- 跨世代保留精英遗传(基因)算法(intergenerational reserved Elitism Genetic Algorithm)
- hdu_1789_Doing Homework again
- C语言的内存分配
- POJ 1787 Charlie's Change 最多金币
- AtomicInteger
- 行为型模式-责任链模式
- [笔记]遗传算法 genetic algorithm
- UVa 10622 - Perfect P-th Powers(对数+快速幂)
- POJ 1679 次小生成树 Kruskal +DFS优化
- iOS开发 - SDWebImage使用(一个可管理远程图片加载的类库)
- hdu 1091 A+B for Input-Output Practice (III)
- Android Studio创建项目
- iOS支付宝问题之:调用支付宝AlipaySDK找不到头文件<openssl/rsa.h>
- 下载文件的php代码
- jsp页面加时间戳问题