c - 如何解决这个: two functions x = sin(x)/a

标签 c math binary-search

我尝试用不同的方式解这个方程,但没有成功:

求两个函数的点数。

f(x) = sin(x)  
y = a  

在给定的a。在这种情况下,我们可以说 a = 0.15

sin(x) = ax
= 0.15x
x = sin(x)/0.15

???

谁能帮忙解答一下这个问题吗?

这就是问题的原话:

编写一个 C 程序,读取值 a 并写出方程 sin(x) = a*x 的所有解(即根)

注意:该方程肯定有一个解:x = 0 。但是,对于 a 的低值,代表方程 y = a*x 的线足够接近水平线以多次穿过正弦波。您的程序应该计算并打印根的数量及其值。

提示:假设您要解方程 f(x) = 0 ,其中f(x)是连续函数。进一步假设您可以找到两个值 xlowxhigh这样f(xlow) < 0f(xhigh) > 0和函数 f(x)在这些值之间的某个位置仅穿过 x 轴一次。您可以继续使用所谓的“二分搜索”技术,如下所示:

  1. Estimate the solution x as x = (xlow + xhigh) / 2.0
  2. If |f(x)| < epsilon then print x as solution and exit; else
  3. If f(x) < 0 then substitute xlow = x else substitute xhigh = x
  4. Go to (1)

使用 epsilon = 0.001

最佳答案

You could proceed using the so called "binary search" technique

这是解决问题的关键。实际上它就是解决方案。让我画两个函数:

           f(x)   g(x)
            /    --
           /   --
          /  --
         / --
        /--
       -*
     --/
   -- /
 --  /

 ^                 ^
 |                 |
 xlow              xhigh

您有xlowxhigh作为对哪里 f(x) 的估计十字架g(x) 。在你的问题中,f(x) = axg(x) = sin(x) .

首先,让我们看看为什么 xlowxhigh做出一个好的估计。如果您注意到,请访问xlow ,我们有f(x) < g(x)并在 xhigh我们有f(x) > g(x) 。由于函数是连续的,因此在 f(x) == g(x) 之间存在某个点.

现在让我们看看 xlow 之间的中间点和xhigh :

           f(x)   g(x)
            /    --
           /   --
          /  --
         / --
        /--
       -*
     --/
   -- /
 --  /

 ^        ^        ^
 |        |        |
 xlow     xmid     xhigh

现在在xmid ,我们有f(x) > g(x) (在本例中)。所以:

f(xhigh) > g(xhigh)
f(xmid)  > g(xmid)
f(xlow)  < g(xlow)

xmid之间和xlow ,函数改变了big-ness-ship(换句话说,f(x) - g(x)改变了它的符号),那么答案肯定在xlow之间。和xmid (请注意, xmidxhigh 之间仍然可能存在偶数个解,但我们目前无法真正判断)。

所以,如果我们分配 xhigh = xmid ,我们会有:

       f(x)  g(x)
         /--
       -*
     --/
   -- /
 --  /

 ^        ^
 |        |
 xlow     xhigh

但这和之前的问题是一样的!只是我们将解的可能位置缩小了一半。重复我们有:

       f(x)  g(x)
         /--
       -*
     --/
   -- /
 --  /

 ^    ^    ^
 |    |    |
 xlow xmid xhigh

f(xhigh) < g(xhigh)
f(xmid)  > g(xmid)
f(xlow)  > g(xlow)

这次是f(x) - g(x)的标志xmid之间的变化和xhigh ,所以我们会这样做xlow = xmid切掉我们不感兴趣的范围的前半部分。我们得到:

       f(x)  g(x)
         /--
       -*
     --/

      ^    ^
      |    |
      xlow xhigh

同样的问题,只不过我们将解决方案可能的范围缩小了一半。

在 while 循环中重复此操作,会出现 |f(xmid) - g(xmid)| 的某个点。几乎为零(例如小于 0.000001(或 1e-6)(另请注意绝对值))。在这种情况下,我们停止搜索,并说那个特定的 xmid就是答案。 (请参阅 here 了解为什么我们不检查相等性,而是检查接近性)。

<小时/>

还有一个问题。对于您的特定功能,可能会有许多横截面。我们如何找到xlowxhigh ?好吧,我们想要范围 [xlow, xhigh]仅包含一种解决方案。因此我们可以逐步找到这些范围并找到它们之间的横截面。

假设a > 0 (以及 x > 0 的解决方案),图表如下所示:

                              ----- f(x) = ax
   _           _         __*__         _ g(x) = sin(x)
  / \         /_*___----- / \         /
 /   *____---*-  \       /   \       /
|---- |     |     |     |     |     |
      |     |     |     |     |     |
       \   /       \   /       \   /
        \_/         \_/         \_/

那么让我们看看解决方案在哪里。当然,这不是sin(x) < 0的地方。 。然后上[2kπ, 2kπ + π/2][2kπ + π/2, 2kπ + π]每个可能有一个解决方案。初始[0, π / 2]可能有也可能没有解决方案,具体取决于 a 。所以最安全的方法就是枚举所有这样的范围,计算f(x) - g(x)对于两者xlowxhigh并看看他们的标志。如果标志没有改变,就没有解决办法,我们可以继续前进。如果确实发生变化,我们将执行上面的二分搜索。

算法什么时候结束?我们知道g(x) = sin(x) <= 1我们知道 a > 0 , f(x) = ax总是在增加。所以当你有 f(xlow) > 1 ,那么肯定没有更多的解决方案了。

该算法将是:

Main Algorithm:
for k = 0,1,...
    xlow = 2kπ
    xhigh = 2kπ + π/2
    binary_search(xlow, xhigh)

    xlow = 2kπ + π/2
    xhigh = 2kπ + π
    binary_search(xlow, xhigh)

binary_search:
if axlow-sin(xlow) and axhigh-sin(xhigh) have the same sign
    return no result in this range
do
    xmid = (xhigh + xlow) / 2
    diff = axmid - sin(axmid)
    if diff and axlow-sin(xlow) have the same sign
        xlow = xmid
    else
        xhigh = xmid
while abs(diff) > epsilon
return xmid

对于 a < 0 的情况,解决方案类似(除了范围更改为 sin 周期的另一半)。顺便说一句,对于每个 x您在上面找到的,-x也是一个解决办法!

关于c - 如何解决这个: two functions x = sin(x)/a,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22377923/

相关文章:

c++ - #define 带有 L 标识符的语法

c - 为什么我的 scanf while 循环在使用换行符时不退出?

c++ - 指针递增递减语法差异

algorithm - 如何计算搜索图形的最小预期时间?

html - 选择可能无限的 child ​​列表的第 n 个 child

使用 char 数组的 C++ 二进制搜索

c - Arduino 和 EtherCard 库 - 将网站内容打印到串行

math - 投影 3D 网格的 2D 轮廓算法

python - 使用二进制搜索获取最接近值的索引

c# - 如何在 List<T>.BinarySearch 中有效地复制 ArrayList.BinarySearch?