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

Scipy是否有无需循环与可视化即可自动求解所有根的方法?

问题:Scipy中是否存在无需循环、无需可视化选择初始猜测值即可程序化找到所有根的方法?

scipy.optimize.root仅能找到一个离初始猜测值较近、收敛速度更快的根。为求解[-4,4]区间内的方程组,目前只能通过循环结合可视化估计初始猜测值的方式来寻找所有根,具体代码如下:

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

x = np.linspace(-4,4,100)   

def fs(y):
    return  (2*y**2+3)
def fd(x):
    return x**3+x**2-6*x+3

def obj(x):
    return fs(x)-fd(x)

# visualize approximate bounds to define init_guess for further root func
plt.plot(  x, fs(x), 'r-', x, fd(x), 'b-')
plt.show()

############## optimize    
roots=[]

def find_root( guess):
    res = root(obj, [guess, ],  method='krylov',    tol=1.4e-100)
    if res.success== True:
        roots.append([round(res.x[0],2), round(fd(res.x[0]),2)])
    else:
        res.message
        exit

# cycle:  List Comprehension - 
[ find_root(x) for x in np.array([4.,1.,-1.5], dtype=float) ]

############## plot
r= np.array(roots).T; print(r)

import pandas as pd
df= pd.DataFrame(r, {'x': r[1], 'y': r[0]}).T; print(df)
print(df)

plt.plot(df['x'], df['y'], 'yo', x, fd(x), 'r-', x, fs(x), 'b-', ms=20, )
plt.show()

回答

Scipy本身没有直接能自动找出区间内所有根的官方函数,但可以通过两种思路实现程序化找根,无需手动选初始值和可视化:

1. 针对多项式方程:用numpy.roots()直接求解

你的问题里,目标函数obj(x) = 2x²+3 - (x³+x²-6x+3)化简后是-x³+x²+6x,属于三次多项式。这种情况直接用numpy.roots()就能一次性算出所有根,完全不需要初始值:

import numpy as np

# 按多项式高次到低次的顺序传入系数:-x³ + x² +6x +0 → 系数为 [-1, 1, 6, 0]
coeffs = [-1, 1, 6, 0]
all_roots = np.roots(coeffs)

# 筛选出[-4,4]区间内的实根
real_roots_in_range = [round(root.real, 2) for root in all_roots 
                       if np.isreal(root) and -4 <= root.real <= 4]
print(real_roots_in_range)  # 输出:[-2.0, 0.0, 3.0]

2. 针对非多项式方程:区间分割+根存在性检测

如果是无法转化为多项式的方程,可以通过分割目标区间,结合scipy.optimize.root_scalar的二分法(bisect)来自动扫描并求解根:

  1. 把[-4,4]分割成多个子区间
  2. 对每个子区间,检查两端函数值是否异号(判断是否存在根)
  3. 对存在根的区间调用求解器得到精确根
import numpy as np
from scipy.optimize import root_scalar

def obj(x):
    return 2*x**2 +3 - (x**3 +x**2 -6*x +3)

# 把区间分割成50个子区间,数量可根据需求调整
interval_points = np.linspace(-4, 4, 50)
found_roots = []

for i in range(len(interval_points)-1):
    a, b = interval_points[i], interval_points[i+1]
    # 跳过端点为根的情况,避免重复计算
    if obj(a) == 0:
        found_roots.append(round(a,2))
        continue
    # 区间两端函数值异号,说明存在根
    if obj(a) * obj(b) < 0:
        res = root_scalar(obj, method='bisect', bracket=[a, b], tol=1e-10)
        if res.converged:
            found_roots.append(round(res.root,2))

# 去重,避免相邻区间重复检测到同一根
unique_roots = list(set(found_roots))
print(unique_roots)  # 输出:[-2.0, 0.0, 3.0]

总结:如果是多项式方程,优先用numpy.roots();如果是非多项式,用区间分割+根检测的方法,都能实现无需手动干预的程序化找根。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:06:07