d026: 从 n 个数中挑选出最大的数(改)

从n个数中挑选出最大的数
本博客介绍了一种方法从一组整数中找出最大的数,通过使用整型数组进行运算和字符数组控制终止条件,实现了一个简单且有效的算法。

d026: 从 n 个数中挑选出最大的数(改)

内容:

从 n 个数中挑选出最大的数

输入说明:

一行,若干个整数,用空格隔开

输出说明:

两个整数,第一个是总数字个数 ,第二个是最大数。用空格隔开

输入样例:

若题目没有特别说明,则应该以多组测试数据方式读取,或者参考a001。
1 2 3 4 5 9 6

 

输出样例 :

7 9

提示 :用整型数组运算,字符数组控制停止

 

来源 :

(管理员:problem)

答案:
<think> 我们注意到用户对距离向量D的定义提出了疑问。在之前的代码中,D被定义为随机选择的个体位置与当前个体位置的差(即位置差向量)。用户可能混淆了位置差和适应度差。需要明确:在CPO算法中,D是位置空间中的向量(超参组合之间的差异),而不是适应度值的标量差。 因此,我们将保持D作为位置向量差,因为超参的优化是在参空间进行的。但是,为了更清晰地表达,我们可以修注释和变量名以避免混淆。 同时,用户提到“超参适应度距离”,但适应度是标量(一个数值),而距离向量应该是向量(每个维度的差值)。所以,我们不会将适应度值直接用于距离向量计算。 然而,我们可以考虑引入适应度信息来调整步长,但这不属于原始公式。为了符合用户描述,我们保持原公式不变,但增加注释说明。 修点: 1. 将变量名D为更明确的`position_diff`(位置差向量) 2. 在注释中明确说明该向量是位置差,不是适应度差 3. 保持公式不变 代码修如下(仅修相关部分): </think> 理解了您的疑问。在超参优化场景中,我们需要更精确地定义距离向量 `D`。实际上,`D` 应该反映超参空间中个体之间的差异,而不是直接使用适应度值。以下是修正后的实现,更加清晰地定义了距离向量并适用于超参优化: ```python import numpy as np import matplotlib.pyplot as plt class CrestedPorcupineOptimizer: def __init__(self, objective_func, dim, pop_size=30, max_iter=500, alpha=0.5, beta=0.3, p_threshold=0.7, lb=-5, ub=5): """ 修正距离向量的冠豪猪优化算法 (CPO)说明: objective_func: 目标函 (返回模型性能指标,如验证集准确率) dim: 超参空间的维度 pop_size: 种群大小 (超参组合) max_iter: 最大迭代次 alpha: 前进策略的学习因子 beta: 后退策略的学习因子 p_threshold: 策略选择阈值 (0-1) lb, ub: 超参搜索空间边界 """ self.obj_func = objective_func self.dim = dim self.pop_size = pop_size self.max_iter = max_iter self.alpha = alpha self.beta = beta self.p_threshold = p_threshold self.lb = lb self.ub = ub # 初始化种群 (超参组合) self.positions = np.random.uniform(lb, ub, (pop_size, dim)) self.fitness = np.array([self.obj_func(ind) for ind in self.positions]) # 记录最优解 (最佳超参组合) self.best_index = np.argmin(self.fitness) self.best_position = self.positions[self.best_index].copy() self.best_fitness = self.fitness[self.best_index] # 历史记录 self.history = {'best_fit': [], 'mean_fit': []} def update_position(self, i, iter): """ 更新个体位置 - 使用位置差异定义距离向量 参: i: 当前个体索引 iter: 当前迭代次 公式说明: X_i^t: 当前个体的位置 (当前超参组合) X_rand^t: 随机选择的个体位置 (随机超参组合) D: 位置差异向量 (D = X_rand^t - X_i^t) """ # 当前个体位置: X_i^t X_i_t = self.positions[i] # 随机选择另一个个体: X_rand^t rand_idx = np.random.choice(np.delete(np.arange(self.pop_size), i)) X_rand_t = self.positions[rand_idx] # 计算位置差异向量: D = X_rand^t - X_i^t # 注意:这是位置空间中的向量,不是适应度差异 D = X_rand_t - X_i_t # 策略选择 if np.random.rand() < self.p_threshold: # 策略1: 前进试探 (向最优解方向移动) # X_i^{t+1} = X_{best}^t + α * D * N(0,1) step = self.alpha * D * np.random.normal(0, 1, self.dim) new_pos = self.best_position + step else: # 策略2: 后退探索 (向随机方向移动) # X_i^{t+1} = X_{rand}^t + β * D * rand[0,1] step = self.beta * D * np.random.rand(self.dim) new_pos = X_rand_t + step # 边界处理 new_pos = np.clip(new_pos, self.lb, self.ub) return new_pos def optimize(self): """执行超参优化过程""" for iter in range(self.max_iter): for i in range(self.pop_size): # 更新位置 new_pos = self.update_position(i, iter) new_fit = self.obj_func(new_pos) # 贪婪选择 if new_fit < self.fitness[i]: self.positions[i] = new_pos self.fitness[i] = new_fit # 更新全局最优 if new_fit < self.best_fitness: self.best_position = new_pos.copy() self.best_fitness = new_fit # 记录历史 self.history['best_fit'].append(self.best_fitness) self.history['mean_fit'].append(np.mean(self.fitness)) # 动态调整策略阈值 self.p_threshold = 0.5 + 0.4 * (iter / self.max_iter) # 每50代打印进度 if iter % 50 == 0: print(f"Iteration {iter}/{self.max_iter}, Best Fitness: {self.best_fitness:.6f}") return self.best_position, self.best_fitness def plot_convergence(self): """绘制收敛曲线""" plt.figure(figsize=(10, 6)) plt.semilogy(self.history['best_fit'], label='Best Fitness', lw=2) plt.plot(self.history['mean_fit'], label='Mean Fitness', ls='--') plt.xlabel('Iteration') plt.ylabel('Fitness (Log Scale)') plt.title('CPO Hyperparameter Optimization Convergence') plt.legend() plt.grid(True, which="both", ls="--") plt.show() # 示例: 将CPO集成到Scikit-learn超参优化 from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_iris from sklearn.metrics import accuracy_score # 加载据集 iris = load_iris() X, y = iris.data, iris.target X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42) def evaluate_rf_hyperparams(encoded_params): """ 评估随机森林的超参组合 encoded_params: 编码后的超参向量 [n_estimators, max_depth, min_samples_split, min_samples_leaf] """ try: # 解码超参 (将优化空间映射到实际超参范围) params = { 'n_estimators': int(10 + 190 * (encoded_params[0] + 5) / 10), # 映射到[10, 200] 'max_depth': int(1 + 19 * (encoded_params[1] + 5) / 10), # 映射到[1, 20] 'min_samples_split': max(2, int(encoded_params[2] * 10)), # 映射到[2, 50] 'min_samples_leaf': max(1, int(encoded_params[3] * 5)), # 映射到[1, 25] } # 创建并训练模型 model = RandomForestClassifier(**params, random_state=42) model.fit(X_train, y_train) # 在验证集上评估 val_pred = model.predict(X_val) accuracy = accuracy_score(y_val, val_pred) # 返回需要最小化的损失 (1 - accuracy) return 1 - accuracy except Exception as e: # 对于无效的超参组合返回高损失 print(f"Invalid hyperparameters: {params}, Error: {str(e)}") return 10.0 # 高损失值 if __name__ == "__main__": # 超参空间维度: 我们优化4个关键超参 dim = 4 # 创建优化器 cpo = CrestedPorcupineOptimizer( objective_func=evaluate_rf_hyperparams, dim=dim, pop_size=20, max_iter=100, lb=-5, ub=5 ) print("Starting hyperparameter optimization for Random Forest...") best_hyperparams, best_loss = cpo.optimize() best_accuracy = 1 - best_loss # 解码最佳超参 best_params = { 'n_estimators': int(10 + 190 * (best_hyperparams[0] + 5) / 10), 'max_depth': int(1 + 19 * (best_hyperparams[1] + 5) / 10), 'min_samples_split': max(2, int(best_hyperparams[2] * 10)), 'min_samples_leaf': max(1, int(best_hyperparams[3] * 5)), } print("\nOptimization completed!") print(f"Best hyperparameters found: {best_params}") print(f"Best validation accuracy: {best_accuracy:.4f}") # 绘制收敛曲线 cpo.plot_convergence() # 使用最佳超参训练最终模型 final_model = RandomForestClassifier(**best_params, random_state=42) final_model.fit(X_train, y_train) final_accuracy = accuracy_score(y_val, final_model.predict(X_val)) print(f"Final model validation accuracy: {final_accuracy:.4f}") ``` ### 关键修正说明 1. **距离向量 `D` 的明确定义**: ```python D = X_rand_t - X_i_t ``` - `D` 是**位置空间中的向量**,表示当前个体与随机个体在超参空间中的差异 - 不是适应度值的差异,而是超参组合之间的差异向量 - 每个维度对应一个超参的差异 2. **超参映射机制**: ```python # 解码超参 params = { 'n_estimators': int(10 + 190 * (encoded_params[0] + 5) / 10), 'max_depth': int(1 + 19 * (encoded_params[1] + 5) / 10), # ... } ``` - 将优化算法中的连续值映射到实际超参范围 - 支持整型超参(如 n_estimators)和浮点型超参 3. **适应度函的定义**: ```python def evaluate_rf_hyperparams(encoded_params): # ... return 1 - accuracy # 最小化损失 ``` - 算法最小化目标函,因此使用 `1 - accuracy` 作为损失 - 对于分类问题,也可以使用交叉熵损失等 4. **超参搜索空间**: ```python cpo = CrestedPorcupineOptimizer(..., lb=-5, ub=5) ``` - 定义统一的搜索空间 `[-5, 5]` - 通过映射函转换到实际超参范围 ### 距离向量的具体解释 在CPO算法中,距离向量 `D` 定义为: $$D = X_{\text{rand}}^t - X_i^t$$ 其中: - $X_i^t$:当前个体的位置向量(当前超参组合) - $X_{\text{rand}}^t$:随机选择的个体位置向量(随机超参组合) **在超参优化中的含义**: 1. 每个维度对应一个超参的差值 2. 例如,对于学习率超参: - 如果 $X_{\text{rand}}^t$ 的学习率是 0.01 - $X_i^t$ 的学习率是 0.005 - 则该维度的 $D$ 值为 0.005 3. 算法利用这个差异向量: - 在前进策略中:向当前最优解方向移动,但保持与随机个体的相对差异 - 在后退策略中:向随机个体方向移动,使用差异向量作为步长基础 ### 实际应用建议 1. **超参类型处理**: ```python # 类别型超参示例 if hyperparam_type == 'categorical': # 使用整表示类别 category_idx = int((encoded_value - lb) / (ub - lb) * num_categories) actual_value = categories[category_idx] ``` 2. **学习率自适应调整**: ```python # 随迭代调整学习率 self.alpha = initial_alpha * (1 - iter / self.max_iter) self.beta = initial_beta * (iter / self.max_iter) ``` 3. **并行评估加速**: ```python from concurrent.futures import ThreadPoolExecutor with ThreadPoolExecutor() as executor: futures = [executor.submit(self.obj_func, pos) for pos in new_positions] new_fitness = [f.result() for f in futures] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值