Метод золотого сечения для поиска минимума функции

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Goldensection(){
listBox1->Items->Clear();
if ((double)numericUpDown2->Value <= (double)numericUpDown1->Value) {
listBox1->Items->Add("Неправильный промежуток");
// Ругаем пользователя за то, что конец промежутка больше начала. (или равны концы)
return; // Неверное условие - делать нечего. Уходим спать :)
}
double u1, u2, f1, f2, epsilon;
double s1=(3-Math::Sqrt(double(5)))/2;
double s2=(Math::Sqrt(double(5))-1)/2;
double a,b,answer;
a = (double)numericUpDown1->Value;
b = (double)numericUpDown2->Value;
epsilon = (double)numericUpDown3->Value;
u1 = a+s1*(b-a);
u2 = a+s2*(b-a);
f1 = foo(u1);
f2 = foo(u2);
while((b-a)>epsilon){
listBox1->Items->Add("Промежуток: [" + a.ToString()+";" + b.ToString()+"]");
listBox1->Items->Add("u1 = " + u1.ToString() + "; u2 = " + u2.ToString());
listBox1->Items->Add("f(u1)=" + f1.ToString() + "; f(u2)=" + f2.ToString());
listBox1->Items->Add("");
if( f1<=f2 ){
b = u2;
u2 = u1;
f2 = f1;
u1 = a+s1*(b-a);
f1 = foo(u1);
} else {
a = u1;
u1 = u2;
f1 = f2;
u2 = a+s2*(b-a);
f2 = foo(u2);
}
}
answer = (f1<=f2)?u1:u2;
listBox1->Items->Add("По заданным условиям был найден минимум в точке");
listBox1->Items->Add("x=" + answer.ToString() + "; f(x)="+foo(answer).ToString());
}