引用这篇文章
实数 二元搜索也可以用于单调函数,其区域是实数集合。在reals上实现二进制搜索通常比在整数上容易,因为您不需要注意如何移动边界: binary_search( lo,hi,p):虽然我们选择不终止: mid = lo + (hi - lo) /2如果p( mid ) ==真: hi = mid mid: lo =mid return 由于实数集合是密集的,所以很明显,我们通常无法找到确切的目标值。然而,我们可以很快地找到一些x,使得f(x)在0和yes之间边界的某种容限内。我们有两种决定何时终止的方法:当搜索空间小于预定的界限(例如10-12)时终止,或者执行固定次数的迭代。在Topcoder上,您最好的选择是使用几百个迭代,这将给您最好的精度,而不需要太多的思考。100次迭代将使搜索空间减少到大约其初始大小的10-30,对于大多数(如果不是全部)问题来说,这应该足够了。 如果您需要尽可能少地进行迭代,则可以在间隔变小时终止,但尝试对边界进行相对比较,而不仅仅是绝对比较。这样做的原因是,双倍的精度永远不会超过15位小数位,所以如果搜索空间包含很大的数字(例如数十亿),那么绝对差就永远不会小于10-7。
最后一段建议做一个相对的比较,而不仅仅是一个绝对的比较。那是什么意思?
发布于 2022-01-10 18:49:26
最后一段解释了使用绝对差别的问题:
如果您需要尽可能少地进行迭代,则可以在间隔变小时终止,但尝试对边界进行相对比较,而不仅仅是绝对比较。这样做的原因是,双倍的精度永远不会超过15位小数位,所以如果搜索空间包含很大的数字(例如数十亿),那么绝对差就永远不会小于10-7。
a和b的绝对区别是
auto diff = std::abs(a - b);
if (diff < 0.00000001) break;由于浮点数只有有限的有效位数,而且绝对值很大,您可能永远看不到像1e-7这样小的绝对差。
相对差异并不取决于比较值的大小:
auto rel_diff = std::abs( a - b) / a;
if (rel_diff < 0.00000001) break;换句话说,通常情况下,以下计算结果为true:
double very_big_number = 100000000.0;
double very_small_number = 0.000000001;
auto ups = (very_big_number + very_small_number) == very_big_number;从两个大浮点数字中你可以有意义地预测的最小的差别是在它们的最后一个重要数字中,它的大小可能比例如1e-7大得多。
https://stackoverflow.com/questions/70657424
复制相似问题