#python #matplotlib
Вопрос:
Я реализовал простой рандомизированный метод оптимизации на основе популяции- оптимизатор Серого волка. У меня возникли некоторые проблемы с правильным захватом графиков Matplotlib на каждой итерации с использованием camera
пакета.
Я запускаю GWO для целевой функции f(x,y) = x^2 y^2. Я вижу только возможные решения, сходящиеся к минимумам, но контурный график не отображается.
У вас есть какие-либо предложения, как я могу отобразить контурный график в фоновом режиме?
Реализация алгоритма GWO
%matplotlib notebook import matplotlib.pyplot as plt import numpy as np from celluloid import Camera import ffmpeg import pillow # X : Position vector of the initial population # n : Initial population size def gwo(f,max_iterations,LB,UB): fig = plt.figure() camera = Camera(fig) def random_population_uniform(m,a,b): dims = len(a) x = [list(a np.multiply(np.random.rand(dims),b - a)) for i in range(m)] return np.array(x) def search_agent_fitness(fitness): alpha = 0 if fitness[1] lt; fitness[alpha]: alpha, beta = 1, alpha else: beta = 1 if fitness[2] gt; fitness[alpha] and fitness[2] lt; fitness[beta]: beta, delta = 2, beta elif fitness[2] lt; fitness[alpha]: alpha,beta,delta = 2,alpha,beta else: delta = 2 for i in range(3,len(fitness)): if fitness[i] lt;= fitness[alpha]: alpha, beta,delta = i, alpha, beta elif fitness[i] gt; fitness[alpha] and fitness[i]lt;= fitness[beta]: beta,delta = i,beta elif fitness[i] gt; fitness[beta] and fitness[i]lt;= fitness[delta]: delta = i return alpha, beta, delta def plot_search_agent_positions(f,X,alpha,beta,delta,a,b): # Plot the positions of search agents x = X[:,0] y = X[:,1] s = plt.scatter(x,y,c='gray',zorder=1) s = plt.scatter(x[alpha],y[alpha],c='red',zorder=1) s = plt.scatter(x[beta],y[beta],c='blue',zorder=1) s = plt.scatter(x[delta],y[delta],c='green',zorder=1) camera.snap() # Initialize the position of the search agents X = random_population_uniform(50,np.array(LB),np.array(UB)) n = len(X) l = 1 # Plot the first image on screen x = np.linspace(LB[0],LB[1],1000) y = np.linspace(LB[0],UB[1],1000) X1,X2 = np.meshgrid(x,y) Z = f(X1,X2) cont = plt.contour(X1,X2,Z,20,linewidths=0.75) while (l lt; max_iterations): # Take the x,y coordinates of the initial population x = X[:,0] y = X[:,1] # Calculate the objective function for each search agent fitness = list(map(f,x,y)) # Update alpha, beta and delta alpha,beta,delta = search_agent_fitness(fitness) # Plot search agent positions plot_search_agent_positions(f,X,alpha,beta,delta,LB,UB) # a decreases linearly from 2 to 0 a = 2 - l *(2 / max_iterations) # Update the position of search agents including the Omegas for i in range(n): x_prey = X[alpha] r1 = np.random.rand(2) #r1 is a random vector in [0,1] x [0,1] r2 = np.random.rand(2) #r2 is a random vector in [0,1] x [0,1] A1 = 2*a*r1 - a C1 = 2*r2 D_alpha = np.abs(C1 * x_prey - X[i]) X_1 = x_prey - A1*D_alpha x_prey = X[beta] r1 = np.random.rand(2) r2 = np.random.rand(2) A2 = 2*a*r1 - a C2 = 2*r2 D_beta = np.abs(C2 * x_prey - X[i]) X_2 = x_prey - A2*D_beta x_prey = X[delta] r1 = np.random.rand(2) r2 = np.random.rand(2) A3 = 2*a*r1 - a C3 = 2*r2 D_delta = np.abs(C3 * x_prey - X[i]) X_3 = x_prey - A3*D_delta X[i] = (X_1 X_2 X_3)/3 l = l 1 return X[alpha],camera
Вызов функции
# define the objective function def f(x,y): return x**2 y**2 minimizer,camera = gwo(f,7,[-10,-10],[10,10]) animation = camera.animate(interval = 1000, repeat = True, repeat_delay = 500)
Ответ №1:
Возможно ли x = np.linspace(LB[0],LB[1],1000)
, чтобы вместо этого была строка x = np.linspace(LB[0],UB[1],1000)
? С вашим текущим определением x
, x
является массивом, заполненным только значением -10
, что означает, что вы вряд ли найдете контур. Еще одна вещь, которую вы, возможно, захотите сделать, — это переместить cont = plt.contour(X1,X2,Z,20,linewidths=0.75)
линию внутри вашей plot_search_agent_positions
функции, чтобы убедиться, что контур отображается на каждой итерации анимации. Как только вы внесете эти изменения, код будет выглядеть следующим образом:
import matplotlib.pyplot as plt import numpy as np from celluloid import Camera import ffmpeg import PIL from matplotlib import animation, rc from IPython.display import HTML, Image # For GIF from scipy.interpolate import griddata rc('animation', html='html5') # X : Position vector of the initial population # n : Initial population size def gwo(f,max_iterations,LB,UB): fig = plt.figure() fig.gca(aspect='equal') camera = Camera(fig) def random_population_uniform(m,a,b): dims = len(a) x = [list(a np.multiply(np.random.rand(dims),b - a)) for i in range(m)] return np.array(x) def search_agent_fitness(fitness): alpha = 0 if fitness[1] lt; fitness[alpha]: alpha, beta = 1, alpha else: beta = 1 if fitness[2] gt; fitness[alpha] and fitness[2] lt; fitness[beta]: beta, delta = 2, beta elif fitness[2] lt; fitness[alpha]: alpha,beta,delta = 2,alpha,beta else: delta = 2 for i in range(3,len(fitness)): if fitness[i] lt;= fitness[alpha]: alpha, beta,delta = i, alpha, beta elif fitness[i] gt; fitness[alpha] and fitness[i]lt;= fitness[beta]: beta,delta = i,beta elif fitness[i] gt; fitness[beta] and fitness[i]lt;= fitness[delta]: delta = i return alpha, beta, delta def plot_search_agent_positions(f,X,alpha,beta,delta,a,b,X1,X2,Z): # Plot the positions of search agents x = X[:,0] y = X[:,1] s = plt.scatter(x,y,c='gray',zorder=1) s = plt.scatter(x[alpha],y[alpha],c='red',zorder=1) s = plt.scatter(x[beta],y[beta],c='blue',zorder=1) s = plt.scatter(x[delta],y[delta],c='green',zorder=1) Z=f(X1,X2) cont=plt.contour(X1,X2,Z,levels=20,colors='k',norm=True) plt.clabel(cont, cont.levels, inline=True, fontsize=10) camera.snap() # Initialize the position of the search agents X = random_population_uniform(50,np.array(LB),np.array(UB)) n = len(X) l = 1 # Plot the first image on screen x = np.linspace(LB[0],UB[1],1000) y = np.linspace(LB[0],UB[1],1000) X1,X2 = np.meshgrid(x,y) Z=f(X1,X2) while (l lt; max_iterations): # Take the x,y coordinates of the initial population x = X[:,0] y = X[:,1] # Calculate the objective function for each search agent fitness = list(map(f,x,y)) # Update alpha, beta and delta alpha,beta,delta = search_agent_fitness(fitness) # Plot search agent positions plot_search_agent_positions(f,X,alpha,beta,delta,LB,UB,X1,X2,Z) # a decreases linearly from 2 to 0 a = 2 - l *(2 / max_iterations) # Update the position of search agents including the Omegas for i in range(n): x_prey = X[alpha] r1 = np.random.rand(2) #r1 is a random vector in [0,1] x [0,1] r2 = np.random.rand(2) #r2 is a random vector in [0,1] x [0,1] A1 = 2*a*r1 - a C1 = 2*r2 D_alpha = np.abs(C1 * x_prey - X[i]) X_1 = x_prey - A1*D_alpha x_prey = X[beta] r1 = np.random.rand(2) r2 = np.random.rand(2) A2 = 2*a*r1 - a C2 = 2*r2 D_beta = np.abs(C2 * x_prey - X[i]) X_2 = x_prey - A2*D_beta x_prey = X[delta] r1 = np.random.rand(2) r2 = np.random.rand(2) A3 = 2*a*r1 - a C3 = 2*r2 D_delta = np.abs(C3 * x_prey - X[i]) X_3 = x_prey - A3*D_delta X[i] = (X_1 X_2 X_3)/3 l = l 1 return X[alpha],camera # define the objective function def f(x,y): return x**2 y**2 minimizer,camera = gwo(f,7,[-10,-10],[10,10]) animation = camera.animate(interval = 1000, repeat = True,repeat_delay = 500)
И результат дает:
Комментарии:
1. Я также добавил
fig.gca(aspect='equal')
, чтобы исправить соотношение сторон сюжета. И я добавил контурные метки сplt.clabel(cont, cont.levels, inline=True, fontsize=10)
помощью .