include iostream библиотека для работы потоками вывода ввода данных ci

  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
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream> // библиотека для работы с потоками вывода/ввода данных, cin, cout, ...
#include <math.h> // библиотека для математических вычислений, из нее используются функции pow и sqrt
using namespace std;
/*
* Для чего тут класс, и что такое класс. Вкратце, это структура, которая позволяет использовать вложенные методы и данные с разными областями видимости
* и инкапсуляцией методов и переменных, а также позволяет упрощать код с точки зрения читабельности и количеству строк.
*/
class GoldenRatio { // создаем класс Золотого сечения
private: // Приватная область, к переменным и функциям которой нельзя получить доступ извне
/*
* bool - булевый тип данных. Хранит только одно из значение: true - истина, либо ложь - false.
* findMax - название приватной переменной
*/
bool findMax;
/*
* Статичная константная функция, возвращающая значение пропорции золотого сечения фи
* Значение в формате плавающей точки с двойной точностью
*/
static const double phi() {
/* Здесь sqrt - это функция, для вычисления квадратного корня из библиотеки <math.h>
* sqrt("число/выражение")
* sqrt(4) => 2, sqrt(25) => 5
*/
return (1 + sqrt(5)) / 2;
//return 1.6180339887; // выражение, для вычисления пропорции золотого сечения ()
}
/* Статичная функция возвращающая значение с плавающей точкой двойной точности.
* Принимает как аргумент значение с плавающей точкой двойной точности (x).
* В ней хранится исходная функция, для которой будут находиться минимум и максимум.
*/
public: // Публичная область, к переменным и функциям которой можно получить доступ вне класса
/*
* По сути конструктор представляет функцию, которая может принимать параметры и которая должна называться именем класса.
* В данном случае конструктор принимает один параметр - findMax, и устанавливает его значение в приватной переменной this->findMax.
* В будущем, в классе будет обращение к этой переменой с проверкой, что мы ищем - максимум или минимум.
* explicit - это ключевое слово, которое необходимо указывать при объявлении конструктора с одним параметром (ну или если все другие параметры имеют default value)
*/
explicit GoldenRatio(bool findMax) { // Конструктор класса.
this->findMax = findMax;
}
double f(double x) {
/* pow - функция, для возведения в степень из библиотеки <math.h>
* pow("число/выражение", "степень")
* pow(5, 2) => 25, pow(2, 5) => 32
*/
return pow(x, 2) + 5 * pow(x, 3); // x^2 + 5 * x^3
}
double calculate(double a, double b, double e) {
/* x1 - переменная, хранящая результат расчетов левой точки деления на отрезки
* x2 - переменная, хранящая результат расчетов правой точки деления на отрезки
* delta - результат выражения (b - a) / phi() в каждой итерации, переменная используется для
* хранения значения в памяти без повторных вычислений значений. можно везде заменить на (b - a) / phi()
*/
double x1, x2, delta;
/*
* Цикл while будет выполняться, пока условие, указанное в круглых скобках является истиной.
* abs(b - a) > e - условие проверки достижения указанной точности
* Если точность достигнута - цикл будет прерван и функция вернет вычисленное значение (a + b) / 2;
* Если точность не достигнута, то будут происходить расчет переменных a и b, путем итеративного разбивания отрезков
*/
while (b - a > e) {
delta = (b - a) / phi(); // создал временную переменную, чтобы дважды не вычислять это значение
/*
* Рассчет координат точек деления, при каждой итерации цикла, исходный отрезок делится на более меньшие отрезки
*/
x1 = b - delta;
x2 = a + delta;
if(this->findMax) { // Проверка ищем ли мы максимум, или минимум (зависит от ввода пользователя)
if (f(x1) <= f(x2)) { // если функция от x1 больше или равна функции от х2, то
a = x1; // сдвиг значения для следующей итерации
} else { // в противном случае
b = x2; // сдвиг значения для следующей итерации
}
} else { // Тут типо ищем минимум
if (f(x1) >= f(x2)) { // если функция от x1 меньше или равна функции от х2, то
a = x1; // сдвиг значения для следующей итерации
} else { // в противном случае
b = x2; // сдвиг значения для следующей итерации
}
}
}
return (a + b) / 2; // возврат значения x
}
};
int main() {
/*
* Исходные данные:
* f(x) = x^2 + 5 * x^3
* Значения, которые я сверял через онлайн-калькулятор https://math.semestr.ru/optim/golden.php
* double a = -8.f, b = 0, e = 0.0001;
* Поиск минимума:
* Результат калькулятора: x = -7.999998675; F(x) = -2495.9987
* Результат программы: x = -7.99996; F(x) = -2495.96
* Поиск максимума:
* Результат калькулятора: x = -0.13333222; F(x) = -0.00593
* Результат программы: x = -0.133349; F(x) = 0.00592593 // ??
*/
double a, b, e;
int value;
cout << "Enter a:";
cin >> a;
cout << "Enter b:";
cin >> b;
cout << "Enter epsilon:";
cin >> e;
cout << "If u want find maximum enter 1 or enter any value for find minimum:";
cin >> value;
/*
* Тут создается объект object класса GoldenRatio, и в конструктор передается value == 1
* value == 1 - это условие, оно вернет true - если value равно 1, в противном случае false
*/
GoldenRatio *object = new GoldenRatio(value == 1);
/*
* Тут вызывается метод calculate объекта object
* В него передаются введенные пользователем данные в качестве аргументов
*/
double x = object->calculate(a, b, e);
cout << endl << "x = " << x << "; F(x) = " << object->f(x); // вывод на экран значения x, и значения функции от x.
}