/*********************************************/ /* 黄金分割法によるy=x^4+3x^3+2x^2+1の最小値 */ /* coded by Y.Suganuma */ /*********************************************/ import java.io.*; public class Test { public static void main(String args[]) throws IOException { double a, b, eps, x, val[] = new double [1]; int max, ind[] = new int [1]; a = -2.0; b = -1.0; eps = 1.0e-10; max = 100; Kansu kn = new Kansu(); x = kn.gold(a, b, eps, val, ind, max); System.out.println("x " + x + " val " + val[0] + " ind " + ind[0]); } } /****************/ /* 関数値の計算 */ /****************/ class Kansu extends Gold { double snx(double x) { double y = x * x * x * x + 3.0 * x * x * x + 2.0 * x * x + 1.0; return y; } } abstract class Gold { /************************************************/ /* 黄金分割法(関数の最小値) */ /* a,b : 初期区間 a < b */ /* eps : 許容誤差 */ /* val : 間数値 */ /* ind : 計算状況 */ /* >= 0 : 正常終了(収束回数) */ /* = -1 : 収束せず */ /* max : 最大試行回数 */ /* return : 結果 */ /************************************************/ abstract double snx(double x); double gold(double a, double b, double eps, double val[], int ind[], int max) { double f1, f2, fa, fb, tau, x = 0.0, x1, x2; int count; tau = (Math.sqrt(5.0) - 1.0) / 2.0; count = 0; ind[0] = -1; x1 = b - tau * (b - a); x2 = a + tau * (b - a); f1 = snx(x1); f2 = snx(x2); while (count < max && ind[0] < 0) { count += 1; if (f2 > f1) { if (Math.abs(b-a) < eps && Math.abs(b-a) < eps*Math.abs(b)) { ind[0] = 0; x = x1; val[0] = f1; } else { b = x2; x2 = x1; x1 = a + (1.0 - tau) * (b - a); f2 = f1; f1 = snx(x1); } } else { if (Math.abs(b-a) < eps && Math.abs(b-a) < eps*Math.abs(b)) { ind[0] = 0; x = x2; val[0] = f2; f1 = f2; } else { a = x1; x1 = x2; x2 = b - (1.0 - tau) * (b - a); f1 = f2; f2 = snx(x2); } } } if (ind[0] == 0) { ind[0] = count; fa = snx(a); fb = snx(b); if (fb < fa) { a = b; fa = fb; } if (fa < f1) { x = a; val[0] = fa; } } return x; } }