FUNC1 p = &inc; 变异为什么通不过

本文通过一个C语言示例程序介绍了函数参数传递的方法,包括按值传递和按引用传递的区别,并展示了如何使用typedef定义函数指针类型,以及如何在函数中使用这些类型进行操作。
 
 
#include <stdio.h>

int inc( int a )
{
	return ( ++a);
}

int multi( int *a, int *b, int *c )
{
	return ( *c = *a * *b );
}

typedef int(FUNC1) (int in);
typedef int(FUNC2)  (int*, int*,int *);

void show( FUNC2 fun, int arg1, int *arg2 )
{
	FUNC1 p = &inc;
	//int temp = inc( arg1 );
	int	 temp = p( arg1 );
	fun( &temp, &arg1,arg2 );
	printf( "%d\n", *arg2 );
}

main()
{
	int	a ;
	show( multi, 10, &a );
	return 0;

}

import time import math import numpy as np import matplotlib.pyplot as plt from scipy.spatial import ConvexHull from scipy.spatial.distance import cdist from scipy.stats import qmc # 全局字体设置,解决中文和特殊符号显示问题 plt.rcParams["font.family"] = ["SimHei", "Arial Unicode MS"] plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 # 1. 目标函数向量化:支持批量解输入(核心优化点1) def zdt1(x): """ZDT1测试函数(支持2D数组输入:n行×dim列)""" x = np.atleast_2d(x) # 确保输入是2D数组 n, dim = x.shape f1 = x[:, 0] # 所有解的第0维(批量取列) g = 1 + 9 * np.mean(x[:, 1:], axis=1) # 每行(每个解)的均值 h = 1 - np.sqrt(f1 / g) f2 = g * h return np.column_stack((f1, f2)) # 输出n行×2列 def zdt2(x): """ZDT2测试函数(支持批量解输入)""" x = np.atleast_2d(x) n, dim = x.shape f1 = x[:, 0] g = 1 + 9 * np.mean(x[:, 1:], axis=1) h = 1 - (f1 / g) ** 2 f2 = g * h return np.column_stack((f1, f2)) def zdt3(x): """ZDT3测试函数(支持批量解输入)""" x = np.atleast_2d(x) n, dim = x.shape f1 = x[:, 0] g = 1 + 9 * np.mean(x[:, 1:], axis=1) h = 1 - np.sqrt(f1 / g) - (f1 / g) * np.sin(10 * np.pi * f1) return np.column_stack((f1, g * h)) def zdt4(x): """严格修正的ZDT4实现""" x = np.atleast_2d(x) n, dim = x.shape f1 = x[:, 0] # 严格遵循原始论文公式 g = 1 + 10 * (dim - 1) + np.sum( x[:, 1:] ** 2 - 10 * np.cos(4 * np.pi * x[:, 1:]), axis=1 ) h = 1 - np.sqrt(f1 / g) f2 = g * h return np.column_stack((f1, f2)) def zdt6(x): """ZDT6测试函数(支持批量解输入)""" x = np.atleast_2d(x) n, dim = x.shape # ZDT6公式:f1 = 1 - exp(-4x1)sin^6(6πx1) f1 = 1 - np.exp(-4 * x[:, 0]) * (np.sin(6 * np.pi * x[:, 0])) ** 6 # g(x) = 1 + 9*(sum(x2~xd)/(d-1))^0.25 g = 1 + 9 * (np.sum(x[:, 1:], axis=1) / (dim - 1)) ** 0.25 # h = 1 - (f1/g)^2 h = 1 - (f1 / g) ** 2 f2 = g * h return np.column_stack((f1, f2)) # --------------------------- 新增:二维DTLZ1/2/3目标函数 --------------------------- def dtlz1(x): """ 二维DTLZ1测试函数(M=2目标,决策变量n=3) 特性:线性Pareto前沿、多模态 决策变量范围:x ∈ [0,1]^3 真实PF:f1 + f2 = 0.5(f1,f2 ≥ 0) """ x = np.atleast_2d(x) # 确保输入为2D数组(n行×3列) n, dim = x.shape assert dim == 3, "DTLZ1(二维目标)需输入3个决策变量(n=3)" # 向量化计算g(x),确保形状为(n,) g = 100 * ( 2 + # 3-2+1=2(n-M+1) (x[:, 2] - 0.5) ** 2 - np.cos(20 * np.pi * (x[:, 2] - 0.5)) ) # 目标函数计算(向量化操作,避免广播错误) f1 = 0.5 * x[:, 0] * x[:, 1] * (1 + g) f2 = 0.5 * (1 - x[:, 0]) * (1 + g) return np.column_stack((f1, f2)) def dtlz2(x): """ 二维DTLZ2测试函数(M=2目标,决策变量n=3) 特性:凸形Pareto前沿、非线性目标关联 决策变量范围:x ∈ [0,1]^3 真实PF:f1² + f2² = 1(f1,f2 ≥ 0) """ x = np.atleast_2d(x) # 确保输入为2D数组(n行×3列) n, dim = x.shape assert dim == 3, "DTLZ2(二维目标)需输入3个决策变量(n=3)" # 向量化计算g(x)(已正确实现,保持并优化注释) g = np.sum((x[:, 2] - 0.5) ** 2, axis=0) # 修正:对于单个变量无需axis=1,避免降维问题 # 目标函数计算 f1 = (1 + g) * np.cos(x[:, 0] * np.pi / 2) * np.cos(x[:, 1] * np.pi / 2) f2 = (1 + g) * np.cos(x[:, 0] * np.pi / 2) * np.sin(x[:, 1] * np.pi / 2) return np.column_stack((f1, f2)) def dtlz3(x): """ 二维DTLZ3测试函数(M=2目标,决策变量n=3) 特性:凸形Pareto前沿、强多模态 决策变量范围:x ∈ [0,1]^3 真实PF:f1² + f2² = 1(f1,f2 ≥ 0) """ x = np.atleast_2d(x) # 确保输入为2D数组(n行×3列) n, dim = x.shape assert dim == 3, "DTLZ3(二维目标)需输入3个决策变量(n=3)" # 向量化计算g(x),确保形状为(n,) g = 100 * ( 2 + # 3-2+1=2(n-M+1) (x[:, 2] - 0.5) ** 2 - np.cos(20 * np.pi * (x[:, 2] - 0.5)) ) # 目标函数计算(向量化操作) f1 = (1 + g) * np.cos(x[:, 0] * np.pi / 2) * np.cos(x[:, 1] * np.pi / 2) f2 = (1 + g) * np.cos(x[:, 0] * np.pi / 2) * np.sin(x[:, 1] * np.pi / 2) return np.column_stack((f1, f2)) def generate_true_front(func, num_points=1000): """ 生成ZDT测试函数真实Pareto前沿,包含ZDT6的实现 :param zdt_func: 目标函数(zdt1/zdt2/zdt3/zdt4/zdt6) :param num_points: 采样点数(越大越精确) :return: 真实前沿的(f1, f2)数组 """ # 以下为原有其他ZDT函数的处理逻辑,保持不变 f1 = np.linspace(0, 1, num_points) f2 = [] # --------------------------- 新增:DTLZ系列前沿生成 --------------------------- if func == dtlz1: # DTLZ1真实PF:f1 + f2 = 0.5(f1∈[0,0.5],f2=0.5-f1) f1 = np.linspace(0, 0.5, num_points) f2 = 0.5 - f1 elif func == dtlz2 or func == dtlz3: # DTLZ2/3真实PF:f1² + f2² = 1(f1∈[0,1],f2=√(1-f1²)) # 注:两函数PF形状相同,仅决策空间多模态差异 theta = np.linspace(0, np.pi / 2, num_points) # 极角(0~90°) f1 = np.cos(theta) f2 = np.sin(theta) if func == zdt1: for f in f1: f2_val = 1 - np.sqrt(f) f2.append(f2_val) elif func == zdt2: for f in f1: f2_val = 1 - f ** 2 f2.append(f2_val) elif func == zdt3: # ZDT3 真实前沿:g(x)=1(x2~xd=0),逐点计算并保留有效分段 for f in f1: g = 1.0 h = 1 - np.sqrt(f / g) - (f / g) * np.sin(10 * np.pi * f) f2_val = g * h # 仅保留物理意义有效的点(过滤极端异常值) if -1.5 <= f2_val <= 1.5: f2.append(f2_val) else: f2.append(np.nan) # 无效点标记为NaN elif func == zdt4: for f in f1: g_fixed = 1.0 # 固定g(x)=1 h = 1 - np.sqrt(f / g_fixed) f2_val = g_fixed * h f2.append(f2_val) elif func == zdt6: # ZDT6真实前沿生成:x2~xd=0时,g(x)=1 for x1 in np.linspace(0, 1, num_points): f1_val = 1 - np.exp(-4 * x1) * (np.sin(6 * np.pi * x1)) ** 6 g = 1.0 # x2~xd=0时g(x)=1 h = 1 - (f1_val / g) ** 2 f2_val = g * h f2.append(f2_val) f1 = [1 - np.exp(-4 * x1) * (np.sin(6 * np.pi * x1)) ** 6 for x1 in np.linspace(0, 1, num_points)] # 转换为numpy数组并过滤NaN f2 = np.array(f2) front = np.column_stack((f1[:len(f2)], f2)) # ZDT3 额外过滤被支配点,确保严格前沿 if func == zdt3: to_keep = np.ones(len(front), dtype=bool) for i in range(len(front)): f1_i, f2_i = front[i] for j in range(len(front)): if i == j: continue f1_j, f2_j = front[j] # 若点j支配点i,则过滤i if f1_j <= f1_i and f2_j <= f2_i and (f1_j < f1_i or f2_j < f2_i): to_keep[i] = False break front = front[to_keep] return front def calculate_igd(algorithm_front, true_front): """计算反向世代距离(IGD)""" if len(algorithm_front) == 0: return float('inf') distances = cdist(true_front, algorithm_front).min(axis=1) return np.mean(distances) def initialization(pop_size, dim, lb, ub): """优化版种群初始化:支持固定维度""" lb = np.array(lb) if not isinstance(lb, np.ndarray) else lb ub = np.array(ub) if not isinstance(ub, np.ndarray) else ub lb = np.repeat(lb, dim) if lb.size == 1 else lb ub = np.repeat(ub, dim) if ub.size == 1 else ub # 分离固定维度(上下界相等)和可采样维度 fixed_dims = lb == ub sample_dims = ~fixed_dims n_sample = np.sum(sample_dims) # 初始化种群(固定维度先设为lb值) population = np.full((pop_size, dim), lb) # 仅对可采样维度做LHS采样 if n_sample > 0: sampler = qmc.LatinHypercube(d=n_sample) samples = sampler.random(n=pop_size) # 映射到可采样维度的上下界 scaled_samples = qmc.scale( samples, lb[sample_dims], ub[sample_dims] ) population[:, sample_dims] = scaled_samples return population def Domination(X, FitX): N = X.shape[0] dominated_count = np.zeros(N, dtype=int) # 生成所有解对的支配关系矩阵(向量化比较) dominate_matrix = np.all(FitX[:, np.newaxis] <= FitX, axis=2) & np.any(FitX[:, np.newaxis] < FitX, axis=2) # 统计每个解被多少个其他解支配 dominated_count = np.sum(dominate_matrix, axis=0) # 筛选非支配解 mask = dominated_count == 0 return X[mask], FitX[mask] def crowding_distance(fitness): """计算每个解的拥挤距离""" n, m = fitness.shape if n <= 2: return np.ones(n) * np.inf # 解数量过少时,距离设为无穷大 crowd_dist = np.zeros(n) for j in range(m): sorted_idx = np.argsort(fitness[:, j]) # 按第j个目标排序 sorted_vals = fitness[sorted_idx, j] # 边界解距离设为无穷大(优先保留) crowd_dist[sorted_idx[0]] = np.inf crowd_dist[sorted_idx[-1]] = np.inf # 中间解计算距离 if sorted_vals[-1] != sorted_vals[0]: # 避免除零 crowd_dist[sorted_idx[1:-1]] += (sorted_vals[2:] - sorted_vals[:-2]) / (sorted_vals[-1] - sorted_vals[0]) return crowd_dist def crowding_distance_crop(X, FitX, L): """使用拥挤距离裁剪种群到大小L""" crowd_dist = crowding_distance(FitX) sorted_indices = np.argsort(-crowd_dist) # 按距离降序 return X[sorted_indices[:L], :], FitX[sorted_indices[:L], :] def UpdateArchive(NumObj, archive_size, A, FitA, X, FitX): """优化的存档更新函数""" A = np.atleast_2d(A) if len(A) > 0 else np.empty((0, X.shape[1])) FitA = np.atleast_2d(FitA) if len(FitA) > 0 else np.empty((0, NumObj)) X = np.atleast_2d(X) FitX = np.atleast_2d(FitX) if len(X) == 0: return A, FitA # 合并存档解和新解 combined_pop = np.vstack([A, X]) combined_fit = np.vstack([FitA, FitX]) total = len(combined_pop) # 向量化计算支配关系矩阵 dominate_matrix = ( np.all(combined_fit[:, np.newaxis] <= combined_fit, axis=2) & np.any(combined_fit[:, np.newaxis] < combined_fit, axis=2) ) # 计算每个解的被支配计数 dominated_count = np.sum(dominate_matrix, axis=0) # 筛选所有非支配解 non_dominated_mask = (dominated_count == 0) non_dominated_pop = combined_pop[non_dominated_mask] non_dominated_fit = combined_fit[non_dominated_mask] # 按拥挤距离裁剪到存档大小 if len(non_dominated_pop) > archive_size: non_dominated_pop, non_dominated_fit = crowding_distance_crop( non_dominated_pop, non_dominated_fit, archive_size ) return non_dominated_pop, non_dominated_fit def soft_rime_search(rimepop, A, FitA, it, max_iter, lb, ub, dim, W=5): """简化版软霜搜索函数""" if max_iter < 1: raise ValueError("max_iter不能小于1") N = rimepop.shape[0] new_rimepop = rimepop.copy() progress = it / max_iter # 迭代进度(0~1) # 软霜因子 rime_factor = (np.random.rand() - 0.5) * 2 * np.cos((np.pi * it / (max_iter / 5))) * ( 1 - np.round(it * W / max_iter) / W) # 阶段式参数 E = np.sqrt(progress) w = 1 / (1 + np.exp(-9 * (progress - 0.5))) # 引导解选择 if len(A) > 0: guides = A[np.random.choice(len(A), size=N)] else: guides = np.mean(rimepop, axis=0, keepdims=True).repeat(N, axis=0) # 位置更新 for i in range(N): global_guide = guides[i] for j in range(dim): if np.random.rand() < E: # 正向引导(向引导解方向) forward_dir = (1 + rime_factor) * (global_guide[j] - new_rimepop[i, j]) * np.random.rand() # 反向引导 if progress < 0.5: reverse_guide = lb[j] + ub[j] - new_rimepop[i, j] rev_strength = 1 + (1 - progress) * (1 + rime_factor) else: arch_mean = np.mean(A[:, j]) if len(A) > 0 else np.mean(rimepop[:, j]) reverse_guide = arch_mean * 2 - new_rimepop[i, j] rev_strength = 1 + (1 - progress) # 反向引导强度 reverse_dir = rev_strength * (reverse_guide - new_rimepop[i, j]) * (np.random.rand() * 2 - 1) new_rimepop[i, j] += (1 - w) * reverse_dir + w * forward_dir return np.clip(new_rimepop, lb, ub) # 边界修正 def hard_rime_puncture(new_rimepop, A, FitA, objective_func, it, max_iter): """优化后的硬霜穿刺函数""" N, dim = new_rimepop.shape # 存档解太少时不穿刺,直接返回 if len(A) < 2: new_FitX = objective_func(new_rimepop) # 使用向量化目标函数 return new_rimepop, new_FitX # 计算新解的目标值(批量计算) new_FitX = objective_func(new_rimepop) # 向量化Pareto等级计算 def pareto_ranking(pop_fitness): n = len(pop_fitness) ranks = np.zeros(n, dtype=int) dominated_count = np.zeros(n, dtype=int) # 向量化构建支配关系矩阵 dominate_matrix = ( np.all(pop_fitness[:, np.newaxis] <= pop_fitness, axis=2) & np.any(pop_fitness[:, np.newaxis] < pop_fitness, axis=2) ) np.fill_diagonal(dominate_matrix, False) dominated_count = np.sum(dominate_matrix, axis=0) # 计算Pareto等级 current_rank = 1 while np.any(ranks == 0): mask = (dominated_count == 0) & (ranks == 0) if not np.any(mask): break ranks[mask] = current_rank # 向量化更新被支配计数(优化点) dominated_count[np.any(dominate_matrix[mask], axis=0)] -= 1 current_rank += 1 return ranks # 计算新解的Pareto等级 ranks = pareto_ranking(new_FitX) max_rank = np.max(ranks) if np.max(ranks) > 0 else 1 # 平衡触发概率 progress = it / max_iter progress_factor = 1 - progress ** 1.5 if max_rank > 1: normalized_ranks = (ranks - 1) / (max_rank - 1) else: normalized_ranks = np.zeros_like(ranks) trigger_prob = 0.4 + (normalized_ranks * 0.3) trigger_prob = trigger_prob * progress_factor trigger_prob = np.clip(trigger_prob, 0.1, 0.9) # 多样性引导解选择 crowd_dists = crowding_distance(FitA) sorted_indices = np.argsort(-crowd_dists) guide_count = max(3, int(10 - 7 * progress)) top_guides = A[sorted_indices[:guide_count]] # 交叉穿刺 for i in range(N): if np.random.rand() < trigger_prob[i]: idx1, idx2 = np.random.choice(len(top_guides), 2, replace=False) guide1, guide2 = top_guides[idx1], top_guides[idx2] for j in range(dim): if np.random.rand() < 0.5: new_rimepop[i, j] = guide1[j] else: new_rimepop[i, j] = guide2[j] # 重新评估穿刺后的解(批量计算) new_FitX = objective_func(new_rimepop) return new_rimepop, new_FitX # 2. 替换低效的双重循环(mask生成优化,核心优化点2) def update_population(combined_pop, combined_fit, N, gen, Maxgen, Xmin, Xmax): """种群更新:筛选非支配解+对被支配解执行云变异后补充""" # 1. 筛选非支配解 non_dominated_pop, non_dominated_fit = Domination(combined_pop, combined_fit) nd_size = len(non_dominated_pop) if nd_size >= N: # 非支配解充足时,按拥挤距离选择 crowd_nd = crowding_distance(non_dominated_fit) sorted_nd_idx = np.argsort(-crowd_nd) return non_dominated_pop[sorted_nd_idx[:N]] else: # 2. 提取被支配解(需补充的解) remaining = N - nd_size mask = np.zeros(len(combined_pop), dtype=bool) for i, pop in enumerate(combined_pop): for nd_pop in non_dominated_pop: if np.allclose(pop, nd_pop, atol=1e-6): mask[i] = True break other_pop = combined_pop[~mask] # 被支配解 other_fit = combined_fit[~mask] # 3. 对被支配解按拥挤距离排序 if len(other_pop) == 0: # 极端情况:重复选择非支配解 selected = np.random.choice(nd_size, remaining, replace=True) supplementary = non_dominated_pop[selected] else: crowd_other = crowding_distance(other_fit) sorted_other_idx = np.argsort(-crowd_other) selected_other = other_pop[sorted_other_idx[:remaining]] # 4. 对选中的被支配解执行云变异 mutated_supplementary = [] for idx in range(len(selected_other)): mutated = cloud_mutation( X=selected_other, n=idx, gen=gen, Maxgen=Maxgen, Xmin=Xmin, Xmax=Xmax, is_non_dominated=False ) mutated_supplementary.append(mutated) supplementary = np.array(mutated_supplementary) # 5. 组合非支配解和变异后的补充解 return np.vstack([non_dominated_pop, supplementary]) def cloud_mutation(X, n, gen, Maxgen, Xmin, Xmax, is_non_dominated): """优化版云变异""" D = X.shape[1] progress = gen / Maxgen # 差异化变异概率 if is_non_dominated: pm = 0.3 - 0.2 * progress else: pm = 0.8 - 0.4 * progress pm = np.clip(pm, 0.05, 0.95) if np.random.rand() >= pm: return X[n, :].copy() # 差异化变异维度数量 if is_non_dominated: dim_ratio = 0.2 - 0.1 * progress dim_count = max(1, int(dim_ratio * D)) else: dim_ratio = 0.6 - 0.3 * progress dim_count = max(1, int(dim_ratio * D)) mutate_dims = np.random.choice(D, dim_count, replace=False) # 动态调整En y = X[n, :].copy() for i in mutate_dims: Ex = X[n, i] dim_std = np.std(X[:, i]) norm_std = dim_std / ((Xmax[i] - Xmin[i]) / 2 + 1e-10) base_En = (Xmax[i] - Xmin[i]) / (10 * np.sqrt(gen + 1)) En = base_En * (1.2 - 0.8 * norm_std) En = max(En, 1e-10) He = En / 10 Enn = np.random.normal(En, He) Enn = max(abs(Enn), 1e-10) CloudDrp_pos = np.random.normal(Ex, abs(Enn)) CloudDrp_certainty = np.exp(-(CloudDrp_pos - Ex) ** 2 / (2 * Enn ** 2)) adjusted_pos = Ex + (CloudDrp_pos - Ex) * CloudDrp_certainty y[i] = np.clip(adjusted_pos, Xmin[i], Xmax[i]) return y def MORIME_zdt(N, max_iter, lb, ub, dim, objective_func, archive_size, NumObj=2): """多目标霜冰优化算法(适配ZDT测试函数)""" start_time = time.time() # 初始化种群 rimepop = initialization(N, dim, lb, ub) # 计算初始种群的目标函数值(批量计算) FitX = objective_func(rimepop) # 初始化存档 A, FitA = Domination(rimepop, FitX) # 防御性检查 if A.size == 0: rimepop = initialization(N, dim, lb, ub) FitX = objective_func(rimepop) A, FitA = Domination(rimepop, FitX) # 主循环 for it in range(max_iter): if it % 10 == 0: print(f"迭代次数: {it + 1}/{max_iter}") # 阶段1:软霜搜索 new_rimepop = soft_rime_search(rimepop, A, FitA, it, max_iter, lb, ub, dim) # 阶段2:硬霜穿刺 new_rimepop, new_FitX = hard_rime_puncture(new_rimepop, A, FitA, objective_func, it, max_iter) # 更新存档 A, FitA = UpdateArchive(NumObj, archive_size, A, FitA, new_rimepop, new_FitX) # 更新种群 combined_pop = np.vstack([new_rimepop, A]) combined_fit = np.vstack([new_FitX, FitA]) # 调用修改后的种群更新函数 rimepop = update_population( combined_pop, combined_fit, N, gen=it, Maxgen=max_iter, Xmin=lb, Xmax=ub ) # 重新计算种群目标值(批量计算) FitX = objective_func(rimepop) run_time = time.time() - start_time return A, FitA, run_time def plot_results(FitA, true_front, name, igd_value, plot_hull=False): """绘制ZDT函数的Pareto前沿对比图""" plt.figure(figsize=(10, 6)) # 绘制真实帕累托前沿 plt.plot(true_front[:, 0], true_front[:, 1], 'b-', lw=2, label='真实帕累托前沿') # 绘制算法得到的非支配解 plt.scatter(FitA[:, 0], FitA[:, 1], c='red', s=50, edgecolors='k', alpha=0.7, label='算法求得的非支配解') # 可选绘制凸包 if plot_hull and len(FitA) > 2: try: hull = ConvexHull(FitA) for simplex in hull.simplices: plt.plot(FitA[simplex, 0], FitA[simplex, 1], 'g--', lw=1, alpha=0.5) except: pass # 图表设置(显示IGD值) plt.xlabel('目标函数 f1', fontsize=12) plt.ylabel('目标函数 f2', fontsize=12) plt.title(f'{name}函数的Pareto最优前沿对比(IGD={igd_value:.6f})', fontsize=14) plt.grid(alpha=0.3) plt.legend() plt.show() # 主函数:包含ZDT4边界修正(核心优化点3) def main(N=100, max_iter=100, archive_size=200): # 定义要测试的函数,包含ZDT系列和新增的DTLZ系列 functions = [ # ZDT系列函数 (函数, 名称, 决策变量维度) (zdt1, "ZDT1", 10), (zdt2, "ZDT2", 10), (zdt3, "ZDT3", 10), (zdt4, "ZDT4", 10), (zdt6, "ZDT6", 10), # 新增DTLZ系列函数 (函数, 名称, 决策变量维度) (dtlz1, "DTLZ1", 3), (dtlz2, "DTLZ2", 3), (dtlz3, "DTLZ3", 3) ] # 存储结果 results = {} # 循环运行每个测试函数 for func, name, dim in functions: print(f"\n======================================") print(f"========== {name} 优化开始 ==========") print(f"======================================\n") # 设置各函数的边界 if name == "ZDT4": # ZDT4原始定义:x1∈[0,1], x2~xd∈[-5,5] lb = np.zeros(dim) ub = np.ones(dim) lb[1:] = -5.0 # 第2到第d维下界为-5 ub[1:] = 5.0 # 第2到第d维上界为5 elif name.startswith("ZDT"): # 其他ZDT函数:所有维度∈[0,1] lb = np.zeros(dim) ub = np.ones(dim) else: # DTLZ系列 # DTLZ1/2/3所有维度∈[0,1] lb = np.zeros(dim) ub = np.ones(dim) # 运行优化算法 A, FitA, run_time = MORIME_zdt( N, max_iter, lb, ub, dim, func, archive_size ) # 生成真实帕累托前沿 true_front = generate_true_front(func) # 计算IGD值 igd_value = calculate_igd(FitA, true_front) # 保存结果 results[name] = { 'solutions': A, 'fitness': FitA, 'run_time': run_time, 'igd': igd_value, 'true_front': true_front } # 打印结果统计 print(f"\n========== {name} 优化结果 ==========") print(f"算法运行时间: {run_time:.2f}秒") print(f"找到的非支配解数量: {len(FitA)}") print(f"IGD值: {igd_value:.6f}") # 绘制结果 plot_results(FitA, true_front, name, igd_value, plot_hull=False) # 打印所有IGD值对比 print("\n======================================") print("各函数的IGD值对比:") for func_name, res in results.items(): print(f"{func_name}: {res['igd']:.6f}") print("======================================") return results if __name__ == "__main__": results = main() 请你检查我的DTLZ函数是否编写错误,为什么这三个函数的图像都很差
08-19
C:\Users\1\PycharmProjects\pythonProject1\.venv\Scripts\python.exe C:\Users\1\PycharmProjects\pythonProject1\2.2text.py 正在加载数据... 成功加载 1082 条有效数据 训练Y染色体浓度预测模型... 模型训练成功 使用遗传算法优化BMI分组和最佳时点... Gen 0: 最小风险=2846.1, 平均风险=8124.8, 最大风险=20839.1 Gen 1: 最小风险=2846.1, 平均风险=4675.0, 最大风险=13469.3 Gen 2: 最小风险=2846.1, 平均风险=3304.1, 最大风险=5719.7 Gen 3: 最小风险=2846.1, 平均风险=3038.7, 最大风险=3368.7 Gen 4: 最小风险=2846.1, 平均风险=2957.1, 最大风险=3124.9 Gen 5: 最小风险=2846.1, 平均风险=2901.3, 最大风险=2973.5 检测到早熟收敛,在第5代增强变异 Gen 6: 最小风险=2846.1, 平均风险=2858.8, 最大风险=2973.5 Gen 7: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 8: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 9: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 10: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第10代增强变异 Gen 11: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 12: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 13: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 14: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 15: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第15代增强变异 Gen 16: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 17: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 18: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 19: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 20: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第20代增强变异 Gen 21: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 22: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 23: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 24: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 25: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第25代增强变异 Gen 26: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 27: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 28: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 29: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 30: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第30代增强变异 Gen 31: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 32: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 33: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 34: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 35: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第35代增强变异 Gen 36: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 37: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 38: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 39: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 40: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第40代增强变异 Gen 41: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 42: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 43: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 44: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 45: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第45代增强变异 Gen 46: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 47: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 48: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 49: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 50: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第50代增强变异 Gen 51: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 52: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 53: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 54: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 55: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第55代增强变异 Gen 56: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 57: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 58: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 59: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 60: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第60代增强变异 Gen 61: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 62: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 63: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 64: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 65: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第65代增强变异 Gen 66: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 67: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 68: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 69: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 70: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第70代增强变异 Gen 71: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 72: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 73: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 74: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 75: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第75代增强变异 Gen 76: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 77: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 78: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 79: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 80: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第80代增强变异 Gen 81: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 82: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 83: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 84: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 85: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第85代增强变异 Gen 86: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 87: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 88: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 89: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 90: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第90代增强变异 Gen 91: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 92: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 93: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 94: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 95: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 检测到早熟收敛,在第95代增强变异 Gen 96: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 97: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 98: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 Gen 99: 最小风险=2846.1, 平均风险=2846.1, 最大风险=2846.1 优化成功!
最新发布
11-01
import pandas as pd import numpy as np import random from deap import base, creator, tools, algorithms import matplotlib.pyplot as plt import xgboost as xgb from sklearn.preprocessing import PolynomialFeatures from scipy.optimize import minimize import functools # 1. 数据准备与第一问模型 def load_and_preprocess_data(filepath): """加载并预处理NIPT数据(仅男胎)""" df = pd.read_excel(filepath, sheet_name=0) df = df.dropna(subset=['孕妇BMI', '检测孕周_天数', 'Y染色体浓度']) df['孕妇BMI'] = pd.to_numeric(df['孕妇BMI'], errors='coerce') df['检测孕周_天数'] = pd.to_numeric(df['检测孕周_天数'], errors='coerce') df['Y染色体浓度'] = pd.to_numeric(df['Y染色体浓度'], errors='coerce') df = df.dropna(subset=['孕妇BMI', '检测孕周_天数', 'Y染色体浓度']) # 确保数据类型正确 df = df.astype({ '孕妇BMI': 'float32', '检测孕周_天数': 'float32', 'Y染色体浓度': 'float32' }) return df def train_concentration_model(df): """训练Y染色体浓度预测模型""" X = df[['孕妇BMI', '检测孕周_天数']].values.astype('float32') y = df['Y染色体浓度'].values.astype('float32') poly = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly.fit_transform(X) model = xgb.XGBRegressor( n_estimators=150, learning_rate=0.05, max_depth=4, random_state=42 ) model.fit(X_poly, y) return model, poly def predict_tau(model, poly, bmi, target_concentration=4.0): """预测达到目标浓度所需的最早时间""" def objective(week): """目标函数""" week_val = week[0] if isinstance(week, (list, np.ndarray)) else week # 创建正确形状的输入数据 X = np.array([[bmi, week_val]], dtype='float32') X_poly = poly.transform(X) pred_concentration = model.predict(X_poly)[0] # 惩罚过早检测 if week_val < 70: return 1000 + (70 - week_val) return abs(pred_concentration - target_concentration) try: res = minimize(objective, x0=np.array([90]), bounds=[(70, 175)], method='Powell') return res.x[0] if res.success else 90 except: return 90 # 2. 修复toolbox未定义问题 class GAOptimizer: def __init__(self, df, tau_pred_func): self.df = df self.tau_pred_func = tau_pred_func self.setup_ga() def setup_ga(self): """初始化遗传算法框架""" creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) creator.create("Individual", list, fitness=creator.FitnessMin) self.toolbox = base.Toolbox() # 个体生成函数 bmi_min, bmi_max = self.df['孕妇BMI'].min(), self.df['孕妇BMI'].max() def create_individual(): cuts = sorted([random.uniform(bmi_min + 1, bmi_max - 1) for _ in range(4)]) times = [random.uniform(80, 150) for _ in range(5)] return cuts + times self.toolbox.register("individual", tools.initIterate, creator.Individual, create_individual) self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) # 使用functools绑定参数 self.toolbox.register("evaluate", self.calculate_risk) # 注册遗传算子 self.toolbox.register("mate", self.cxSimulatedBinaryBounded) self.toolbox.register("mutate", self.mutate_individual, indpb=0.2) self.toolbox.register("select", tools.selTournament, tournsize=3) def feasible(self, individual): """确保个体参数在合理范围内""" cuts = sorted(individual[:4]) times = individual[4:] # BMI切点范围 bmi_min, bmi_max = self.df['孕妇BMI'].min(), self.df['孕妇BMI'].max() cuts = [np.clip(c, bmi_min + 1, bmi_max - 1) for c in cuts] times = [np.clip(t, 70, 175) for t in times] return sorted(cuts) + times def calculate_risk(self, individual): """计算适应度(风险)""" individual = self.feasible(individual) cuts = sorted(individual[:4]) times = individual[4:] # 创建分组边界 bins = [self.df['孕妇BMI'].min() - 0.1] + cuts + [self.df['孕妇BMI'].max() + 0.1] group_labels = np.digitize(self.df['孕妇BMI'], bins) - 1 total_risk = 0 for i, row in self.df.iterrows(): group = group_labels[i] if group >= len(times) or group < 0: group = min(len(times) - 1, max(0, group)) t_k = times[group] try: tau_i = self.tau_pred_func(row['孕妇BMI']) except: tau_i = 100 # 延误检测风险 if t_k > tau_i: if tau_i <= 84: w = 0.1 elif tau_i <= 119: w = 0.5 else: w = 1.0 risk = w * (t_k - tau_i) # 提前检测损失 else: risk = np.log(1 + abs(tau_i - t_k)) total_risk += risk return (total_risk,) def cxSimulatedBinaryBounded(self, ind1, ind2, eta=15.0): """交叉算子""" child1 = self.feasible(ind1) child2 = self.feasible(ind2) # BMI切点交叉 for i in range(4): if random.random() > 0.5: continue x1, x2 = child1[i], child2[i] beta = random.uniform(0.8, 1.2) new_x1 = 0.5 * (x1 + x2) * beta new_x2 = 0.5 * (x1 + x2) * (2 - beta) child1[i] = new_x1 child2[i] = new_x2 # 时点基因交叉 for i in range(4, 9): if random.random() > 0.5: continue x1, x2 = child1[i], child2[i] beta = random.uniform(0.9, 1.1) new_val = 0.5 * (x1 + x2) * beta child1[i] = new_val child2[i] = new_val return self.feasible(child1), self.feasible(child2) def mutate_individual(self, individual, indpb=0.2): """变异算子""" ind = self.feasible(individual) for i in range(len(ind)): if random.random() < indpb: if i < 4: # BMI切点变异 ind[i] += random.gauss(0, 0.5) else: # 时点变异 ind[i] += random.gauss(0, 3) return (self.feasible(ind),) def optimize(self, ngen=50, pop_size=100): """执行优化""" pop = self.toolbox.population(n=pop_size) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values[0]) stats.register("avg", np.mean) stats.register("min", np.min) # 逐步执行进化 logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + stats.fields for gen in range(ngen): # 选择下一代 offspring = self.toolbox.select(pop, len(pop)) offspring = [self.toolbox.clone(ind) for ind in offspring] # 交叉 for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < 0.7: child1[:], child2[:] = self.toolbox.mate(child1, child2) # 变异 for mutant in offspring: if random.random() < 0.2: mutant[:] = self.toolbox.mutate(mutant)[0] # 评估 invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = self.toolbox.map(self.toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # 更新种群 pop[:] = offspring # 更新名人堂 hof.update(pop) # 记录统计 record = stats.compile(pop) logbook.record(gen=gen, nevals=len(invalid_ind), **record) print(f"Gen {gen}: 最小风险={record['min']:.1f}, 平均风险={record['avg']:.1f}") # 提取最优解 best = hof[0] cuts = sorted(best[:4]) times = best[4:] return cuts, times, logbook # 3. 结果可视化 def visualize_results(df, cuts, times): """可视化优化结果""" # 创建BMI分组 bins = [df['孕妇BMI'].min()] + cuts + [df['孕妇BMI'].max()] df['BMI组'] = pd.cut(df['孕妇BMI'], bins, labels=[f'组{i + 1}' for i in range(5)]) plt.figure(figsize=(15, 8)) # BMI分组分布 plt.subplot(221) plt.hist(df['孕妇BMI'], bins=30, alpha=0.7, color='skyblue') for cut in cuts: plt.axvline(cut, color='r', linestyle='--', linewidth=1.5) plt.title('BMI分组分布') plt.xlabel('BMI') plt.grid(alpha=0.3) # 最佳检测时点 plt.subplot(222) group_names = [f"分组{i + 1}" for i in range(5)] plt.bar(group_names, times, color=['#4C72B0', '#55A868', '#C44E52', '#8172B2', '#CCB974']) plt.axhline(84, color='g', linestyle='--', label='12周(84天)') plt.axhline(119, color='orange', linestyle='--', label='17周(119天)') for i, time in enumerate(times): plt.text(i, time + 2, f'{time:.1f}天', ha='center') plt.title('各BMI组最佳检测时间') plt.ylabel('孕周(天)') plt.legend() plt.grid(alpha=0.3) # 分组孕妇数量 plt.subplot(223) group_counts = df['BMI组'].value_counts().sort_index() group_counts.plot(kind='bar', color='#4C72B0', alpha=0.8) plt.title('各分组孕妇数量分布') plt.xlabel('BMI分组') for i, count in enumerate(group_counts): plt.text(i, count + 5, str(count), ha='center') plt.grid(alpha=0.3) plt.tight_layout() plt.savefig('优化结果.png', dpi=300) plt.show() # 输出分组方案 print("\n===== 最优分组方案 =====") for i in range(5): lower = bins[i] upper = bins[i + 1] if i < 4 else df['孕妇BMI'].max() weeks = times[i] print(f"分组{i + 1}: BMI范围[{lower:.1f}-{upper:.1f}) → " f"最佳检测时间: {weeks // 7:.0f}周{weeks % 7:.0f}天 ({weeks:.1f}天)") return group_counts # 4. 主程序 if __name__ == "__main__": # 加载数据 data_path = r"C:\Users\1\Desktop\处理后结果.xlsx" print("正在加载数据...") try: df = load_and_preprocess_data(data_path) print(f"成功加载 {len(df)} 条有效数据") except Exception as e: print(f"数据加载失败: {str(e)}") exit() # 训练浓度预测模型 print("训练Y染色体浓度预测模型...") try: model, poly = train_concentration_model(df) print("模型训练成功") except Exception as e: print(f"模型训练失败: {str(e)}") exit() # 定义tau预测函数(带异常处理) def safe_tau_pred_func(bmi): try: return predict_tau(model, poly, bmi) except: return 100 # 使用封装类优化 print("使用遗传算法优化BMI分组和最佳时点...") try: optimizer = GAOptimizer(df, safe_tau_pred_func) cuts, times, log = optimizer.optimize(ngen=50, pop_size=100) print("优化成功!") except Exception as e: print(f"优化失败: {str(e)}") exit() # 结果可视化与输出 group_counts = visualize_results(df, cuts, times) print(f"\n各组孕妇数量:\n{group_counts}") print("优化完成!结果已保存为'优化结果.png'") 当前代码还需要生成分组后的散点图,不同的组需要用颜色区分,代码报错: C:\Users\1\PycharmProjects\pythonProject1\.venv\Scripts\python.exe C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py 正在加载数据... 成功加载 1082 条有效数据 训练Y染色体浓度预测模型... 模型训练成功 使用遗传算法优化BMI分组和最佳时点... Gen 0: 最小风险=2078.6, 平均风险=9220.4 Gen 1: 最小风险=2078.6, 平均风险=4444.1 Gen 2: 最小风险=2078.6, 平均风险=2694.8 Gen 3: 最小风险=2078.6, 平均风险=2236.8 Gen 4: 最小风险=2078.6, 平均风险=2110.5 Gen 5: 最小风险=2078.6, 平均风险=2085.4 Gen 6: 最小风险=2078.6, 平均风险=2079.2 Gen 7: 最小风险=2078.6, 平均风险=2078.6 Gen 8: 最小风险=2078.6, 平均风险=2078.6 Gen 9: 最小风险=2078.6, 平均风险=2078.6 Gen 10: 最小风险=2078.6, 平均风险=2078.6 Gen 11: 最小风险=2078.6, 平均风险=2078.6 Gen 12: 最小风险=2078.6, 平均风险=2078.6 Gen 13: 最小风险=2078.6, 平均风险=2078.6 Gen 14: 最小风险=2078.6, 平均风险=2078.6 Gen 15: 最小风险=2078.6, 平均风险=2078.6 Gen 16: 最小风险=2078.6, 平均风险=2078.6 Gen 17: 最小风险=2078.6, 平均风险=2078.6 Gen 18: 最小风险=2078.6, 平均风险=2078.6 Gen 19: 最小风险=2078.6, 平均风险=2078.6 Gen 20: 最小风险=2078.6, 平均风险=2078.6 Gen 21: 最小风险=2078.6, 平均风险=2078.6 Gen 22: 最小风险=2078.6, 平均风险=2078.6 Gen 23: 最小风险=2078.6, 平均风险=2078.6 Gen 24: 最小风险=2078.6, 平均风险=2078.6 Gen 25: 最小风险=2078.6, 平均风险=2078.6 Gen 26: 最小风险=2078.6, 平均风险=2078.6 Gen 27: 最小风险=2078.6, 平均风险=2078.6 Gen 28: 最小风险=2078.6, 平均风险=2078.6 Gen 29: 最小风险=2078.6, 平均风险=2078.6 Gen 30: 最小风险=2078.6, 平均风险=2078.6 Gen 31: 最小风险=2078.6, 平均风险=2078.6 Gen 32: 最小风险=2078.6, 平均风险=2078.6 Gen 33: 最小风险=2078.6, 平均风险=2078.6 Gen 34: 最小风险=2078.6, 平均风险=2078.6 Gen 35: 最小风险=2078.6, 平均风险=2078.6 Gen 36: 最小风险=2078.6, 平均风险=2078.6 Gen 37: 最小风险=2078.6, 平均风险=2078.6 Gen 38: 最小风险=2078.6, 平均风险=2078.6 Gen 39: 最小风险=2078.6, 平均风险=2078.6 Gen 40: 最小风险=2078.6, 平均风险=2078.6 Gen 41: 最小风险=2078.6, 平均风险=2078.6 Gen 42: 最小风险=2078.6, 平均风险=2078.6 Gen 43: 最小风险=2078.6, 平均风险=2078.6 Gen 44: 最小风险=2078.6, 平均风险=2078.6 Gen 45: 最小风险=2078.6, 平均风险=2078.6 Gen 46: 最小风险=2078.6, 平均风险=2078.6 Gen 47: 最小风险=2078.6, 平均风险=2078.6 Gen 48: 最小风险=2078.6, 平均风险=2078.6 Gen 49: 最小风险=2078.6, 平均风险=2078.6 优化成功! C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 20998 (\N{CJK UNIFIED IDEOGRAPH-5206}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 24067 (\N{CJK UNIFIED IDEOGRAPH-5E03}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 23381 (\N{CJK UNIFIED IDEOGRAPH-5B55}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 21608 (\N{CJK UNIFIED IDEOGRAPH-5468}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 22825 (\N{CJK UNIFIED IDEOGRAPH-5929}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 21508 (\N{CJK UNIFIED IDEOGRAPH-5404}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 26368 (\N{CJK UNIFIED IDEOGRAPH-6700}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 20339 (\N{CJK UNIFIED IDEOGRAPH-4F73}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 26816 (\N{CJK UNIFIED IDEOGRAPH-68C0}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 27979 (\N{CJK UNIFIED IDEOGRAPH-6D4B}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 26102 (\N{CJK UNIFIED IDEOGRAPH-65F6}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 38388 (\N{CJK UNIFIED IDEOGRAPH-95F4}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 22919 (\N{CJK UNIFIED IDEOGRAPH-5987}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:288: UserWarning: Glyph 37327 (\N{CJK UNIFIED IDEOGRAPH-91CF}) missing from font(s) DejaVu Sans. plt.tight_layout() C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 20998 (\N{CJK UNIFIED IDEOGRAPH-5206}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 24067 (\N{CJK UNIFIED IDEOGRAPH-5E03}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 23381 (\N{CJK UNIFIED IDEOGRAPH-5B55}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 21608 (\N{CJK UNIFIED IDEOGRAPH-5468}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 22825 (\N{CJK UNIFIED IDEOGRAPH-5929}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 21508 (\N{CJK UNIFIED IDEOGRAPH-5404}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 26368 (\N{CJK UNIFIED IDEOGRAPH-6700}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 20339 (\N{CJK UNIFIED IDEOGRAPH-4F73}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 26816 (\N{CJK UNIFIED IDEOGRAPH-68C0}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 27979 (\N{CJK UNIFIED IDEOGRAPH-6D4B}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 26102 (\N{CJK UNIFIED IDEOGRAPH-65F6}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 38388 (\N{CJK UNIFIED IDEOGRAPH-95F4}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 22919 (\N{CJK UNIFIED IDEOGRAPH-5987}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\PycharmProjects\pythonProject1\2.1满意.py:289: UserWarning: Glyph 37327 (\N{CJK UNIFIED IDEOGRAPH-91CF}) missing from font(s) DejaVu Sans. plt.savefig('优化结果.png', dpi=300) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 20998 (\N{CJK UNIFIED IDEOGRAPH-5206}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 32452 (\N{CJK UNIFIED IDEOGRAPH-7EC4}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 24067 (\N{CJK UNIFIED IDEOGRAPH-5E03}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 23381 (\N{CJK UNIFIED IDEOGRAPH-5B55}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 21608 (\N{CJK UNIFIED IDEOGRAPH-5468}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 22825 (\N{CJK UNIFIED IDEOGRAPH-5929}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 21508 (\N{CJK UNIFIED IDEOGRAPH-5404}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 26368 (\N{CJK UNIFIED IDEOGRAPH-6700}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 20339 (\N{CJK UNIFIED IDEOGRAPH-4F73}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 26816 (\N{CJK UNIFIED IDEOGRAPH-68C0}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 27979 (\N{CJK UNIFIED IDEOGRAPH-6D4B}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 26102 (\N{CJK UNIFIED IDEOGRAPH-65F6}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 38388 (\N{CJK UNIFIED IDEOGRAPH-95F4}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 22919 (\N{CJK UNIFIED IDEOGRAPH-5987}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 25968 (\N{CJK UNIFIED IDEOGRAPH-6570}) missing from font(s) DejaVu Sans. func(*args) C:\Users\1\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py:862: UserWarning: Glyph 37327 (\N{CJK UNIFIED IDEOGRAPH-91CF}) missing from font(s) DejaVu Sans. func(*args) ===== 最优分组方案 ===== 分组1: BMI范围[20.7-27.6) → 最佳检测时间: 20周4天 (144.1天) 分组2: BMI范围[27.6-31.6) → 最佳检测时间: 13周7天 (97.6天) 分组3: BMI范围[31.6-37.1) → 最佳检测时间: 15周3天 (108.0天) 分组4: BMI范围[37.1-45.9) → 最佳检测时间: 13周2天 (92.8天) 分组5: BMI范围[45.9-46.9) → 最佳检测时间: 14周2天 (100.4天) 各组孕妇数量: BMI组 组1 4 组2 510 组3 500 组4 62 组5 2 Name: count, dtype: int64 优化完成!结果已保存为'优化结果.png' 进程已结束,退出代码为 0
11-01
# ====== 2. NSGA-II核心实现 ====== def nsga2(pop_size=100, generations=100): # 初始化参数 n_var = 30 # 变量维度 pc, pm = 0.9, 1/n_var # 交叉/变异概率 eta_c, eta_m = 20, 20 # 分布指数 # 初始化种群 pop = np.random.rand(pop_size, n_var) for _ in range(generations): # 生成子代 offspring = crossover_mutation(pop, pc, pm, eta_c, eta_m) # 合并种群 combined = np.vstack((pop, offspring)) # 非支配排序 fronts = fast_non_dominated_sort(combined) # 拥挤度排序 new_pop = [] for front in fronts: if len(new_pop) + len(front) > pop_size: crowding_distances = crowding_distance(front) front = front[np.argsort(-crowding_distances)] new_pop += front[:pop_size - len(new_pop)].tolist() break else: new_pop += front.tolist() pop = np.array(new_pop) return pop # ====== 3. 核心操作实现 ====== def fast_non_dominated_sort(pop): # 实现快速非支配排序 S = [[] for _ in range(len(pop))] fronts = [[]] n = np.zeros(len(pop), dtype=int) rank = np.zeros(len(pop), dtype=int) # 计算支配关系 for i, p in enumerate(pop): for j, q in enumerate(pop): if all(zdt1(p) <= zdt1(q)) and any(zdt1(p) < zdt1(q)): S[i].append(j) elif all(zdt1(q) <= zdt1(p)) and any(zdt1(q) < zdt1(p)): n[i] += 1 if n[i] == 0: rank[i] = 0 fronts[0].append(p) # 构建前沿层 i = 0 while fronts[i]: next_front = [] for p in fronts[i]: for q in S[np.where((pop == p).all(axis=1))[0][0]]: n[q] -= 1 if n[q] == 0: rank[q] = i + 1 next_front.append(pop[q]) i += 1 fronts.append(next_front) return fronts[:-1] def crowding_distance(front): # 计算拥挤度 distances = np.zeros(len(front)) for obj in range(2): # 对每个目标函数排序 sorted_front = front[np.argsort([zdt1(ind)[obj] for ind in front])] distances[0] = distances[-1] = np.inf norm = zdt1(sorted_front[-1])[obj] - zdt1(sorted_front[0])[obj] if norm == 0: continue for i in range(1, len(front)-1): distances[i] += (zdt1(sorted_front[i+1])[obj] - zdt1(sorted_front[i-1])[obj]) / norm return distances # ====== 4. 遗传算子 ====== def crossover_mutation(pop, pc, pm, eta_c, eta_m): # 模拟二进制交叉和多项式变异 offspring = [] for _ in range(len(pop)//2): parents = pop[np.random.choice(len(pop), 2, replace=False)] if np.random.rand() < pc: # SBX交叉 beta = np.where(np.random.rand(*parents[0].shape) < 0.5, (2 * np.random.rand(*parents[0].shape))**(1/(eta_c+1)), (1/(2*(1 - np.random.rand(*parents[0].shape))))**(1/(eta_c+1))) c1 = 0.5 * ((1 + beta)*parents[0] + (1 - beta)*parents[1]) c2 = 0.5 * ((1 - beta)*parents[0] + (1 + beta)*parents[1]) else: c1, c2 = parents[0].copy(), parents[1].copy() # 多项式变异 for child in [c1, c2]: delta = np.where(np.random.rand(*child.shape) < pm, np.where(np.random.rand(*child.shape) < 0.5, (2*np.random.rand(*child.shape))**(1/(eta_m+1)) - 1, 1 - (2*(1 - np.random.rand(*child.shape)))**(1/(eta_m+1))), 0) child = np.clip(child + delta, 0, 1) offspring.extend([c1, c2]) return np.array(offspring) 将上述代码改为一个class类,以供后续调用
04-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值