#/*********************************************************** # goldsect.rb -- 黄金分割法 #***********************************************************/ def goldsect( a, b, tolerance, f ) r = 2 / (3 + Math::sqrt(5)) if (a > b); t = a; a = b; b = t; end t = r * (b - a); c = a + t; d = b - t fc = f.call(c); fd = f.call(d) while (true) if (fc > fd) a = c; c = d; fc = fd; d = b - r * (b - a) if (d - c <= tolerance); return c; end fd = f.call(d) else b = d; d = c; fd = fc; c = a + r * (b - a) if (d - c <= tolerance); return d; end fc = f.call(c) end end end TEST = true $count = 0 func = Proc.new do |x| # 最小化する関数 $count = 0 xmin = 0.314 value = (x - xmin) * (x - xmin) if TEST printf("%4d: f(%g) = %g\n", $count += 1, x, value) end value end printf("x = %g\n", goldsect(0, 1, 1e-6, func)) exit 0