日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python優化算法之遺傳算法案例代碼_python

作者:旅途中的寬~ ? 更新時間: 2023-05-20 編程語言

一、前言

優化算法,尤其是啟發式的仿生智能算法在最近很火,它適用于解決管理學,運籌學,統計學里面的一些優化問題。比如線性規劃,整數規劃,動態規劃,非線性約束規劃,甚至是超參數搜索等等方向的問題。

但是一般的優化算法還是matlab里面用的多,Python相關代碼較少。

我在參考了一些文章的代碼和模塊之后,決定學習scikit-opt這個模塊。這個優化算法模塊對新手很友好,代碼簡潔,上手簡單。而且代碼和官方文檔是中國人寫的,還有很多案例,學起來就沒什么壓力。

缺點是包裝的算法種類目前還不算多,只有七種:(差分進化算法、遺傳算法、粒子群算法、模擬退火算法、蟻群算法、魚群算法、免疫優化算法)

本次帶來的是數學建模里面經常使用的遺傳算法的使用演示。

二、安裝

首先安裝模塊,在cmd里面或者anaconda prompt里面輸入:

pip install scikit-opt

對于當前開發人員版本:

git clone git@github.com:guofei9987/scikit-opt.git
cd scikit-opt
pip install .

三、遺傳算法

3.1 自定義函數

UDF(用戶定義函數)現已推出!

例如,您剛剛制定了一種新型函數?,F在,你的函數是這樣的:

該函數有大量的局部最小值,具有很強的沖擊力,在(0,0) 處的全局最小值,值為 0。

import numpy as np
def schaffer(p):
    x1, x2 = p
    x = np.square(x1) + np.square(x2)
    return 0.5 + (np.square(np.sin(x)) - 0.5) / np.square(1 + 0.001 * x)

導入和構建 ga :(遺傳算法)

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

運行結果為:

在這里插入圖片描述


可以看到基本找到了全局最小值和對應的x 。

畫出迭代次數的圖:

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

在這里插入圖片描述

GA算法的參數詳解:

輸入參數:

輸入參數 默認值 參數的意義
func - 目標函數
n_dim - 目標函數的維度
size_pop 50 種群規模
max_iter 200 最大迭代次數
prob_mut 0.001 變異概率
lb -1 每個自變量的最小值
ub 1 每個自變量的最大值
constraint_eq 空元組 等式約束
constraint_ueq 空元組 不等式約束
precision 1e-7 精確度,int / float或者它們組成的列表

輸出參數:

GA & GA_TSP

輸出參數 參數的意義
ga.generation_best_X 每一代的最優函數值對應的輸入值
ga.generation_best_Y 每一代的最優函數值
ga.all_history_FitV 每一代的每個個體的適應度
ga.all_history_Y 每一代每個個體的函數值

3.2 遺傳算法進行整數規劃

在多維優化時,想讓哪個變量限制為整數,就設定 precision 為 整數 即可。

例如,我想讓我的自定義函數的某些變量限制為整數+浮點數(分別是整數,整數,浮點數),那么就設定 precision=[1, 1, 1e-7]

例子如下:

from sko.GA import GA
demo_func = lambda x: (x[0] - 1) ** 2 + (x[1] - 0.05) ** 2 + x[2] ** 2
ga = GA(func = demo_func, n_dim = 3, max_iter = 500, lb = [-1, -1, -1], ub = [5, 1, 1], precision = [1,1,1e-7])
best_x, best_y = ga.run()
print('best_x:', best_x, '\n', 'best_y:', best_y)

在這里插入圖片描述

可以看到第一個、第二個變量都是整數,第三個就是浮點數了 。

3.3 遺傳算法用于旅行商問題

商旅問題(TSP)就是路徑規劃的問題,比如有很多城市,你都要跑一遍,那么先去哪個城市再去哪個城市可以讓你的總路程最小。

實際問題需要一個城市坐標數據,比如你的出發點位置為(0,0),第一個城市離位置為 ( x 1 , y 1 ) (x_1,y_1) (x1?,y1?),第二個為 ( x 2 , y 2 ) (x_2,y_2) (x2?,y2?)…這里沒有實際數據,就直接隨機生成了。

import numpy as np
from scipy import spatial
import matplotlib.pyplot as plt
num_points = 50
points_coordinate = np.random.rand(num_points, 2)  # generate coordinate of points
points_coordinate

在這里插入圖片描述

這里定義的是50個城市,每個城市的坐標都在是上圖隨機生成的矩陣。

然后我們把它變成類似相關系數里面的矩陣:

distance_matrix = spatial.distance.cdist(points_coordinate, points_coordinate, metric='euclidean')
distance_matrix.shape
(50, 50)

這個矩陣就能得出每個城市之間的距離,算上自己和自己的距離(0),總共有2500個數。

定義問題:

def cal_total_distance(routine):
    num_points, = routine.shape
    return sum([distance_matrix[routine[i % num_points], routine[(i + 1) % num_points]] for i in range(num_points)])

求解問題:

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

我們展示一下結果:

best_distance

在這里插入圖片描述

畫圖查看計算出來的路徑,還有迭代次數和y的關系:

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

在這里插入圖片描述

3.4 使用遺傳算法進行曲線擬合

構建數據集:

import numpy as np
import matplotlib.pyplot as plt
from sko.GA import GA
x_true = np.linspace(-1.2, 1.2, 30)
y_true = x_true ** 3 - x_true + 0.4 * np.random.rand(30)
plt.plot(x_true, y_true, 'o')

構建的數據是 y = x 3 ? x + 0.4 y=x^3-x+0.4 y=x3?x+0.4,然后加上了隨機擾動項。如圖:

在這里插入圖片描述

定義需要擬合的函數(三次函數),然后將殘差作為目標函數去求解:

def f_fun(x, a, b, c, d):
    return a * x ** 3 + b * x ** 2 + c * x + d   #三次函數

def obj_fun(p):
    a, b, c, d = p
    residuals = np.square(f_fun(x_true, a, b, c, d) - y_true).sum()
    return residuals

求解:

ga = GA(func = obj_fun, n_dim = 4, size_pop = 100, max_iter = 500, lb = [-2] * 4, ub = [2] * 4)
best_params, residuals = ga.run()
print('best_x:', best_params, '\n', 'best_y:', residuals)

在這里插入圖片描述

可以看到擬合出來的方程為 y = 0.9656 x 3 ? 0.0065 x 2 ? 1.0162 x + 0.2162 y=0.9656x^{3}-0.0065x^{2}-1.0162x+0.2162 y=0.9656x3?0.0065x2?1.0162x+0.2162

畫出擬合線:

y_predict = f_fun(x_true, *best_params)
fig, ax = plt.subplots()
ax.plot(x_true, y_true, 'o')
ax.plot(x_true, y_predict, '-')
plt.show()

在這里插入圖片描述

原文鏈接:https://blog.csdn.net/wzk4869/article/details/129036683

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新