Python带约束的非线性优化问题求解求助(Gekko适用?)
带约束的非线性加权最小化问题求解(Python实现)
问题明确
给定观测数据 $x_1, x_2, ..., x_n$、固定目标值 $B$ 和容差 $E$,求解参数 $a_0, a_1, a_2$:
- 目标函数:最小化 $\sum_{i=1}^n w_i^2$,其中 $w_i = \exp(a_0 + a_1 x_i + a_2 x_i^2)$
- 约束条件:
- $\sum_{i=1}^n w_i = n$($w_i$ 的均值为1)
- $B - E \leq \frac{1}{n}\sum_{i=1}^n w_i x_i \leq B + E$(加权均值与目标值的偏差在容差范围内)
Python 实现(基于Gekko)
Gekko适合处理这类带约束的非线性优化问题,以下是可直接运行的示例代码:
import numpy as np from gekko import GEKKO # ---------------------- 模拟输入数据(可替换为你的真实数据) ---------------------- n = 50 # 样本量 x = np.random.normal(loc=5, scale=2, size=n) # 模拟观测数据 B = 6.0 # 目标加权均值 E = 0.1 # 容差 # ---------------------- 初始化Gekko模型 ---------------------- m = GEKKO(remote=False) # remote=False表示本地运行 # ---------------------- 定义优化变量 a0, a1, a2 ---------------------- a0 = m.Var(value=0) # 初始值设为0,可根据实际调整 a1 = m.Var(value=0) a2 = m.Var(value=0) # ---------------------- 计算每个样本的w_i ---------------------- w = [m.exp(a0 + a1 * xi + a2 * xi**2) for xi in x] # ---------------------- 设置目标函数:最小化sum(w_i^2) ---------------------- m.Obj(sum(wi**2 for wi in w)) # ---------------------- 添加约束条件 ---------------------- # 约束1:sum(w_i) = n m.Equation(sum(w) == n) # 约束2:加权均值在[B-E, B+E]范围内 weighted_mean = sum(wi * xi for wi, xi in zip(w, x)) / n m.Equation(weighted_mean >= B - E) m.Equation(weighted_mean <= B + E) # ---------------------- 求解优化问题 ---------------------- m.options.SOLVER = 3 # 使用IPOPT求解器(适合非线性问题) m.solve(disp=True) # disp=True显示求解过程 # ---------------------- 输出结果 ---------------------- print("\n优化结果:") print(f"a0 = {a0.value[0]:.6f}") print(f"a1 = {a1.value[0]:.6f}") print(f"a2 = {a2.value[0]:.6f}") # ---------------------- 验证约束条件 ---------------------- w_values = np.exp(a0.value[0] + a1.value[0] * x + a2.value[0] * x**2) sum_w = np.sum(w_values) weighted_mean_calc = np.sum(w_values * x) / n print("\n约束验证:") print(f"sum(w_i) = {sum_w:.4f} (目标值:{n})") print(f"加权均值 = {weighted_mean_calc:.4f} (目标范围:[{B-E:.4f}, {B+E:.4f}])") print(f"目标函数值 sum(w_i^2) = {np.sum(w_values**2):.4f}")
关键说明
- 约束转换:将绝对值约束拆分为两个不等式约束,符合Gekko的等式/不等式约束定义规范。
- 求解器选择:使用IPOPT(Solver=3)是因为它擅长处理包含指数函数的非线性优化问题。
- 初始值:如果求解不收敛,可尝试调整
a0,a1,a2的初始值(比如根据数据分布设置合理初始值)。 - 数据替换:只需替换代码中
x,B,E的值为你的真实观测数据和参数即可。
内容的提问来源于stack exchange,提问作者Jonathan A
相关产品推荐
相关产品推荐

