Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
ElKros
2 / 2 / 1
Регистрация: 14.02.2018
Сообщений: 492
1

Покоординатный спуск

28.02.2019, 20:45. Просмотров 614. Ответов 27
Метки нет (Все метки)

помогите пожалуйста реализовать метод покоординатного спуска ? очень нужно, только без использования метода золотого сечения для функции, зависящей от 2х параметров a и b, например,
f(a,b) = (y[1]+y[2])*(y[0]-y[1])
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.02.2019, 20:45
Ответы с готовыми решениями:

рекурсивный спуск
Подскажите книгу где описано рекурсивный спуск!

Рекурсивный спуск
нужно реализовать рекурсивный спуск буквально за час, буду оч признателен. Нужно найти ошибку в...

Рекурсивный спуск для грамматики
Добрый день. Необходимо написать нисходящий разбор методом рекурсивного спуска для сложения...

Спуск по треугольной куче с наименьшей суммой
Добрый день, пытаюсь решить задачу по программированию ( задание ниже), как понимаю для решения...

Рекурсивный спуск - Функция не останавливается на "else return"
не могу понять, почему функция не останавливается на "else return *(a+mid);" делал отладку, после...

27
Kuzia domovenok
2844 / 2431 / 621
Регистрация: 25.03.2012
Сообщений: 8,651
Записей в блоге: 1
Завершенные тесты: 1
15.05.2019, 23:05 21
ещё одна ошибка в моём ответе
C++
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
const double  eps = 0.001;
double x1old, x2old;
do{
    //пока обе координаты не сошлись
    x1old=x1; x2old=x2;//x1 x2 скоро пересчитаем, а эти значения сохраняем для контроля выхода из цикла
    
    double a = x1_beg, b = x1_end;
    //поиск x1 при постоянном x2    
     while (eps < fabs(b - a)) {         
        double x_alpha = b - t * (b - a); //предполагаемые границы сужения
        double x_beta  = a + t * (b - a);//чтоб не путать с номерами аргумента ф-ии назовём
        double h1 = function_optimiz(x_alpha, x2);
        double h2 = function_optimiz(x_beta, x2);
        if (h2 < h1) a = x_alpha;
        else b = x_beta;
    }
    x1=(b+a)/2;
    //поиск x2 при постоянном x1
    a = x2_beg, b = x2_end;
    while (eps < fabs(b - a)) {      
        double x_alpha = b - t * (b - a); //предполагаемые границы сужения
        double x_beta  = a + t * (b - a);//чтоб не путать с номерами аргумента ф-ии назовём
        double h1 = function_optimiz(x1, x_alpha);
        double h2 = function_optimiz(x1, x_beta);
        if (h2 < h1) a = x_alpha;
        else b = x_beta;
    }   
    x2=(b+a)/2;
}while( fabs(x1old-x1)>eps || fabs(x2old-x2)>eps );
0
ElKros
2 / 2 / 1
Регистрация: 14.02.2018
Сообщений: 492
15.05.2019, 23:06  [ТС] 22
Kuzia domovenok, и поскольку будет цикл на проверку разницы между точками, то мне не нужен основной цикл для сравнения функций ? а хотя, мне же нужно минимизировать функцию, поэтому разница между значениями функций будет корректной. а что мне тогда даст разница между значениями точек ?
0
Kuzia domovenok
2844 / 2431 / 621
Регистрация: 25.03.2012
Сообщений: 8,651
Записей в блоге: 1
Завершенные тесты: 1
15.05.2019, 23:15 23
Цитата Сообщение от ElKros Посмотреть сообщение
Kuzia domovenok, и поскольку будет цикл на проверку разницы между точками, то мне не нужен основной цикл для сравнения функций ? а хотя, мне же нужно минимизировать функцию, поэтому разница между значениями функций будет корректной. а что мне тогда даст разница между значениями точек ?
не понял, чё?
Цитата Сообщение от ElKros Посмотреть сообщение
а что мне тогда даст разница между значениями точек ?
даст то, что если этой разницы нет или она мала, то точки сошлись в одну точку. Ясен пень, что у одинаковых точек и значение функции одинаково, это уже само собой следует из ситуации. Обратное же "следствие" - неверно. На рисунке - значение одинаково, а точки разные.
0
ElKros
2 / 2 / 1
Регистрация: 14.02.2018
Сообщений: 492
15.05.2019, 23:29  [ТС] 24
Kuzia domovenok, просто у меня задача, которую численно проверить невозможно.. а на тестовых примерах работает. Правда, есть в моей задаче значения к которым я должна прийти, но мне пока не удавалось...

Добавлено через 9 минут
Kuzia domovenok, что-то работает не так.. двигается только правый конец отрезка, а левый неподвижен...
0
15.05.2019, 23:29
Kuzia domovenok
2844 / 2431 / 621
Регистрация: 25.03.2012
Сообщений: 8,651
Записей в блоге: 1
Завершенные тесты: 1
16.05.2019, 00:31 25
C++
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
#include <cmath>
using namespace std;
double function_optimiz(double x, double y) {
    return 2 * exp(-0.1*((x - 1)*(x - 1) + (y + 5)*(y + 5))) + 5 * exp(-0.2*(x*x + y * y));
}
int main()
{
    const double  eps = 0.001, t = (std::sqrt(5) - 1) / 2;
    double x1old, x2old;
    double x1 = -5, x2 = -5;
    double x1_beg = -5, x1_end = 5, x2_beg = -5, x2_end = 5;
    do {
        //пока обе координаты не сошлись
        x1old = x1; x2old = x2;//x1 x2 скоро пересчитаем, а эти значения сохраняем для контроля выхода из цикла
 
        double a = x1_beg, b = x1_end;
        //поиск x1 при постоянном x2    
        while (eps < fabs(b - a)) {
            double x_alpha = b - t * (b - a); //предполагаемые границы сужения
            double x_beta = a + t * (b - a);//чтоб не путать с номерами аргумента ф-ии назовём
            double h1 = function_optimiz(x_alpha, x2);
            double h2 = function_optimiz(x_beta, x2);
            if (h2 < h1)  b = x_beta;
            else a = x_alpha;
        }
        x1 = (b + a) / 2;
        //поиск x2 при постоянном x1
        a = x2_beg, b = x2_end;
        while (eps < fabs(b - a)) {
            double x_alpha = b - t * (b - a); //предполагаемые границы сужения
            double x_beta = a + t * (b - a);//чтоб не путать с номерами аргумента ф-ии назовём
            double h1 = function_optimiz(x1, x_alpha);
            double h2 = function_optimiz(x1, x_beta);
            if (h2 < h1)  b = x_beta;
            else a = x_alpha;
        }
        x2 = (b + a) / 2;
    } while (fabs(x1old - x1) > eps || fabs(x2old - x2) > eps);
    return 0;
}
Добавлено через 3 минуты
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
C++
1
2
if (h2 < h1) b = x_beta;
 else a = x_alpha;
поменял крест накрест в обоих половинах программы.
Это, между прочим, твоя ошибка из самого первого сообщения пошла.
0
ElKros
2 / 2 / 1
Регистрация: 14.02.2018
Сообщений: 492
16.05.2019, 03:29  [ТС] 26
Kuzia domovenok, та же ситуация, только теперь наоборот правый неподвижен...
0
Kuzia domovenok
2844 / 2431 / 621
Регистрация: 25.03.2012
Сообщений: 8,651
Записей в блоге: 1
Завершенные тесты: 1
16.05.2019, 09:07 27
ну и? ответ-то подходит?

Добавлено через 22 минуты
вот, написал отдельно для больших любителей "библиотеки" functional в С++
с помощью конструкции bind "фиксировать" одну из координат в функции - как раз наш метод
с помощью типа std::function можно передавать различные функции как один из аргументов
C++
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
#include <cmath>
#include <functional>
using namespace std;
double function_optimiz(double x, double y) {
    return 2 * exp(-0.1*((x - 1)*(x - 1) + (y + 5)*(y + 5))) + 5 * exp(-0.2*(x*x + y * y));
}
double goldrush(double a, double b, const double  eps, std::function<double(double)> foo_mono) {
    //goldrush это поиск точки максимума в функции одного аргумента  
    const double t = (std::sqrt(5) - 1) / 2;
    while (eps < fabs(b - a)) {
        double x_alpha = b - t * (b - a); //предполагаемые границы сужения
        double x_beta = a + t * (b - a);//чтоб не путать с номерами аргумента ф-ии назовём
        double h1 = foo_mono(x_alpha);
        double h2 = foo_mono(x_beta);
        if (h2 < h1)  b = x_beta;
        else a = x_alpha;
    }
    return (b + a) / 2;
}
int main()
{
    const double  eps = 0.001;
    double x1old, x2old;
    double x1 = -5, x2 = -5;
    double x1_beg = -5, x1_end = 5, x2_beg = -5, x2_end = 5;
    do {//пока обе координаты не сошлись
        x1old = x1; x2old = x2;//x1 x2 скоро пересчитаем, а эти значения сохраняем для контроля выхода из цикла        
        //Покоординатный спуск: шаг по x1 - шаг по x2
        x1 = goldrush(x1_beg, x1_end, eps, bind(function_optimiz, std::placeholders::_1, x2));//поиск x1 при постоянном x2
        x2 = goldrush(x2_beg, x2_end, eps, bind(function_optimiz, x1, std::placeholders::_1));//поиск x2 при постоянном x1
    } while (abs(x1old - x1) > eps || abs(x2old - x2) > eps);
    return 0;
}
0
ElKros
2 / 2 / 1
Регистрация: 14.02.2018
Сообщений: 492
16.05.2019, 10:23  [ТС] 28
Kuzia domovenok, а если поиск точки минимума, то меняются местами
C++
1
2
if (h2 < h1) *b = x_beta; * * * 
* else a = x_alpha
?
0
16.05.2019, 10:23
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.05.2019, 10:23

покоординатный спуск. не компилируется!
Попробовал реализовать метод покоординатного спуска, пользовался примером из книги Мудрова...

Наискорейший спуск
Здравствуйте! Подскажите, пожалуйста, как здесь определить значение величины шага g (здесь она...

Градиентный спуск
Нужно найти приближенное решение системы уравнений. Методом Ньютона все получилось, а нужно еще...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.