📜  在A和B之间找到给定的非递减函数的根

📅  最后修改于: 2021-05-04 20:12:25             🧑  作者: Mango

给定三个形成单调递增函数的数字abc f(x)形式为a * x 2 + b * x + c以及两个数字AB ,任务是找到函数的根,即,找到x的值,使得f(x) = 0  其中A≤x≤B.

例子:

方法:以下是任何函数的图形表示f(x)

从上图可以看出,

  1. 每当f(A)* f(B)≤0时,表示函数的图将在该范围内的某处切割x轴,并表示某处存在使该函数的值为0的点,然后该图变为负y轴
  2. 如果f(A)* f(B)> 0 ,则表示在[A,B]范围内, f(A)f(B)的y值始终保持正值,因此它们从不切割x轴

因此,从上面的观察中,想法是使用二进制搜索来解决此问题。使用给定的[A,B]范围作为方程式根的上下限,可以通过对该范围进行二进制搜索来找出x 。步骤如下:

  1. 找到范围[A,B]的中间(例如mid )。
  2. 如果f(mid)* f(A)≤0为真,则搜索空间减小为[A,mid] ,因为在此段中发生了x轴切割。
  3. 其他搜索空间缩小为[mid,B]
  4. 根的最小可能值是高值刚好小于EPS (最小值〜10 -6 )+下限值时,即fabs(高–低)> EPS
  5. 打印根的值。

下面是上述方法的实现:

C++
// C++ program for the above approach 
#include  
using namespace std; 
#define eps 1e-6 
  
// Given function 
double func(double a, double b, 
            double c, double x) 
{ 
    return a * x * x + b * x + c; 
} 
  
// Function to find the root of the 
// given non-decreasing Function 
double findRoot(double a, double b, 
                double c, double low, 
                double high) 
{ 
    double x; 
  
    // To get the minimum possible 
    // answer for the root 
    while (fabs(high - low) > eps) { 
  
        // Find mid 
        x = (low + high) / 2; 
  
        // Search in [low, x] 
        if (func(a, b, c, low) 
                * func(a, b, c, x) 
            <= 0) { 
            high = x; 
        } 
  
        // Search in [x, high] 
        else { 
            low = x; 
        } 
    } 
  
    // Return the required answer 
    return x; 
} 
  
// Function to find the roots of the 
// given equation within range [a, b] 
void solve(double a, double b, double c, 
        double A, double B) 
{ 
  
    // If root doesn't exists 
    if (func(a, b, c, A) 
            * func(a, b, c, B) 
        > 0) { 
        cout << "No solution"; 
    } 
  
    // Else find the root upto 4 
    // decimal places 
    else { 
        cout << fixed 
            << setprecision(4) 
            << findRoot(a, b, c, 
                        A, B); 
    } 
} 
  
// Driver Code 
int main() 
{ 
    // Given range 
    double a = 2, b = -3, c = -2, 
        A = 0, B = 3; 
  
    // Function Call 
    solve(a, b, c, A, B); 
    return 0; 
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
  
class GFG{
      
static final double eps = 1e-6;
  
// Given function
static double func(double a, double b,
                   double c, double x)
{
    return a * x * x + b * x + c;
}
  
// Function to find the root of the
// given non-decreasing Function
static double findRoot(double a, double b,
                       double c, double low,
                       double high)
{
    double x = -1;
      
    // To get the minimum possible
    // answer for the root
    while (Math.abs(high - low) > eps)
    {
          
        // Find mid
        x = (low + high) / 2;
          
        // Search in [low, x]
        if (func(a, b, c, low) * 
            func(a, b, c, x) <= 0)
        {
            high = x;
        }
          
        // Search in [x, high]
        else
        {
            low = x;
        }
    }
      
    // Return the required answer
    return x;
}
  
// Function to find the roots of the
// given equation within range [a, b]
static void solve(double a, double b, double c,
                  double A, double B)
{
      
    // If root doesn't exists
    if (func(a, b, c, A) * func(a, b, c, B) > 0)
    {
        System.out.println("No solution");
    }
      
    // Else find the root upto 4
    // decimal places
    else 
    {
        System.out.format("%.4f", findRoot(
            a, b, c, A, B));
    }
}
  
// Driver Code
public static void main (String[] args)
{
      
    // Given range
    double a = 2, b = -3, c = -2,
           A = 0, B = 3;
             
    // Function call
    solve(a, b, c, A, B);
}
}
  
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
import math 
eps = 1e-6
  
# Given function
def func(a ,b , c , x):
  
    return a * x * x + b * x + c
  
# Function to find the root of the
# given non-decreasing Function
def findRoot( a, b, c, low, high):
  
    x = -1
      
    # To get the minimum possible
    # answer for the root
    while abs(high - low) > eps:
      
        # Find mid
        x = (low + high) / 2
          
        # Search in [low, x]
        if (func(a, b, c, low) * 
            func(a, b, c, x) <= 0):
            high = x
      
        # Search in [x, high]
        else:
            low = x
              
    # Return the required answer
    return x
  
# Function to find the roots of the
# given equation within range [a, b]
def solve(a, b, c, A, B):
  
    # If root doesn't exists
    if (func(a, b, c, A) * 
        func(a, b, c, B) > 0):
        print("No solution")
      
    # Else find the root upto 4
    # decimal places
    else:
        print("{:.4f}".format(findRoot(
              a, b, c, A, B)))
      
# Driver code
if __name__ == '__main__': 
  
    # Given range
    a = 2
    b = -3
    c = -2
    A = 0
    B = 3
              
    # Function call
    solve(a, b, c, A, B)
  
# This code is contributed by jana_sayantan


C#
// C# program for the above approach
using System;
  
class GFG{
      
static readonly double eps = 1e-6;
  
// Given function
static double func(double a, double b,
                   double c, double x)
{
    return a * x * x + b * x + c;
}
  
// Function to find the root of the
// given non-decreasing Function
static double findRoot(double a, double b,
                       double c, double low,
                       double high)
{
    double x = -1;
      
    // To get the minimum possible
    // answer for the root
    while (Math.Abs(high - low) > eps)
    {
          
        // Find mid
        x = (low + high) / 2;
          
        // Search in [low, x]
        if (func(a, b, c, low) * 
            func(a, b, c, x) <= 0)
        {
            high = x;
        }
          
        // Search in [x, high]
        else
        {
            low = x;
        }
    }
      
    // Return the required answer
    return x;
}
  
// Function to find the roots of the
// given equation within range [a, b]
static void solve(double a, double b, double c,
                  double A, double B)
{
      
    // If root doesn't exists
    if (func(a, b, c, A) * func(a, b, c, B) > 0)
    {
        Console.WriteLine("No solution");
    }
      
    // Else find the root upto 4
    // decimal places
    else
    {
        Console.Write("{0:F4}", findRoot(
            a, b, c, A, B));
    }
}
  
// Driver Code
public static void Main(String[] args)
{
      
    // Given range
    double a = 2, b = -3, c = -2,
           A = 0, B = 3;
              
    // Function call
    solve(a, b, c, A, B);
}
}
  
// This code is contributed by 29AjayKumar


输出:
2.0000

时间复杂度: O(log(B – A))
辅助空间: O(1)