问题描述
设 f1 和 f2 为 [a,b] 范围内的两个函数,maxerr 为所需的近似值。它们在这个范围内既可微又连续。我应该返回一个近似交集 Xs 的迭代,这样: ∀x∈Xs,|f_1(x) - f_2(x)|
例如函数的签名应该是:
def intersection(self,f1: callable,f2: callable,a: float,b: float,maxerr=0.001) -> callable:
注意事项:
现在我的代码如下:
def intersection_recursive(f1,f2,a,b,maxerr,X,start_time,timeout,side_flag):
f = f1 - f2
startX = a
endX = b
while not f(startX) * f(endX) < 0 and time.time() < start_time + timeout:
startX = random.uniform(a,b)
endX = random.uniform(startX,b)
mid = (startX + endX) / 2
while not abs(f(mid)) < maxerr and time.time() < start_time + timeout:
if f(startX) * f(mid) < -1:
endX = mid
else:
startX = mid
mid = (startX + endX) / 2
if abs(f(mid)) < maxerr:
X.append(mid)
else:
return X
if side_flag:
return intersection_recursive(f1,mid,not side_flag)
else:
return intersection_recursive(f1,not side_flag)
def intersection(self,maxerr=0.001) -> callable:
timeout = 10
X = []
start_time = time.time()
intersection_recursive(f1,True)
return X
解决方法
下面的答案是对原始问题的回答,其中没有对函数进行任何假设...
没有关于函数的任何额外信息,没有免费午餐定理适用,任何搜索策略都与其他任何策略一样有效。
也就是说,如果有足够的时间,simple quasirandom sequence 在每个细节级别统一覆盖所有 [a,b]
。
顺便说一下,我认为您的函数签名不正确,它应该返回一个可迭代对象。
from typing import Callable,Iterable
def intersection(f1: Callable[[float],float],f2: Callable[[float],a: float,b: float,maxerr: float=0.001) -> Iterable[float]:
a,b = sorted([a,b])
invphi = 2 / (1 + 5**0.5)
t = 0.5
while True:
x = a + (b-a)*t
if abs(f1(x) - f2(x)) < maxerr:
yield x
t = (t + invphi) % 1.0