有偿有偿,在做一个用遗传算法求解最优解的程序,刚学,遗传算法库用不明白,有很多地方想要修改,所以自己写了一个,不过我发现运行速度太慢了,有没有懂得可以帮忙看看修改一下,在保留原有功能的前提运行速度更快一点,
对你们来讲这代码也不长,最好是可以给一个修改好的,因为你们说怎么修改我可能不懂
from tmm import coh_tmm
import numpy as np
import time
import cupy as cp
import random
from collections import deque
import os
import pandas as pd
st_time01 = time.time()
base_directory = "G:\\\\Good_Good_Study\\\\Python_wl\\\\MARCs\\\\MARCS_GRU+Self-Attention Mechanism\\\\材料库"
kinds_materials = ["GaSb", "Air", "Si", "WO3", "ZnSe", "SiO2", "Fe2O3", "Ti", "MgF2", "Ti", "ZrO2", "Ge2Sb2Te5"]
# 一次性读取所有Excel文件,并存储在词典中
material_data = {}
Base_material = "GaSb"
def load_all_material_data():
for material in kinds_materials:
filename = os.path.join(base_directory, f"{material}.xlsx")
if os.path.exists(filename):
try:
df = pd.read_excel(filename)
material_data[material] = df
except Exception as e:
print(f"'{material}'材料数据加载时出错:{e}")
else:
print(f"未找到文件: '{filename}'")
print(f'加载材料数据。。。')
load_all_material_data()
def get_refractive_index_and_extinction_coefficient(current_material, lambda_):
material_df = material_data[current_material]
# 查找精确匹配的值
lambda_np = lambda_
n_exact = material_df.loc[material_df['L'] == lambda_np, 'n'].values
k_exact = material_df.loc[material_df['L'] == lambda_np, 'k'].values
if n_exact.size > 0 and k_exact.size > 0:
n_value = n_exact[0]
k_value = k_exact[0]
else:
# 使用插值来估算
n_value = np.interp(lambda_np, material_df['L'], material_df['n'])
k_value = np.interp(lambda_np, material_df['L'], material_df['k'])
return n_value, k_value
def get_nk(material, lambda_):
N, K = get_refractive_index_and_extinction_coefficient(material, lambda_)
return N + 1j * K
# 根据TMM库做计算
def cacular_T_new(Material_combination, thick_combination, Lambda_Min, Lambda_Max):
materials = ['Air'] + Material_combination + ["GaSb"]
thicknesses = [np.inf] + thick_combination + [np.inf]
# 入射角度
theta_inc = 0
# 波长范围
wavelengths = np.linspace(Lambda_Min, Lambda_Max, 100)
# 初始化结果列表
T = []
R = []
A = []
# 计算不同波长下的透射率
for wavelength in wavelengths:
# 获取各层材料在当前波长下的复折射率
n_list = [get_nk(material, wavelength) for material in materials]
# 将cupy数组转换为np数组
n_list = np.array([np.asarray(n.get()) if isinstance(n, cp.ndarray) else n for n in n_list])
thicknesses = np.array([np.asarray(d.get()) if isinstance(d, cp.ndarray) else d for d in thicknesses])
# 使用TMM计算透射率
try:
result = coh_tmm('s', n_list, thicknesses, theta_inc, wavelength)
T.append(result['T'])
R.append(result['T'])
A.append(result['T'])
except ValueError as e:
print(f"Error in TMM calculation at wavelength {wavelength}: {e}")
continue
return T, R, A
def calculate_Transmittance_average(Material_combination, thick_combination, Lambda_Min, Lambda_Max):
sum_T = cacular_T_new(Material_combination, thick_combination, Lambda_Min, Lambda_Max)[0]
# 计算均值
numpy_mean = np.mean(sum_T)
# 计算总体方差
population_variance = np.var(sum_T)
return numpy_mean, population_variance
# 定义适应度函数
def fitness_function(thick_combination):
# 引入目标函数,将厚度列表作为变量
avg_transmittance, var_transmittance = calculate_Transmittance_average(Material_combination, thick_combination,
Lambda_Min, Lambda_Max)
fitness = avg_transmittance - var_transmittance * 5
return fitness
# 初始化种群
def init_population(pop_size, individual_size):
# 生成包含pop_size个个体,每个个体有individual_size个均匀分布的随机数(最小,最大,数量)
return [[max(cp.random.uniform(0.001, 1.0).tolist(), 0.001) for _ in range(individual_size)] for _ in
range(pop_size)]
# 评估种群
def evaluate_population(population):
# population为不同厚度列表的个体组成的种群
return cp.array([fitness_function(individual) for individual in population]) # 计算种群的个体适应度
# 选择操作(轮盘赌选择)
def select(population, fitnesses, k):
# fitnesses = fitnesses - cp.min(fitnesses) # 确保所有适应度值为非负数
fitnesses[fitnesses <= 0] = 0.0001 # 将所有负数设为0
# 从种群中选取k个体,并规定每个个体被选中的概率
selected_indices = cp.random.choice(len(population), size=k, replace=True, p=fitnesses / cp.sum(fitnesses))
return [population[int(i)] for i in selected_indices] # 用选出来的个体替换原本种群中的个体
# 交叉操作
def crossover(parent1, parent2, crossover_rate):
if random.random() < crossover_rate:
# 随机选择交叉点
crossover_points = random.sample(range(len(parent1)), random.randint(1, len(parent1) - 1))
child1 = parent1.copy()
child2 = parent2.copy()
for point in crossover_points:
child1[point] = parent2[point]
child2[point] = parent1[point]
return child1, child2
else:
return parent1, parent2
# 变异操作
def mutate(individual, mutation_rate, mutation_step):
for i in range(len(individual)):
if random.random() < mutation_rate:
individual[i] += cp.random.uniform(-mutation_step, mutation_step)
individual[i] = max(individual[i], 0.001) # 保证值大于0.01
return individual
# 遗传算法主函数
def genetic_algorithm(pop_size, individual_size, generations, crossover_rate, mutation_rate, mutation_step):
# 包含个体数量,个体元素数量,迭代次数,交叉概率,变异概率
population = init_population(pop_size, individual_size)
best_individual = None
best_fitness = -float('inf')
last_three_max_fitness = deque(maxlen=3) # 判断迭代缓急
last_six_max_fitness = deque(maxlen=6) # 判断迭代缓急
last_eight_max_fitness = deque(maxlen=8) # 判断迭代缓急
mutation_rate_new = mutation_rate
stream = cp.cuda.Stream()
for gen in range(generations):
with stream:
fitness_list = evaluate_population(population)
stream.synchronize()
max_fitness = cp.max(fitness_list)
if max_fitness > best_fitness:
best_fitness = max_fitness
best_individual = population[int(cp.argmax(fitness_list))]
last_three_max_fitness.append(best_individual)
last_six_max_fitness.append(best_individual)
last_eight_max_fitness.append(best_individual)
# 实时调整变异率
if len(last_three_max_fitness) > 3 and abs(last_three_max_fitness[2] - last_three_max_fitness[0]) < 1e-7:
mutation_rate_new = 0.4
if len(last_six_max_fitness) > 6 and abs(last_six_max_fitness[5] - last_six_max_fitness[0]) < 1e-7:
mutation_rate_new = 0.8
if len(last_eight_max_fitness) > 8 and abs(last_eight_max_fitness[7] - last_eight_max_fitness[0]) < 1e-7:
mutation_rate_new = 1
if len(last_three_max_fitness) > 3 and abs(last_eight_max_fitness[3] - last_eight_max_fitness[0]) > 1e-6:
mutation_rate_new = 0.25
new_population = []
for _ in range(pop_size // 2):
parents = select(population, fitness_list, 2)
offspring1, offspring2 = crossover(parents[0], parents[1], crossover_rate)
new_population.append(mutate(offspring1, mutation_rate_new, mutation_step))
new_population.append(mutate(offspring2, mutation_rate_new, mutation_step))
population = new_population
# print(f"Generation {gen}: Best Fitness = {best_fitness}")
print("当前平均透射率:", calculate_Transmittance_average(Material_combination, best_individual,
Lambda_Min, Lambda_Max))
# 将cupy数组转换为普通Python列表
best_individual = [float(x) for x in best_individual]
best_fitness = float(best_fitness)
print("当前平均透射率:", calculate_Transmittance_average(Material_combination, best_individual,
Lambda_Min, Lambda_Max))
return best_individual, best_fitness
folder_path = 'G:\Good_Good_Study\Python_wl\MARCs\MARCS_GRU+Self-Attention Mechanism\计算数据'
if __name__ == "__main__":
# 参数设置
Material_combination = ["MgF2", "SiO2", "ZnSe", "SiO2", "MgF2"]
Lambda_Min = 0.8
Lambda_Max = 3
# 遗传算法参数
pop_size = 200 # 群体中个体数量
individual_size = len(Material_combination) # 个体元素数量
generations = 200 # 迭代次数
crossover_rate = 0.65 # 交叉概率
mutation_rate = 0.25 # 变异概率
mutation_step = 0.02 # 变异步长
# 包含个体数量,个体元素数量,迭代次数,交叉概率,变异概率
results = []
pop_size_num = [50, 500, 1000]
generations_num = [100] # 迭代次数
for pop_size in pop_size_num:
st_time02 = time.time()
for i in range(10): # 重复次数
for generations in generations_num:
best_thick_combination, best_fitness = genetic_algorithm(pop_size, individual_size, generations,
crossover_rate,
mutation_rate, mutation_step)
best_avg, best_var = calculate_Transmittance_average(Material_combination,
best_thick_combination,
Lambda_Min, Lambda_Max)
results.append({
"pop_size": pop_size,
"Generations": generations,
"Best Thickness Combination": best_thick_combination,
"Best Fitness": best_fitness,
"best_avg": best_avg,
"best_var": best_var
})
print(
f"种群:{pop_size},迭代次数:{generations},第{i}次重复: 优化后的平均透射率 = {best_avg},离散度 = {best_var}")
print(f"膜层厚度:{best_thick_combination}")
end_time01 = time.time()
print("单次迭代时长:", end_time01 - st_time02)
end_time02 = time.time()
print(f"种群{pop_size}求解时长:", end_time02 - st_time02)
df = pd.DataFrame(results)
Number_generations = '厚度多目标优化重复实验MgF2_SiO2_ZnS.xlsx'
output_path = os.path.join(folder_path, Number_generations)
df.to_excel(output_path, index=False)
# 保存结果到Excel文件
print(f"迭代结果已保存到 {folder_path}")
end_time03 = time.time()
print("程序总用时:", end_time03 - st_time01)