Оптимизация методом Фибоначчи - C#
Формулировка задачи:
Есть что-то похожее на pascal.
program fibonacci;
uses crt;
const n_m=40;
type mas=array[1..n_m] of integer;
type funo=function (x:real):real;
var
a,b,e:real;
nom,n:integer;
s:mas;
procedure VvodIsxD_FC( var f:mas; var n:integer; var a,b,e:real);
var i:integer;
begin
writeln('Ввод исходных данных для метода Фибоначчи');
write('Задайте N (количество разбиений): ');
readln(n);
writeln('Количество разбиений N = ',n);
f[1]:=1;
f[2]:=2;
for i:=3 to n do
f[i]:=f[i-1]+f[i-2];
write('Задайте EPSILON (точность) : ');
readln(e);
writeln('Задайте интервал (a,b)');
readln(a,b);
writeln(a:12:8,', b = ',b:12:8);
end;
procedure Fibonach(z:funo; f:mas; n:integer; a,b,e:real);
var
k,i,p:integer;
f2,f4,x1,x2,x3,x4:real;
begin
writeln;
writeln('Нахождение минимума по методу Фибоначчи');
x1:=a;
x2:=a+((b-a)*f[n-1]+e)/f[n];
x3:=b;
f2:=z(x2);
writeln(' Текущий интервал');
k:=1;
writeln(x1:12:8,' ',x3:12:8);
repeat
x4:=x1-x2+x3;
f4:=z(x4);
if f4>f2 then
begin
if x2<x4 then
begin
x3:=x4;
writeln(x1:12:8,' ',x3:12:8);
end
else
begin
x1:=x4;
writeln(x1:12:8,' ',x3:12:8);
end;
end
else
begin
if x2<x4 then
begin
x1:=x2;
x2:=x4;
f2:=f4;
writeln(x1:12:8,' ',x3:12:8);
end
else
begin
x3:=x2;
x2:=x4;
f2:=f4;
writeln(x1:12:8,' ',x3:12:8);
end
end;
k:=k+1;
until k>n;
writeln;
writeln('Минимум найден по методу Фибоначчи');
write('Конечный интервал [');
writeln(x1:12:8,',',x3:12:8,' ]');
writeln('Значение функции F = ',f2:15:12);
end;
function q(x:real):real;
begin
q:=cos(x);
end;
begin
writeln('Нахождение оптимума по методу Фибоначчи');
VvodIsxD_FC(s,n,a,b,e);
Fibonach(q,s,n,a,b,e);
end.Решение задачи: «Оптимизация методом Фибоначчи»
textual
Листинг программы
static int F(int n)
{
int f, f1 =1, f2=1, m=0;
while (m < n - 1)
{
f = f1 + f2;
f1 = f2;
f2 = f;
++m;
}
return f1;
}
static double Fun(double x)
{
return (x * x * x * x / Math.Log(x)); //здесь может быть ваше уравнение
}
static void Fib(double a, double b, double eps)
{
double x1, x2, _x, xf1, xf2;
int k=0;
int N=0;
double fn1=1, fn2=1, fn, f = (b - a) / eps;
while (fn1 < f)
{
fn = fn1 + fn2;
fn1 = fn2;
fn2 = fn;
++N;
}
bool bix;
int ix = N & 1;
if (ix == 1)
bix = true;
else
bix = false;
x1 = a + (double)F(N - 2) / F(N) * (b - a) - (bix ? -1 : 1) * eps / F(N);
x2 = a + (double)F(N - 1) / F(N) * (b - a) + (bix ? -1 : 1) * eps / F(N);
xf1 = Fun(x1);
xf2 = Fun(x2);
P:
++k;
if (xf1 >= xf2)
{
ix = (N - k) & 1;
if (ix == 1)
bix = true;
else
bix = false;
a = x1;
x1 = x2;
xf1 = xf2;
x2 = a + (double)F(N - k - 1) / F(N - k) * (b - a) + (bix ? -1 : 1) * eps / F(N - k);
xf2 = Fun(x2);
}
else
{
ix = (N - k) & 1;
if (ix == 1)
bix = true;
else
bix = false;
b = x2;
x2 = x1;
xf2 = xf1;
x1 = a + (double)F(N - k - 2) / F(N - k) * (b - a) - (bix ? -1 : 1) * eps / F(N - k);
xf1 = Fun(x1);
}
if (Math.Abs(b - a) <= eps)
{
_x = (a + b) / 2;
Console.WriteLine("x = {0:F4}, F(x) = {1:F4}, Количество итераций: {2}", _x, Fun(_x), k );
}
else
goto P;
}
static void Main(string[] args)
{
double a = 1.1, b = 1.3, eps = 0.001;
Fib(a, b,eps);
Console.ReadKey();
}