You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scipy的differential_evolution函数时遇RuntimeError问题求助

使用Scipy differential_evolution时遇到RuntimeError的解决方法

问题描述

在完成大学课程参数化作业时,用Scipy的differential_evolution拟合五次多项式,出现错误:

RuntimeError: The map-like callable must be of the form f(func, iterable), returning a sequence of numbers the same length as 'iterable'

代码及错误栈如下:

原代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import differential_evolution

x = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
y = [0.0, 1.8, 2.0, 4.0, 4.0, 6.0, 4.0, 3.6, 3.4, 2.8, 0.0]

plt.plot(x, y, 'bo', markersize=3, label='Dados')
plt.legend()
plt.show()

def model_reta(x, c0, c1, c2, c3, c4, c5 ):
  return c0+c1*x+c2*pow(x,2)+c3*pow(x,3)+c4*pow(x,4)+c5*pow(x,5)

def model(params):
  sol = model_reta(x, params[0], params[1], params[2], params[3], params[4], params[5])

  erro = np.linalg.norm(y-sol, 1)/np.linalg.norm(y, 1)

  return [erro, sol, x]

def model_adj(x, args):
  result = model(x)
  return result[0]

bounds = [(-10, 10),(-10, 10),(-10, 10),(-10, 10),(-10, 10),(-10, 10),]

result = differential_evolution(model_adj, bounds, strategy='best1bin', disp=True)

完整错误栈

TypeError                                 Traceback (most recent call last)
File c:\Users\filip\AppData\Local\Programs\Python\Python311\Lib\site-packages\scipy\optimize\_differentialevolution.py:1146, in DifferentialEvolutionSolver._calculate_population_energies(self, population)
   1145 try:
-> 1146     calc_energies = list(
   1147         self._mapwrapper(self.func, parameters_pop[0:S])
   1148     )
   1149     calc_energies = np.squeeze(calc_energies)

File c:\Users\filip\AppData\Local\Programs\Python\Python311\Lib\site-packages\scipy\_lib\_util.py:360, in _FunctionWrapper.__call__(self, x)
    359 def __call__(self, x):
-> 360     return self.f(x, *self.args)

TypeError: model_adj() missing 1 required positional argument: 'args'

The above exception was the direct cause of the following exception:

RuntimeError                              Traceback (most recent call last)
d:\Scripts Python\atividade_integracao_numerica\integracao_numerica.ipynb Cell 9 line 1
     13   return result[0]
     15 bounds = [(-10, 10),(-10, 10),(-10, 10),(-10, 10),(-10, 10),(-10, 10),]
---> 17 result = differential_evolution(model_adj, bounds, strategy='best1bin', disp=True)
     18 '''
     19 print(result.x)
     20 erro, sol, x = model(result.x)
...
   1156     ) from e
   1158 if calc_energies.size != S:
   1159     if self.vectorized:

RuntimeError: The map-like callable must be of the form f(func, iterable), returning a sequence of numbers the same length as 'iterable'

错误原因

  1. 目标函数参数不符合要求:differential_evolution要求目标函数仅接受一个参数(待优化的系数数组),但model_adj定义了两个参数,且参数名x与全局数据变量重名,导致逻辑混淆。
  2. 冗余返回值干扰优化:model函数返回了误差、预测值、数据x三个元素,但优化过程只需要误差值作为目标输出,多余返回值破坏了优化逻辑。

修正后的代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import differential_evolution

# 原始数据,重命名避免与参数混淆
x_data = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
y_data = [0.0, 1.8, 2.0, 4.0, 4.0, 6.0, 4.0, 3.6, 3.4, 2.8, 0.0]

plt.plot(x_data, y_data, 'bo', markersize=3, label='Dados')
plt.legend()
plt.show()

# 五次多项式模型,直接接收系数数组
def model_poly(x, coeffs):
    c0, c1, c2, c3, c4, c5 = coeffs
    return c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + c5*x**5

# 优化目标函数:仅返回归一化L1误差
def objective_func(coeffs):
    y_pred = model_poly(x_data, coeffs)
    return np.linalg.norm(y_data - y_pred, 1) / np.linalg.norm(y_data, 1)

# 参数边界
bounds = [(-10, 10)] * 6

# 运行差分进化优化
result = differential_evolution(objective_func, bounds, strategy='best1bin', disp=True)

# 输出结果并绘制拟合曲线
print("优化得到的系数:", result.x)
y_fit = model_poly(x_data, result.x)

plt.plot(x_data, y_data, 'bo', markersize=3, label='Dados')
plt.plot(x_data, y_fit, 'r-', label='Ajuste')
plt.legend()
plt.show()

关键修改说明

  • 重命名全局数据变量为x_data、y_data,避免与函数参数冲突。
  • 简化多项式模型函数,直接接收系数数组作为参数,无需逐个拆解。
  • 目标函数仅返回误差值,完全符合differential_evolution的输入要求。
  • 移除冗余的中间函数,优化代码结构,逻辑更清晰。

内容的提问来源于stack exchange,提问作者Filipe Vidal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:33:26