SymPy求解二元方程组触发NotImplementedError问题求助
问题详情
我有两组二元方程组(共4个方程),预期求解结果为:
- wI = 0.107 ∈ (a1, a2) ,y= 0.176
- wII = 0.123 ∈ (b1, b2) ,x= 0.877
针对每组方程组,我尝试了两种整理形式:一种是将等式整理为等于0的形式,另一种是整理为等于ww1/ww2的形式,但无论哪种方式,SymPy求解时都会抛出NotImplementedError,错误信息如下:
NotImplementedError('could not solve %s' % eq2)
以及具体的方程求解报错:
NotImplementedError: could not solve: -52**(4/5)2*(24/25)5*(19/25)ww2 + 580000000000000000000**(1/25)(1 - 2ww2)**(22/25)(-(4010**(19/25)ww2 - 9(100ww2 - 7)(22/25))/(20*5(19/25)(1 - 4ww2)(22/25) - 9*(100*ww2 - 7)(22/25)) + 1) + 2**(22/25)(9 - 50ww2)(22/25)(4010(19/25)ww2 - 9(100ww2 - 7)**(22/25))/(205**(19/25)(1 - 4ww2)(22/25) - 9*(100*ww2 - 7)(22/25))
我的代码
import nashpy as nash import numpy as np import math from sympy import symbols, Eq, solve a4 = 0.6 a3 = 0.242 a2 = 0.115 a1 = 0.043 b4 = 0.5 b3 = 0.25 b2 = 0.18 b1 = 0.07 alpha = 0.88 beta = alpha LambdaI = 2.25 LambdaII = LambdaI Mu = alpha Nu = alpha y,ww1=symbols('y ww1') eq3=Eq((y*pow((a4-ww1),alpha)+(1-y)*pow((a2-ww1),alpha)-ww1),0) eq4=Eq(((-1)*LambdaI*y*pow((ww1-a1),beta)+(1-y)*pow((a3-ww1),alpha)-ww1),0) print(solve((eq3,eq4), (y, ww1))) y,ww1=symbols('y ww1') eq3=Eq((y*pow((a4-ww1),alpha)+(1-y)*pow((a2-ww1),alpha)),ww1) eq4=Eq(((-1)*LambdaI*y*pow((ww1-a1),beta)+(1-y)*pow((a3-ww1),alpha)),ww1) print(solve((eq3,eq4), (y, ww1))) x,ww2=symbols('x ww2') eq5=Eq((x*pow((b3-ww2),Nu)-(-1)*LambdaII*(1-x)*pow((ww2-b1),Nu)),ww2) eq6=Eq((x*pow((b2-ww2),Nu)+(1-x)*pow((b4-ww2),Nu)),ww2) print(solve((eq5,eq6), (x, ww2))) x,ww2=symbols('x ww2') eq5=Eq((x*pow((b3-ww2),Nu)-(-1)*LambdaII*(1-x)*pow((ww2-b1),Nu)-ww2),0) eq6=Eq((x*pow((b2-ww2),Nu)+(1-x)*pow((b4-ww2),Nu)-ww2),0) print(solve((eq5,eq6), (x, ww2)))
解决方案
SymPy的solve函数主要针对符号可解的代数方程,你遇到的方程组包含非整数次幂(如0.88=22/25次方),属于非线性超越方程组,没有解析解,因此solve无法处理,抛出NotImplementedError。
针对这类问题,建议使用数值求解方法,比如用SciPy的root或fsolve函数,结合预期的解区间来迭代求解:
修改后的数值求解代码
import numpy as np from scipy.optimize import root # 定义参数 a4 = 0.6 a3 = 0.242 a2 = 0.115 a1 = 0.043 b4 = 0.5 b3 = 0.25 b2 = 0.18 b1 = 0.07 alpha = 0.88 beta = alpha LambdaI = 2.25 LambdaII = LambdaI Nu = alpha # 第一组方程组:求解y和ww1 def equations1(vars): y, ww1 = vars eq1 = y * (a4 - ww1)**alpha + (1 - y) * (a2 - ww1)**alpha - ww1 eq2 = -LambdaI * y * (ww1 - a1)**beta + (1 - y) * (a3 - ww1)**alpha - ww1 return [eq1, eq2] # 初始猜测值(基于预期结果) initial_guess1 = [0.176, 0.107] result1 = root(equations1, initial_guess1) print("第一组解:") if result1.success: y_sol, ww1_sol = result1.x print(f"wI = {ww1_sol:.3f}, y = {y_sol:.3f}") else: print("求解失败:", result1.message) # 第二组方程组:求解x和ww2 def equations2(vars): x, ww2 = vars eq1 = x * (b3 - ww2)**Nu + LambdaII * (1 - x) * (ww2 - b1)**Nu - ww2 # 修正原代码符号:-(-1)*LambdaII = +LambdaII eq2 = x * (b2 - ww2)**Nu + (1 - x) * (b4 - ww2)**Nu - ww2 return [eq1, eq2] # 初始猜测值(基于预期结果) initial_guess2 = [0.877, 0.123] result2 = root(equations2, initial_guess2) print("\n第二组解:") if result2.success: x_sol, ww2_sol = result2.x print(f"wII = {ww2_sol:.3f}, x = {x_sol:.3f}") else: print("求解失败:", result2.message)
说明
- 数值求解依赖初始猜测值,使用预期结果作为初始值能大幅提高求解成功率和精度。
- 修正了第二组方程中的符号错误:原代码
-(-1)*LambdaII等价于+LambdaII,确保方程与预期逻辑一致。 - SciPy的
root函数支持多种数值算法,默认使用hybrd算法,适合这类非线性方程组。
内容的提问来源于stack exchange,提问作者Typo

