我有一个目标函数,我想对't‘最小化,在这个函数中,有一个从0到t的积分,必须考虑它的优化。但是,我不知道如何将这个积分包含到我的目标函数中。我用过simpy和simpy的图书馆,但它们似乎都没有用。这是我的代码:
Cf= 100;
Cp=50;
Eta=72.66585511711865;
Beta=1.18609324
def R(t):
return math.exp(-t/Eta)**Beta
def f(t):
return (Beta/(Eta**Beta))*t**(Beta-1)*(math.exp(-t/Eta)**Beta)
def M(t):
return t*f(t)
import sympy as sp
from scipy import *
import scipy.integrate
t = sp.Symbol('t')
Mt=t*(Beta/(Eta**Beta))*t**(Beta-1)*(sp.exp(-t/Eta)**Beta);
intM=sp.integrate(Mt,t)
print(intM)
def C(t):
return (Cp*R(t)+Cf*(1-R(t)))/(t*R(t)+ intM)
from scipy.optimize import minimize_scalar
res = minimize_scalar(C)
res
这给了我错误“TypeError:无法确定关系的真值”。在scipy.integrate.quad中,我不能将我的上限定义为t‘。另一方面,当我试图把sp.integrate输出放到目标函数时,它就不能工作了。如果你能帮忙我会很高兴的。谢谢。
发布于 2022-06-07 17:27:01
首先,您不能在优化例程中有一个不确定的积分,因为它被定义为一个常量。不是函数,而是一类函数。
但是看起来你的积分是一个确定的积分,你把它积分到某个虚拟变量上,比如说,t',从t'=0到t‘。所以这很好,你只需要这样做。
首先,让我们来做你的定积分:
intM = sp.integrate(Mt, (t, 0, t))
# second arg is variable of integration, lower bound, upper bound
# we can skip defining tprime, a mathematician would hate you for this but meh
这仍然取决于t
,所以现在让我们将它转换为一个数值函数:
intM_func = sp.lambdify(t, intM)
# note how you can do intM_func(3) and get a number
然后将intM_func(t)
而不是符号intM
添加到您的C
可最小化函数中,您应该可以这样做:)
适用于我的完整版本:
Cf = 100
Cp = 50
Eta = 72.66585511711865
Beta = 1.18609324
def R(t):
return math.exp(-t / Eta) ** Beta
def f(t):
return (Beta / (Eta**Beta)) * t ** (Beta - 1) * (math.exp(-t / Eta) ** Beta)
def M(t):
return t * f(t)
import sympy as sp
from scipy import *
import scipy.integrate
t = sp.Symbol("t")
Mt = t * (Beta / (Eta**Beta)) * t ** (Beta - 1) * (sp.exp(-t / Eta) ** Beta)
intM = sp.integrate(Mt, (t, 0, t))
intMfunc = sp.lambdify(t, intM)
print(intM)
import numpy as np
def C(t):
if t == 0: # dodge a division-by-zero bullet
return np.inf
return (Cp * R(t) + Cf * (1 - R(t))) / (t * R(t) + intMfunc(t))
from scipy.optimize import minimize_scalar
res = minimize_scalar(C)
print(res)
我得到了:
fun: 1.5407809938973502
message: '\nOptimization terminated successfully;\nThe returned value satisfies the termination criteria\n(using xtol = 1.48e-08 )'
nfev: 61
nit: 28
success: True
x: 2964.8614509894874
作为输出。
发布于 2022-06-07 21:17:35
我想“关闭”这是因为你没有给出完全的错误-用回溯。但你似乎得到了答案,所以我会尽量把错误集中在你给它的时候。
error " TypeError: cannot determine truth value of Relational" . in scipy.integrate.quad
这类似于numpy数组中常见的“歧义错误”。有些东西试图做一个简单的真/假操作,比如一个if
。The函数可能正在测试范围值是否处于正确的顺序。或者,错误可能发生在您的func
中。如果没有追溯,我们只能猜测,或者从先前的知识中推断出来。所以你很幸运有人已经熟悉了这些问题。别指望这个!
为了说明:
在isympy
会话中,考虑一个符号:
In [35]: x
和一个关系:
In [36]: x>0
In [37]: type(_)
Out[37]: sympy.core.relational.StrictGreaterThan
将该关系放在` `if:
In [38]: if x>0: print('yes')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [38], in <cell line: 1>()
----> 1 if x>0: print('yes')
File ~\anaconda3\lib\site-packages\sympy\core\relational.py:511, in Relational.__bool__(self)
510 def __bool__(self):
--> 511 raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
sympy
不能从关系表达式返回简单的真假。
同时使用sympy
和scipy
需要相当多的知识来了解两者的工作原理。在数字函数中以不起作用的方式使用渐近表达式太容易了。
这是丢失的追踪:
In [59]: res = minimize_scalar(C)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [59], in <cell line: 1>()
----> 1 res = minimize_scalar(C)
File ~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py:794, in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
792 return method(fun, args=args, bracket=bracket, bounds=bounds, **options)
793 elif meth == 'brent':
--> 794 return _minimize_scalar_brent(fun, bracket, args, **options)
795 elif meth == 'bounded':
796 if bounds is None:
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2396, in _minimize_scalar_brent(func, brack, args, xtol, maxiter, **unknown_options)
2393 brent = Brent(func=func, args=args, tol=tol,
2394 full_output=True, maxiter=maxiter)
2395 brent.set_bracket(brack)
-> 2396 brent.optimize()
2397 x, fval, nit, nfev = brent.get_result(full_output=True)
2399 success = nit < maxiter and not (np.isnan(x) or np.isnan(fval))
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2180, in Brent.optimize(self)
2177 def optimize(self):
2178 # set up for optimization
2179 func = self.func
-> 2180 xa, xb, xc, fa, fb, fc, funcalls = self.get_bracket_info()
2181 _mintol = self._mintol
2182 _cg = self._cg
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2154, in Brent.get_bracket_info(self)
2151 ### BEGIN core bracket_info code ###
2152 ### carefully DOCUMENT any CHANGES in core ##
2153 if brack is None:
-> 2154 xa, xb, xc, fa, fb, fc, funcalls = bracket(func, args=args)
2155 elif len(brack) == 2:
2156 xa, xb, xc, fa, fb, fc, funcalls = bracket(func, xa=brack[0],
2157 xb=brack[1], args=args)
File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2606, in bracket(func, xa, xb, args, grow_limit, maxiter)
2604 fa = func(*(xa,) + args)
2605 fb = func(*(xb,) + args)
-> 2606 if (fa < fb): # Switch so fa > fb
2607 xa, xb = xb, xa
2608 fa, fb = fb, fa
File ~\anaconda3\lib\site-packages\sympy\core\relational.py:511, in Relational.__bool__(self)
510 def __bool__(self):
--> 511 raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
因此,正如我所怀疑的,scipy
正在试图检查范围;
if (fa < fb): # Switch so fa > fb
C
被赋予一个简单的标量参数产生一个sympy
表达式--带有一个未求值的积分。
In [57]: C(1)
Out[57]:
你忘记给我们看的那个intM
:
In [60]: intM
Out[60]:
https://stackoverflow.com/questions/72535067
复制相似问题