java中的Bisection方法实现

时间:2014-09-21 05:43:15

标签: java

我正在实现用于求解java中的方程的二分法。我最初编码解决方案的预定义多项式方程x ^ 3 + 4x ^ 2-10。现在我正在推广用户输入的任何多项式的解。

我读了相应度数的系数。现在我只需要调整f()方法,以便我可以计算f(a),f(b)和f(c)。

// BISECTION METHOD IMPLEMENTATION IN JAVA
// This program uses bisection method to solve for x^3 + 4x^2 -10 = 0

package nisarg;
import java.util.Scanner;

public class BetterBisection {

   public static void main(String[] args) {
      double a, b, c; // a, b and c have the usual meaning
      double f_of_a, f_of_b; // f_of_a, f_of_b store values of f(a) and f(b)
                             // respectively
      int highest_degree;
      System.out.println("What is the highest degree of your polynomial? ");
      Scanner input = new Scanner(System.in);
      highest_degree = input.nextInt();
      for (int i = highest_degree; i >= 0; i--) {
         int coeff_deg_i;
         coeff_deg_i = poly_input(i);
         // System.out.println(coeff_deg_i);
      }
      // The following do-while loop keeps asking the user for a and b until
      // f(a)f(b) does not become negative
      do {
         a = input();
         b = input();
         if (f(a) * f(b) >= 0) {
            System.out
                  .println("Sorry the two numbers are not bracketing the root.  Please try again ");
         }
      } while (f(a) * f(b) >= 0);
      f_of_a = f(a);
      f_of_b = f(b);
      double root = bisectionMethod(f_of_a, f_of_b, a, b);
      System.out.println("Root is : " + root);
   }

   public static double input() { // Reads in the bracketing number i.e a and b
      Scanner input = new Scanner(System.in);
      System.out.println("Enter a bracketing number");
      return (input.nextDouble());
   }

   public static double f(double num) { // Calculates f(x) given x and returns
                                        // f(x)
      final int COEFF_DEG_3 = 1; // Coefficient of x^3
      final int COEFF_DEG_2 = 4; // Coefficient of x^2
      final int COEFF_DEG_0 = -10; // Coefficient of x^0
      return (COEFF_DEG_3 * Math.pow(num, 3) + COEFF_DEG_2 * Math.pow(num, 2) + COEFF_DEG_0
            * Math.pow(num, 0));
   }

   public static double bisectionMethod(double f_of_a, double f_of_b, double a,
         double b) { // Does the actual work of evaluating
      double c; // the root using the method of bisection.
      double f_of_c;
      final double TOLERANCE = 0.0001;
      while (Math.abs(a - b) > TOLERANCE) {
         c = (a + b) / 2;
         f_of_c = f(c);
         if (f_of_c * f(a) == 0 || f_of_c * f(b) == 0) {
            return c;
         } else if (f_of_c * f(a) > 0) {
            a = c;
         } else {
            b = c;
         }
      }
      return (a + b) / 2;
   }

   public static int poly_input(int degree) {
      System.out.println("Please enter coefficient for degree " + degree);
      Scanner input = new Scanner(System.in);
      int coefficient;
      coefficient = input.nextInt();
      return coefficient;
   }
}

3 个答案:

答案 0 :(得分:1)

您不能使用循环来定义变量。要么有12个显式变量:

public class global {
    public static int coeff_deg_1;
    public static int coeff_deg_2;
    public static int coeff_deg_3;
    // and so on...
}

或者定义一个包含12个元素的数组:

public class global {
    public static final int coeff_degs = new int[12];
}

答案 1 :(得分:0)

这是一个递归的:

public static double f(double x) {
            return (x*x*x)-4*x-10;
}
public static double RecursiveBisection(Function fct, final double left, final double right, final double tolerance) {
    double x = 0;
    double dx = 0;
    if ( Math.abs(right - left) < tolerance ) // base case
        return (left + right) / 2;
    else { // recursive case
        x = (left + right)/2;
        System.out.println("Root obtained: " + x);
        dx = right - left;
        System.out.println("Estimated error: " + dx);
        if ( fct.f(left) * fct.f(x) > 0 ) // on same side
            return RecursiveBisection (fct, x, right, tolerance);
        else // opposite side
            return RecursiveBisection(fct, left, x, tolerance);

    }
}

答案 2 :(得分:0)

import java.util.*;

public class Bisection {
    
    private static Scanner input = new Scanner(System.in);
    private static List<Double> coefficients = new ArrayList<>();
    
    private static double epsilon = 0.00000001; // precision.
    
    /**
     * Input the coefficients of the polynomial
     */
    private void inputPolynomial() {
        System.out.print("Enter the order of the polynomial: ");
        int order = input.nextInt();

        System.out.print("Enter the coefficient of terms of the function: ");

        while (order >= 0) {
            double value = input.nextDouble();
            coefficients.add(value);
            order--;
        }
    }

    /**
     * The function method to compute the value of the function given variable x
     * 
     * @param x
     * @return result of inputing variable x
     */
    private double function(double x) {
        double result = 0.0;
        for (int index = 0, order = coefficients.size()-1; index < coefficients.size(); order--, index++) {
            result += coefficients.get(index) * (Math.pow(x, order));
        }
        return result;
    }
    
    private void calculateRoot() {
        double a, b;
        // Ask user for a and b until f(a) * f(b) > 0
        do {
            System.out.print("Enter the start of the interval: ");
            a = input.nextDouble();
            System.out.print("Enter the end of the interval: ");
            b = input.nextDouble();
            
            if (function(a) * function(b) >= 0) {
                System.out.println("Sorry, the root is not within the 2 numbers.\nDo try again.");
            }
        } while(function(a)*function(b) >= 0);
        
        long startTime = System.nanoTime();
        double root = bisectionMethod(a, b);
        long timeUsed = System.nanoTime() - startTime;
        System.out.printf("\nThe root is: %.6f.\n", root);
        System.out.println("Time used is " + timeUsed/1000 + " milliseconds.");
    }
    
    private double bisectionMethod(double start, double end) {
        double middle = (start + end)/2.0;;
        
        while (Math.abs(start - end) > epsilon) {           
            //System.out.println("x: " + middle);
            
            if ((function(start) * function(middle) == 0.0) || (function(end) * function(middle) == 0.0)) {
                break;
            } else if (function(start) * function(middle) > 0.0) {
                start = middle;
            } else {
                end = middle;
            }   
            middle = (start + end)/2.0;
        }
        return middle;
    }
    
    public static void main(String[] args) {        
        Bisection bisection = new Bisection();
        bisection.inputPolynomial();
        bisection.calculateRoot();
    }
}