小言_互联网的博客

一个易用、易部署的Python遗传算法库

326人阅读  评论(0)

简介: # [scikit-opt](https://github.com/guofei9987/scikit-opt) [![PyPI](https://img.shields.io/pypi/v/scikit-opt)](https://pypi.org/project/scikit-opt/) [![release](https://img.shields.io/github/v/relea

scikit-opt

PyPI
release


PyPI_downloads
Stars
Forks

一个封装了7种启发式算法的 Python 代码库 
(差分进化算法、遗传算法、粒子群算法、模拟退火算法、蚁群算法、鱼群算法、免疫优化算法)



安装

pip install scikit-opt
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

或者直接把源代码中的 sko 文件夹下载下来放本地也调用可以

特性

特性1:UDF(用户自定义算子)

举例来说,你想出一种新的“选择算子”,如下
-> Demo code: examples/demo_ga_udf.py#s1


  
  1. # step1: define your own operator:
  2. def selection_tournament(algorithm, tourn_size):
  3. FitV = algorithm.FitV
  4. sel_index = []
  5. for i in range(algorithm.size_pop):
  6. aspirants_index = np.random.choice(range(algorithm.size_pop), size=tourn_size)
  7. sel_index.append(max(aspirants_index, key=lambda i: FitV[i]))
  8. algorithm.Chrom = algorithm.Chrom[sel_index, :] # next generation
  9. return algorithm.Chrom

导入包,并且创建遗传算法实例 
-> Demo code: examples/demo_ga_udf.py#s2


  
  1. import numpy as np
  2. from sko.GA import GA, GA_TSP
  3. demo_func = lambda x: x[ 0] ** 2 + (x[ 1] - 0. 05) ** 2 + (x[ 2] - 0. 5) ** 2
  4. ga = GA(func=demo_func, n_dim= 3, size_pop= 100, max_iter= 500, lb=[- 1, - 10, - 5], ub=[ 2, 10, 2],
  5. precision=[ 1e- 7, 1e- 7, 1])

把你的算子注册到你创建好的遗传算法实例上 
-> Demo code: examples/demo_ga_udf.py#s3

ga.register(operator_name='selection', operator=selection_tournament, tourn_size=3)

scikit-opt 也提供了十几个算子供你调用 
-> Demo code: examples/demo_ga_udf.py#s4


  
  1. from sko.operators import ranking, selection, crossover, mutation
  2. ga. register(operator_name= 'ranking', operator=ranking.ranking). \
  3. register(operator_name= 'crossover', operator=crossover.crossover_2point). \
  4. register(operator_name= 'mutation', operator=mutation.mutation)

做遗传算法运算
-> Demo code: examples/demo_ga_udf.py#s5


  
  1. best_x, best_y = ga.run()
  2. print( 'best_x:', best_x, '\n', 'best_y:', best_y)

现在 udf 支持遗传算法的这几个算子: crossovermutationselectionranking

Scikit-opt 也提供了十来个算子,参考这里

提供一个面向对象风格的自定义算子的方法,供进阶用户使用:

-> Demo code: examples/demo_ga_udf.py#s6


  
  1. class MyGA(GA):
  2. def selection(self, tourn_size= 3):
  3. FitV = self.FitV
  4. sel_index = []
  5. for i in range(self.size_pop):
  6. aspirants_index = np.random.choice(range(self.size_pop), size=tourn_size)
  7. sel_index.append(max(aspirants_index, key=lambda i: FitV[i]))
  8. self.Chrom = self.Chrom[sel_index, :] # next generation
  9. return self.Chrom
  10. ranking = ranking.ranking
  11. demo_func = lambda x: x[ 0] ** 2 + (x[ 1] - 0. 05) ** 2 + (x[ 2] - 0. 5) ** 2
  12. my_ga = MyGA(func=demo_func, n_dim= 3, size_pop= 100, max_iter= 500, lb=[- 1, - 10, - 5], ub=[ 2, 10, 2],
  13. precision=[ 1e- 7, 1e- 7, 1])
  14. best_x, best_y = my_ga.run()
  15. print('best_x:', best_x, '\n', 'best_y:', best_y)

特性2: GPU 加速

GPU加速功能还比较简单,将会在 1.0.0 版本大大完善。 
有个 demo 已经可以在现版本运行了: https://github.com/guofei9987/scikit-opt/blob/master/examples/demo_ga_gpu.py

特性3:断点继续运行

例如,先跑10代,然后在此基础上再跑20代,可以这么写:


  
  1. from sko.GA import GA
  2. func = lambda x: x[0] ** 2
  3. ga = GA( func=func, n_dim=1)
  4. ga.run( 10)
  5. ga.run( 20)

快速开始

1. 差分进化算法

Step1:定义你的问题,这个demo定义了有约束优化问题 
-> Demo code: examples/demo_de.py#s1


  
  1. '''
  2. min f(x1, x2, x3) = x1^2 + x2^2 + x3^2
  3. s.t.
  4. x1*x2 >= 1
  5. x1*x2 <= 5
  6. x2 + x3 = 1
  7. 0 <= x1, x2, x3 <= 5
  8. '''
  9. def obj_func(p):
  10. x1, x2, x3 = p
  11. return x1 ** 2 + x2 ** 2 + x3 ** 2
  12. constraint_eq = [
  13. lambda x: 1 - x[ 1] - x[ 2]
  14. ]
  15. constraint_ueq = [
  16. lambda x: 1 - x[ 0] * x[ 1],
  17. lambda x: x[ 0] * x[ 1] - 5
  18. ]

Step2: 做差分进化算法 
-> Demo code: examples/demo_de.py#s2


  
  1. from sko.DE import DE
  2. de = DE(func=obj_func, n_dim= 3, size_pop= 50, max_iter= 800, lb=[ 0, 0, 0], ub=[ 5, 5, 5],
  3. constraint_eq=constraint_eq, constraint_ueq=constraint_ueq)
  4. best_x, best_y = de.run()
  5. print('best_x:', best_x, '\n', 'best_y:', best_y)

2. 遗传算法

第一步:定义你的问题 
-> Demo code: examples/demo_ga.py#s1


  
  1. import numpy as np
  2. def schaffer(p):
  3. '''
  4. This function has plenty of local minimum, with strong shocks
  5. global minimum at (0,0) with value 0
  6. '''
  7. x1, x2 = p
  8. x = np.square(x1) + np.square(x2)
  9. return 0.5 + (np.sin(x) - 0.5) / np.square( 1 + 0.001 * x)

第二步:运行遗传算法 
-> Demo code: examples/demo_ga.py#s2


  
  1. from sko.GA import GA
  2. ga = GA(func=schaffer, n_dim= 2, size_pop= 50, max_iter= 800, lb=[- 1, - 1], ub=[ 1, 1], precision= 1e- 7)
  3. best_x, best_y = ga.run()
  4. print('best_x:', best_x, '\n', 'best_y:', best_y)

第三步:用 matplotlib 画出结果 
-> Demo code: examples/demo_ga.py#s3


  
  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. Y_history = pd.DataFrame(ga.all_history_Y)
  4. fig, ax = plt.subplots( 2, 1)
  5. ax[ 0].plot(Y_history.index, Y_history.values, '.', color= 'red')
  6. Y_history.min(axis= 1).cummin().plot(kind= 'line')
  7. plt.show()

2.2 遗传算法用于旅行商问题

GA_TSP 针对TSP问题重载了 交叉(crossover)变异(mutation) 两个算子

第一步,定义问题。 
这里作为demo,随机生成距离矩阵. 实战中从真实数据源中读取。

-> Demo code: examples/demo_ga_tsp.py#s1


  
  1. import numpy as np
  2. from scipy import spatial
  3. import matplotlib.pyplot as plt
  4. num_points = 50
  5. points_coordinate = np.random.rand(num_points, 2) # generate coordinate of points
  6. distance_matrix = spatial.distance.cdist(points_coordinate, points_coordinate, metric= 'euclidean')
  7. def cal_total_distance(routine):
  8. '''The objective function. input routine, return total distance.
  9. cal_total_distance(np.arange(num_points))
  10. '''
  11. num_points, = routine.shape
  12. return sum([distance_matrix[routine[i % num_points], routine[(i + 1) % num_points]] for i in range(num_points)])

第二步,调用遗传算法进行求解 
-> Demo code: examples/demo_ga_tsp.py#s2


  
  1. from sko. GA import GA_TSP
  2. ga_tsp = GA_TSP( func=cal_total_distance, n_dim=num_points, size_pop=50, max_iter=500, prob_mut=1)
  3. best_points, best_distance = ga_tsp. run ()

第三步,画出结果: 
-> Demo code: examples/demo_ga_tsp.py#s3


  
  1. fig, ax = plt.subplots( 1, 2)
  2. best_points_ = np.concatenate([best_points, [best_points[0]]])
  3. best_points_coordinate = points_coordinate[best_points_, :]
  4. ax[ 0].plot(best_points_coordinate[:, 0], best_points_coordinate[:, 1], 'o-r')
  5. ax[ 1].plot(ga_tsp.generation_best_Y)
  6. plt.show()

3. 粒子群算法

(PSO, Particle swarm optimization)

3.1 带约束的粒子群算法

第一步,定义问题 
-> Demo code: examples/demo_pso.py#s1


  
  1. def demo_func(x):
  2. x1, x 2, x 3 = x
  3. return x 1 ** 2 + (x 2 - 0. 05) ** 2 + x 3 ** 2

第二步,做粒子群算法 
-> Demo code: examples/demo_pso.py#s2


  
  1. from sko.PSO import PSO
  2. pso = PSO(func=demo_func, dim= 3, pop= 40, max_iter= 150, lb=[ 0, - 1, 0. 5], ub=[ 1, 1, 1], w= 0. 8, c 1= 0. 5, c 2= 0. 5)
  3. pso.run()
  4. print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)

第三步,画出结果 
-> Demo code: examples/demo_pso.py#s3


  
  1. import matplotlib .pyplot as plt
  2. plt .plot( pso .gbest_y_hist)
  3. plt .show()


see examples/demo_pso.py

3.2 不带约束的粒子群算法

-> Demo code: examples/demo_pso.py#s4


  
  1. pso = PSO( func=demo_func, dim=3)
  2. fitness = pso. run ()
  3. print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)

4. 模拟退火算法

(SA, Simulated Annealing)

4.1 模拟退火算法用于多元函数优化

第一步:定义问题 
-> Demo code: examples/demo_sa.py#s1

demo_func = lambda x: x[0] ** 2 + (x[1] - 0.05) ** 2 + x[2] ** 2

第二步,运行模拟退火算法 
-> Demo code: examples/demo_sa.py#s2


  
  1. from sko.SA import SA
  2. sa = SA(func=demo_func, x 0=[ 1, 1, 1], T_max= 1, T_min= 1e- 9, L= 300, max_stay_counter= 150)
  3. best_x, best_y = sa.run()
  4. print('best_x:', best_x, 'best_y', best_y)

第三步,画出结果
-> Demo code: examples/demo_sa.py#s3


  
  1. import matplotlib.pyplot as plt
  2. import pandas as pd
  3. plt.plot(pd. DataFrame(sa.best_y_history).cummin(axis= 0))
  4. plt.show()

另外,scikit-opt 还提供了三种模拟退火流派: Fast, Boltzmann, Cauchy. 更多参见 more sa

4.2 模拟退火算法解决TSP问题(旅行商问题)

第一步,定义问题。(我猜你已经无聊了,所以不黏贴这一步了)

第二步,调用模拟退火算法 
-> Demo code: examples/demo_sa_tsp.py#s2


  
  1. from sko. SA import SA_TSP
  2. sa_tsp = SA_TSP( func=cal_total_distance, x0=range(num_points), T_max= 100, T_min= 1, L= 10 * num_points)
  3. best_points, best_distance = sa_tsp.run()
  4. print(best_points, best_distance, cal_total_distance(best_points))

第三步,画出结果
-> Demo code: examples/demo_sa_tsp.py#s3


  
  1. from matplotlib.ticker import FormatStrFormatter
  2. fig, ax = plt.subplots( 1, 2)
  3. best_points_ = np.concatenate([best_points, [best_points[0]]])
  4. best_points_coordinate = points_coordinate[best_points_, :]
  5. ax[ 0].plot(sa_tsp.best_y_history)
  6. ax[ 0].set_xlabel( "Iteration")
  7. ax[ 0].set_ylabel( "Distance")
  8. ax[ 1].plot(best_points_coordinate[:, 0], best_points_coordinate[:, 1],
  9. marker='o', markerfacecolor='b', color='c', linestyle='-')
  10. ax[ 1].xaxis.set_major_formatter(FormatStrFormatter('%. 3f'))
  11. ax[ 1].yaxis.set_major_formatter(FormatStrFormatter('%. 3f'))
  12. ax[ 1].set_xlabel( "Longitude")
  13. ax[ 1].set_ylabel( "Latitude")
  14. plt.show()

咱还有个动画 

参考代码 examples/demo_sa_tsp.py

5. 蚁群算法

蚁群算法(ACA, Ant Colony Algorithm)解决TSP问题

-> Demo code: examples/demo_aca_tsp.py#s2


  
  1. from sko. ACA import ACA_TSP
  2. aca = ACA_TSP( func=cal_total_distance, n_dim=num_points,
  3. size_pop=50, max_iter=200,
  4. distance_matrix= distance_matrix)
  5. best_x, best_y = aca. run ()

6. 免疫优化算法

(immune algorithm, IA)
-> Demo code: examples/demo_ia.py#s2


  
  1. from sko.IA import IA_TSP
  2. ia_tsp = IA_TSP(func=cal_total_distance, n_dim=num_points, size_pop= 500, max_iter= 800, prob_mut= 0. 2,
  3. T= 0. 7, alpha= 0. 95)
  4. best_points, best_distance = ia_tsp.run()
  5. print('best routine:', best_points, 'best_distance:', best_distance)

7. 人工鱼群算法

人工鱼群算法(artificial fish swarm algorithm, AFSA)

-> Demo code: examples/demo_afsa.py#s1


  
  1. def func(x):
  2. x1, x 2 = x
  3. return 1 / x 1 ** 2 + x 1 ** 2 + 1 / x 2 ** 2 + x 2 ** 2
  4. from sko.AFSA import AFSA
  5. afsa = AFSA(func, n_dim= 2, size_pop= 50, max_iter= 300,
  6. max_try_num= 100, step= 0. 5, visual= 0. 3,
  7. q= 0. 98, delta= 0. 5)
  8. best_x, best_y = afsa.run()
  9. print(best_x, best_y)

 

 

原文链接
本文为阿里云原创内容,未经允许不得转载。


转载:https://blog.csdn.net/yunqiinsight/article/details/108144993
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场