如何使用PuLP最小化由自定义函数计算的整数参数目标值?
问题分析
你遇到的核心问题是PuLP作为线性/混合整数线性规划工具,无法直接处理黑箱非线性目标函数:
- PuLP的
LpVariable是抽象的符号变量,不是具体整数,不能直接传入需要实际整数的pandas rolling方法,这是报错的直接原因。 - 更关键的是,PuLP的求解器只能解析由决策变量线性组合构成的目标和约束,你的自定义
func_to_minimize属于黑箱函数(内部是pandas数据处理逻辑,无法转化为线性表达式),无法被PuLP直接识别。
可行解决方案
方案一:枚举所有整数参数组合(适合参数范围较小的场景)
你的参数范围非常有限:param1取2-10的整数,param2取2-20的整数,总共只有9×19=171种组合,完全可以暴力枚举所有可能,找到使目标值最小的参数集。
修改后的代码实现:
import pandas as pd class ComplexClass(): def __init__(self, path_data:str): d = {'col1': [i for i in range(100)], 'col2': [i**2 for i in range(100)]} self.df = pd.DataFrame(data=d) def eval_value(self, param: list): p1, p2 = param self.df['col3'] = self.df['col1'].rolling(window=p1).mean() self.df['col4'] = self.df['col2'].rolling(window=p2).mean() self.df['col5'] = self.df['col3']+self.df['col4'] return self.df['col5'].iloc[-1] path = './path2data/data.csv' my_class = ComplexClass(path_data=path) # 枚举所有可能的参数组合 min_value = float('inf') best_params = None for p1 in range(2, 11): for p2 in range(2, 21): current_value = my_class.eval_value([p1, p2]) if current_value < min_value: min_value = current_value best_params = [p1, p2] print(f"最优参数集: {best_params}") print(f"最小目标值: {min_value}")
方案二:使用黑箱优化工具(参数范围大时推荐)
如果后续参数范围扩大,枚举不再可行,建议使用专门处理黑箱优化的工具(如Optuna、Hyperopt),这类工具原生支持整数参数优化,且能高效搜索最优解,无需依赖线性规划的约束。
原代码失效原因
原代码中prob += func_to_minimize([x1, x2], my_class)的错误本质是:
x1和x2是PuLP的LpVariable对象,不是具体整数,无法作为rolling(window=...)的参数。- PuLP无法将你的自定义数据处理逻辑转化为求解器能识别的线性表达式,因此无法直接将黑箱函数作为目标函数。
内容的提问来源于stack exchange,提问作者Hedwin
相关产品推荐
相关产品推荐

