Алгоритм успешного ресторатора — Successful Restaurateur Algorithm (SRA)
Содержание
Введение
Меня всегда увлекали параллели между задачами оптимизации и реальными жизненными сценариями. Исследуя новые подходы к метаэвристическим алгоритмам, я обнаружил сходство между популяционной оптимизацией и эволюцией ресторанного бизнеса, и эта идея стала источником вдохновения для того, что я называю "Алгоритмом успешного ресторатора" (SRA).
Представьте владельца ресторана, который постоянно стремится улучшить свое меню для улучшения популярности своего ресторана и привлечения новых клиентов. Вместо того, чтобы полностью отказываться от непопулярных блюд, он использует более тонкий подход: определяет наименее популярную позицию, а затем аккуратно смешивает ее с элементами из самых успешных блюд. Иногда вносятся консервативные изменения, а иногда добавляются смелые новые ингредиенты. Цель всегда одна — превратить самое слабое предложение в нечто, что может стать новым фаворитом в меню для клиентов ресторана.
Эта кулинарная метафора формирует основу SRA. В отличие от традиционных эволюционных алгоритмов, которые часто полностью отбрасывают неудачные решения, SRA фокусируется на реабилитации наихудших исполнителей, сочетая их с успешными элементами. Такой подход сохраняет разнообразие в пространстве решений, одновременно неуклонно повышая общее качество популяции.
В этой статье рассмотрим основные механизмы SRA, проанализируем его реализацию и то, как параметры вроде "температуры" и "интенсивности кулинарных экспериментов" управляют балансом между эксплуатацией и исследованием, а также я поделюсь результатами тестирования, сравнивая SRA с другими известными алгоритмами в рейтинговой таблице на различных тестовых функциях.
То, что начиналось как творческий мысленный эксперимент, превратилось в многообещающий подход с уникальными характеристиками. Приглашаю вас исследовать, как этот алгоритм, вдохновленный ресторанным бизнесом, предлагает решения оптимизации со своим особенным вкусом.
Реализация алгоритма
Давайте разберем работу алгоритма через простые аналогии. Представьте, что я являюсь владельцем ресторана. У меня есть меню с разными блюдами и замечаю, что некоторые из них очень популярны, а некоторые блюда гости почти не заказывают. Что я делаю? Я не выбрасываю сразу непопулярные блюда из меню (тем самым уменьшая список доступных блюд), а вместо этого — беру самое непопулярное блюдо и пытаюсь его улучшить. Как? Я смотрю на хитовые позиции ресторана и заимствую оттуда какие-то идеи или ингредиенты. Например, у меня плохо продаётся рыбное блюдо, а салат — очень популярен. Я беру элементы из успешного салата (может, особую заправку или способ подачи) и применяю к рыбному блюду. Получается что-то новое.
Иногда я делаю небольшие изменения, а иногда — решаюсь на смелые эксперименты. В начале, когда я только открыл ресторан, я больше экспериментировал, а когда уже нашел несколько действительно удачных блюд, делаю более тонкую настройку состава ингредиентов и их количества. Со временем, даже самые слабые блюда в моем меню становятся всё лучше и лучше. А иногда бывает, что бывший аутсайдер после доработки становится новым успешным блюдом! Таким образом, общая популярность ресторана растет за счет того, что все позиции меню пользуются успехом.
Вот так работает и мой алгоритм, — мы не выбрасываем плохие решения, а постоянно улучшаем их, используя идеи из лучших решений. И чем дальше, тем меньше мы экспериментируем, больше уточняя уже найденное. На рисунке 1 представлена схема работы алгоритма.

Рисунок 1. Схема работы алгоритма SRA
Схема начинается с блока "Инициализация", где создаётся начальное меню. Затем следует основной цикл алгоритма, в центре которого находится текущее меню ресторана, отсортированное по качеству блюд. Это меню изображено как цветовой градиент от зелёного (лучшие блюда) к красному (худшие блюда). Ниже идут четыре последовательных шага: первый — выбор блюд для улучшения, где берётся худшее блюдо и лучший донор с увеличенной вероятностью ко квадратичному закону; второй — создание новых вариантов путём комбинирования рецептов и мутации ингредиентов (причём, чем выше температура, тем смелее эксперименты); третий — оценка новых блюд через расчёт фитнес-функции; четвёртый — снижение температуры для уменьшения радикальности экспериментов. Слева пунктирная стрелка показывает, что процесс повторяется до достижения сходимости или выполнения критерия останова. Справа даны обозначения: A (зелёный круг) — лучшие блюда, B (красный круг) — худшие блюда. Вся схема визуализирует процесс, напоминающий работу ресторатора, который систематически улучшает слабые позиции своего меню, используя элементы успешных блюд.
Переходим к написанию псевдокода алгоритма SRA.
// Инициализация
Создать популяцию из popSize агентов (блюд в меню)
Для каждого агента:
Случайно инициализировать все координаты в допустимых пределах
Установить начальную температуру = 1.0
Установить коэффициент охлаждения = 0.98
Установить интенсивность кулинарных экспериментов = 0.3
// Основной цикл алгоритма
ПОКА не выполнено условие остановки:
// Шаг 1: Оценка всех агентов
Для каждого агента:
Вычислить значение фитнес-функции
// Объединить текущую и предыдущую популяции
Сформировать общее меню из текущих агентов и предыдущих агентов
Отсортировать общее меню по значению фитнес-функции от лучшего к худшему
// Шаг 2: Создание новых вариантов
Для каждого агента в новой популяции:
// Берем худший элемент из первой половины отсортированной популяции
Скопировать координаты из агента с индексом (popSize-1)
// Выбор между улучшением и экспериментом
Если (случайное число < (1.0 - menuInnovationRate * температура)):
// Выбираем "донора" методом квадратичной рулетки
r = случайное число от 0 до 1
r = r²
donorIndex = масштабировать r от 0 до (popSize-1)
// Для каждой координаты
Для каждой координаты c:
// С вероятностью 0.8 берем координату из донора
Если (случайное число < 0.8):
текущий_агент.c = донор.c
// Адаптивная мутация
mutationRate = 0.1 + 0.4 * температура * (индекс_агента / popSize)
Если (случайное число < mutationRate):
// Выбираем тип мутации
Если (случайное число < 0.5):
текущий_агент.c = гауссовское распределение(текущий_агент.c)
Иначе:
текущий_агент.c = случайное значение в диапазоне
// Убедиться, что значение в допустимых пределах
текущий_агент.c = округлить до ближайшего допустимого значения
Иначе:
// Создание нового "блюда"
Для каждой координаты c:
Если (случайное число < 0.7):
текущий_агент.c = случайное значение в диапазоне
Иначе:
текущий_агент.c = гауссовское распределение(лучшее_решение.c)
// Убедиться, что значение в допустимых пределах
текущий_агент.c = округлить до ближайшего допустимого значения
// Элитизм — иногда простое добавление элементов из лучшего решения
Если (случайное число < 0.1):
numEliteCoords = случайное число от 1 до (coords * 0.3)
Для i от 1 до numEliteCoords:
c = случайный индекс координаты
текущий_агент.c = лучшее_решение.c
// Шаг 3: Обновление лучшего решения
Для каждого агента:
Если агент.фитнес > лучшее_решение.фитнес:
лучшее_решение = агент
// Шаг 4: Снижение температуры
температура = температура * коэффициент_охлаждения
Если температура < 0.1:
температура = 0.1
Вернуть лучшее_решение
Теперь можно приступить к написанию кода алгоритма. Напишем класс "C_AO_SRA", который наследуется от главного класса "C_AO" и реализует алгоритм SRA. Давайте разберем его подробнее.
Конструктор и деструктор: popSize, temperature, coolingRate, menuInnovationRate — эти параметры определяют основные характеристики алгоритма, такие как количество агентов и параметры управления поиском.
Метод SetParams: обновляет параметры класса на основании значений, хранящихся в массиве "params", параметры ранее инициализировались в конструкторе.
Метод Init: предназначен для инициализации алгоритма. Он принимает минимальные и максимальные значения, шаг изменения параметров и количество эпох и подготавливает алгоритм к выполнению задачи поиска.
Методы Moving и Revision: предназначены для выполнения основных этапов работы алгоритма, связанных с движением (или обновлением) состояния агентов и "Revision", который отвечает за пересмотр и адаптацию параметров.
Члены класса:
- temperature — текущая температура, связанная с управлением исследованием и температурным графиком алгоритма.
- coolingRate — скорость охлаждения, которая используется для управления тем, как быстро температура будет понижаться.
- menuInnovationRate — интенсивность кулинарных экспериментов, насколько агенты поощряются к поиску новых решений.
- S_AO_Agent menu [] — массив агентов, который представляет "меню" в контексте алгоритма SRA.
- S_AO_Agent menuT [] — массив агентов, используемый для временного хранения вариантов блюд.
//—————————————————————————————————————————————————————————————————————————————— class C_AO_SRA : public C_AO { public: //-------------------------------------------------------------------- ~C_AO_SRA () { } C_AO_SRA () { ao_name = "SRA"; ao_desc = "Successful Restaurateur Algorithm (joo)"; ao_link = "https://www.mql5.com/ru/articles/17380"; popSize = 50; // число агентов (размер "меню") temperature = 1.0; // начальная "температура" для управления исследованием coolingRate = 0.98; // скорость охлаждения menuInnovationRate = 0.3; // интенсивность кулинарных экспериментов ArrayResize (params, 4); params [0].name = "popSize"; params [0].val = popSize; params [1].name = "temperature"; params [1].val = temperature; params [2].name = "coolingRate"; params [2].val = coolingRate; params [3].name = "menuInnovationRate"; params [3].val = menuInnovationRate; } void SetParams () { popSize = (int)params [0].val; temperature = params [1].val; coolingRate = params [2].val; menuInnovationRate = params [3].val; } bool Init (const double &rangeMinP [], // минимальные значения const double &rangeMaxP [], // максимальные значения const double &rangeStepP [], // шаг изменения const int epochsP = 0); // количество эпох void Moving (); void Revision (); //---------------------------------------------------------------------------- double temperature; // текущая "температура" double coolingRate; // скорость охлаждения double menuInnovationRate; // интенсивность кулинарных экспериментов private: //------------------------------------------------------------------- S_AO_Agent menu []; S_AO_Agent menuT []; }; //——————————————————————————————————————————————————————————————————————————————
Метод "Init" класса "C_AO_SRA" выполняет инициализацию алгоритма:
Проверка начальной инициализации: метод вызывает "StandardInit" с минимальными и максимальными значениями диапазонов и шагов, если неудачно, возвращается "false".
Инициализация массивов:
- Распределяет размеры массивов "menu" и "menuT" в соответствии с количеством агентов.
- Инициализирует каждого агента в массиве "menu".
Сброс температуры: устанавливает начальное значение "temperature" равным "1.0".
Успешное завершение: возвращается "true", если инициализация прошла успешно.
//—————————————————————————————————————————————————————————————————————————————— //--- Инициализация bool C_AO_SRA::Init (const double &rangeMinP [], const double &rangeMaxP [], const double &rangeStepP [], const int epochsP = 0) { if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; //---------------------------------------------------------------------------- ArrayResize (menu, popSize * 2); ArrayResize (menuT, popSize * 2); for (int p = 0; p < popSize * 2; p++) menu [p].Init (coords); temperature = 1.0; // сброс температуры при инициализации return true; } //——————————————————————————————————————————————————————————————————————————————
Метод "Moving" класса "C_AO_SRA" реализует основной шаг алгоритма. Он имеет две основные части: инициализацию агентов и их адаптацию через мутацию и создание новых решений.
Первоначальная инициализация (если "revision" равно "false"):- Каждый агент инициализируется случайными значениями в пределах заданных диапазонов (rangeMin, rangeMax) с применением шагов (rangeStep). Значения сохраняются в "c" и "cB" для каждого агента.
- Устанавливается "revision" в "true" и метод завершает выполнение.
Снижение температуры: температура умножается на коэффициент охлаждения (coolingRate), что влияет на вероятности дальнейших изменений.
Основной цикл по агентам: для каждого агента выбирается худший элемент из первой половины отсортированной популяции (из массива menu).
Классификация действий: с определенной вероятностью, которая зависит от температуры, агент либо:
- модифицирует текущее решение (с использованием "рецепта-донор" из лучшего блюда), применяя мутацию с изменяющейся вероятностью.
- создает новое решение (случайные значения).
Элитизм: с некоторой вероятностью к новому решению могут быть добавлены элементы от лучшего найденного решения.
//—————————————————————————————————————————————————————————————————————————————— //--- Основной шаг алгоритма void C_AO_SRA::Moving () { //---------------------------------------------------------------------------- // Начальная инициализация if (!revision) { for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); a [p].cB [c] = a [p].c [c]; } } revision = true; return; } //---------------------------------------------------------------------------- // Снижаем температуру temperature *= coolingRate; // Основной цикл по агентам популяции for (int p = 0; p < popSize; p++) { // Берем худший элемент из первой половины отсортированной популяции (с индексом popSize-1) // Помним, что в menu элементы отсортированы от лучшего к худшему ArrayCopy (a [p].c, menu [popSize - 1].c, 0, 0, WHOLE_ARRAY); // Решаем, создавать ли гибрид или экспериментировать с новым "блюдом" // Вероятность эксперимента зависит от температуры - в начале больше экспериментов if (u.RNDprobab () < (1.0 - menuInnovationRate * temperature)) { // Выбираем "рецепт-донор" с вероятностью пропорциональной успешности блюда double r = u.RNDprobab (); r = pow (r, 2); // Усиление предпочтения к лучшим блюдам int menuIND = (int)u.Scale (r, 0, 1.0, 0, popSize - 1); // Лучшие в начале массива // Для каждой координаты for (int c = 0; c < coords; c++) { // С вероятностью, зависящей от температуры, берем параметр из успешного блюда if (u.RNDprobab () < 0.8) { a [p].c [c] = menu [menuIND].c [c]; } // Мутация с адаптивной вероятностью - чем дальше от лучшего решения и выше температура, тем больше мутаций double mutationRate = 0.1 + 0.4 * temperature * (double)(p) / popSize; if (u.RNDprobab () < mutationRate) { // Комбинация различных типов мутаций if (u.RNDprobab () < 0.5) a [p].c [c] = u.GaussDistribution (a [p].c [c], rangeMin [c], rangeMax [c], 2); else a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); // Иногда полностью новое значение // Убедимся, что значение в допустимых пределах a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } else // Создаем абсолютно новое "блюдо" { for (int c = 0; c < coords; c++) { // Вариация 1: полностью случайное значение if (u.RNDprobab () < 0.7) { a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); } // Вариация 2: основано на лучшем найденном решении с большим отклонением else { a [p].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 1); } a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } // Иногда добавляем элементы из лучшего решения напрямую (элитизм) if (u.RNDprobab () < 0.1) { int numEliteCoords = u.RNDintInRange (1, coords / 3); // Берем от 1 до 30% координат for (int i = 0; i < numEliteCoords; i++) { int c = u.RNDminusOne (coords); a [p].c [c] = cB [c]; // Берем значение из лучшего решения } } } } //——————————————————————————————————————————————————————————————————————————————
Метод "Revision" класса "C_AO_SRA" отвечает за обновление лучшего найденного решения и за управление общим "меню" решений в процессе работы алгоритма:
Поиск лучшего агента: проходит по всем агентам в текущей популяции и находит агента с наилучшей фитнес-функцией (f). Если найден новый лучший агент, обновляет значение "fB" и индекс "bestIND".
Обновление лучшего решения: если найден лучший агент (т.е. bestIND не равен -1), копирует его параметры решения (c) в переменную cB, представляющую текущее лучшее решение.
Обновление общего "меню": добавляет текущие параметры всех агентов в общее "меню", что позволяет сохранять выполненные эксперименты.
Сортировка меню: сортирует массив "menu" по фитнес-функции от лучших к худшим решениям, обеспечивая, что лучшие решения находятся в первой половине. Это будет использоваться в следующей итерации алгоритма.
Контроль температуры: устанавливает нижний порог для температуры, чтобы она не опускалась ниже "0.1", что предотвращает слишком быструю конвергенцию.//—————————————————————————————————————————————————————————————————————————————— //--- Обновление лучшего решения с учетом жадного выбора и вероятности принятия худших решений void C_AO_SRA::Revision () { int bestIND = -1; // Находим лучшего агента в текущей популяции for (int p = 0; p < popSize; p++) { if (a [p].f > fB) { fB = a [p].f; bestIND = p; } } // Если нашли лучшее решение, обновляем cB if (bestIND != -1) ArrayCopy (cB, a [bestIND].c, 0, 0, WHOLE_ARRAY); // Добавляем текущий набор блюд в общее "меню" for (int p = 0; p < popSize; p++) { menu [popSize + p] = a [p]; } // Сортируем всё "меню" от лучших к худшим решениям // После сортировки, первая половина menu будет содержать лучшие решения, // которые будут использоваться на следующей итерации u.Sorting (menu, menuT, popSize * 2); // Не позволяем температуре упасть ниже определенного порога if (temperature < 0.1) temperature = 0.1; } //——————————————————————————————————————————————————————————————————————————————
Результаты тестов
Теперь можем посмотреть, как работает алгоритм SRA. Ниже представлена распечатка результатов тестирования:
SRA|Successful Restaurateur Algorithm|50.0|1.0|0.98|0.3|
=============================
5 Hilly's; Func runs: 10000; result: 0.9688326305968623
25 Hilly's; Func runs: 10000; result: 0.6345483084017249
500 Hilly's; Func runs: 10000; result: 0.292167027537253
=============================
5 Forest's; Func runs: 10000; result: 0.946368863880973
25 Forest's; Func runs: 10000; result: 0.5550607959254661
500 Forest's; Func runs: 10000; result: 0.19124225531141872
=============================
5 Megacity's; Func runs: 10000; result: 0.7492307692307693
25 Megacity's; Func runs: 10000; result: 0.4403076923076923
500 Megacity's; Func runs: 10000; result: 0.12526153846153956
=============================
All score: 4.90302 (54.48%)
Визуализация работы алгоритма SRA на тестовом стенде позволяет сделать выводы о характерных чертах стратегии поиска. В данном случае наблюдается широкое исследование пространства поиска: агенты равномерно распределены по всему пространству, изучая даже самые удаленные его уголки. При этом, не наблюдается заметных признаков группирования в локальных экстремумах, движения агентов выглядят хаотично.
Однако, несмотря на хорошую способность к исследованию, алгоритм демонстрирует некоторые недостатки в уточнении решений, что проявляется в относительно низкой точности сходимости. Следует отметить также небольшой разброс результатов тестирования.

SRA на тестовой функции Hilly

SRA на тестовой функции Forest

SRA на тестовой функции Megacity
По результатам проведенных тестов, алгоритм занимает 20 место в рейтинге самых сильных популяционных алгоритмов оптимизации. На данный момент в таблице представлены девять авторских алгоритмов оптимизации (joo), в число которых входит и новый алгоритм SRA.
| № | AO | Description | Hilly | Hilly final | Forest | Forest final | Megacity (discrete) | Megacity final | Final result | % of MAX | ||||||
| 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | ||||||||
| 1 | ANS | across neighbourhood search | 0,94948 | 0,84776 | 0,43857 | 2,23581 | 1,00000 | 0,92334 | 0,39988 | 2,32323 | 0,70923 | 0,63477 | 0,23091 | 1,57491 | 6,134 | 68,15 |
| 2 | CLA | code lock algorithm (joo) | 0,95345 | 0,87107 | 0,37590 | 2,20042 | 0,98942 | 0,91709 | 0,31642 | 2,22294 | 0,79692 | 0,69385 | 0,19303 | 1,68380 | 6,107 | 67,86 |
| 3 | AMOm | animal migration ptimization M | 0,90358 | 0,84317 | 0,46284 | 2,20959 | 0,99001 | 0,92436 | 0,46598 | 2,38034 | 0,56769 | 0,59132 | 0,23773 | 1,39675 | 5,987 | 66,52 |
| 4 | (P+O)ES | (P+O) evolution strategies | 0,92256 | 0,88101 | 0,40021 | 2,20379 | 0,97750 | 0,87490 | 0,31945 | 2,17185 | 0,67385 | 0,62985 | 0,18634 | 1,49003 | 5,866 | 65,17 |
| 5 | CTA | comet tail algorithm (joo) | 0,95346 | 0,86319 | 0,27770 | 2,09435 | 0,99794 | 0,85740 | 0,33949 | 2,19484 | 0,88769 | 0,56431 | 0,10512 | 1,55712 | 5,846 | 64,96 |
| 6 | TETA | time evolution travel algorithm (joo) | 0,91362 | 0,82349 | 0,31990 | 2,05701 | 0,97096 | 0,89532 | 0,29324 | 2,15952 | 0,73462 | 0,68569 | 0,16021 | 1,58052 | 5,797 | 64,41 |
| 7 | SDSm | stochastic diffusion search M | 0,93066 | 0,85445 | 0,39476 | 2,17988 | 0,99983 | 0,89244 | 0,19619 | 2,08846 | 0,72333 | 0,61100 | 0,10670 | 1,44103 | 5,709 | 63,44 |
| 8 | BOAm | billiards optimization algorithm M | 0,95757 | 0,82599 | 0,25235 | 2,03590 | 1,00000 | 0,90036 | 0,30502 | 2,20538 | 0,73538 | 0,52523 | 0,09563 | 1,35625 | 5,598 | 62,19 |
| 9 | AAm | archery algorithm M | 0,91744 | 0,70876 | 0,42160 | 2,04780 | 0,92527 | 0,75802 | 0,35328 | 2,03657 | 0,67385 | 0,55200 | 0,23738 | 1,46323 | 5,548 | 61,64 |
| 10 | ESG | evolution of social groups (joo) | 0,99906 | 0,79654 | 0,35056 | 2,14616 | 1,00000 | 0,82863 | 0,13102 | 1,95965 | 0,82333 | 0,55300 | 0,04725 | 1,42358 | 5,529 | 61,44 |
| 11 | SIA | simulated isotropic annealing (joo) | 0,95784 | 0,84264 | 0,41465 | 2,21513 | 0,98239 | 0,79586 | 0,20507 | 1,98332 | 0,68667 | 0,49300 | 0,09053 | 1,27020 | 5,469 | 60,76 |
| 12 | ACS | artificial cooperative search | 0,75547 | 0,74744 | 0,30407 | 1,80698 | 1,00000 | 0,88861 | 0,22413 | 2,11274 | 0,69077 | 0,48185 | 0,13322 | 1,30583 | 5,226 | 58,06 |
| 13 | DA | dialectical algorithm | 0,86183 | 0,70033 | 0,33724 | 1,89940 | 0,98163 | 0,72772 | 0,28718 | 1,99653 | 0,70308 | 0,45292 | 0,16367 | 1,31967 | 5,216 | 57,95 |
| 14 | BHAm | black hole algorithm M | 0,75236 | 0,76675 | 0,34583 | 1,86493 | 0,93593 | 0,80152 | 0,27177 | 2,00923 | 0,65077 | 0,51646 | 0,15472 | 1,32195 | 5,196 | 57,73 |
| 15 | ASO | anarchy society optimization | 0,84872 | 0,74646 | 0,31465 | 1,90983 | 0,96148 | 0,79150 | 0,23803 | 1,99101 | 0,57077 | 0,54062 | 0,16614 | 1,27752 | 5,178 | 57,54 |
| 16 | RFO | royal flush optimization (joo) | 0,83361 | 0,73742 | 0,34629 | 1,91733 | 0,89424 | 0,73824 | 0,24098 | 1,87346 | 0,63154 | 0,50292 | 0,16421 | 1,29867 | 5,089 | 56,55 |
| 17 | AOSm | atomic orbital search M | 0,80232 | 0,70449 | 0,31021 | 1,81702 | 0,85660 | 0,69451 | 0,21996 | 1,77107 | 0,74615 | 0,52862 | 0,14358 | 1,41835 | 5,006 | 55,63 |
| 18 | TSEA | turtle shell evolution algorithm (joo) | 0,96798 | 0,64480 | 0,29672 | 1,90949 | 0,99449 | 0,61981 | 0,22708 | 1,84139 | 0,69077 | 0,42646 | 0,13598 | 1,25322 | 5,004 | 55,60 |
| 19 | DE | differential evolution | 0,95044 | 0,61674 | 0,30308 | 1,87026 | 0,95317 | 0,78896 | 0,16652 | 1,90865 | 0,78667 | 0,36033 | 0,02953 | 1,17653 | 4,955 | 55,06 |
| 20 | SRA | successful restaurateur algorithm (joo) | 0,96883 | 0,63455 | 0,29217 | 1,89555 | 0,94637 | 0,55506 | 0,19124 | 1,69267 | 0,74923 | 0,44031 | 0,12526 | 1,31480 | 4,903 | 54,48 |
| 21 | CRO | chemical reaction optimisation | 0,94629 | 0,66112 | 0,29853 | 1,90593 | 0,87906 | 0,58422 | 0,21146 | 1,67473 | 0,75846 | 0,42646 | 0,12686 | 1,31178 | 4,892 | 54,36 |
| 22 | BIO | blood inheritance optimization (joo) | 0,81568 | 0,65336 | 0,30877 | 1,77781 | 0,89937 | 0,65319 | 0,21760 | 1,77016 | 0,67846 | 0,47631 | 0,13902 | 1,29378 | 4,842 | 53,80 |
| 23 | BSA | bird swarm algorithm | 0,89306 | 0,64900 | 0,26250 | 1,80455 | 0,92420 | 0,71121 | 0,24939 | 1,88479 | 0,69385 | 0,32615 | 0,10012 | 1,12012 | 4,809 | 53,44 |
| 24 | HS | harmony search | 0,86509 | 0,68782 | 0,32527 | 1,87818 | 0,99999 | 0,68002 | 0,09590 | 1,77592 | 0,62000 | 0,42267 | 0,05458 | 1,09725 | 4,751 | 52,79 |
| 25 | SSG | saplings sowing and growing | 0,77839 | 0,64925 | 0,39543 | 1,82308 | 0,85973 | 0,62467 | 0,17429 | 1,65869 | 0,64667 | 0,44133 | 0,10598 | 1,19398 | 4,676 | 51,95 |
| 26 | BCOm | bacterial chemotaxis optimization M | 0,75953 | 0,62268 | 0,31483 | 1,69704 | 0,89378 | 0,61339 | 0,22542 | 1,73259 | 0,65385 | 0,42092 | 0,14435 | 1,21912 | 4,649 | 51,65 |
| 27 | ABO | african buffalo optimization | 0,83337 | 0,62247 | 0,29964 | 1,75548 | 0,92170 | 0,58618 | 0,19723 | 1,70511 | 0,61000 | 0,43154 | 0,13225 | 1,17378 | 4,634 | 51,49 |
| 28 | (PO)ES | (PO) evolution strategies | 0,79025 | 0,62647 | 0,42935 | 1,84606 | 0,87616 | 0,60943 | 0,19591 | 1,68151 | 0,59000 | 0,37933 | 0,11322 | 1,08255 | 4,610 | 51,22 |
| 29 | TSm | tabu search M | 0,87795 | 0,61431 | 0,29104 | 1,78330 | 0,92885 | 0,51844 | 0,19054 | 1,63783 | 0,61077 | 0,38215 | 0,12157 | 1,11449 | 4,536 | 50,40 |
| 30 | BSO | brain storm optimization | 0,93736 | 0,57616 | 0,29688 | 1,81041 | 0,93131 | 0,55866 | 0,23537 | 1,72534 | 0,55231 | 0,29077 | 0,11914 | 0,96222 | 4,498 | 49,98 |
| 31 | WOAm | wale optimization algorithm M | 0,84521 | 0,56298 | 0,26263 | 1,67081 | 0,93100 | 0,52278 | 0,16365 | 1,61743 | 0,66308 | 0,41138 | 0,11357 | 1,18803 | 4,476 | 49,74 |
| 32 | AEFA | artificial electric field algorithm | 0,87700 | 0,61753 | 0,25235 | 1,74688 | 0,92729 | 0,72698 | 0,18064 | 1,83490 | 0,66615 | 0,11631 | 0,09508 | 0,87754 | 4,459 | 49,55 |
| 33 | AEO | artificial ecosystem-based optimization algorithm | 0,91380 | 0,46713 | 0,26470 | 1,64563 | 0,90223 | 0,43705 | 0,21400 | 1,55327 | 0,66154 | 0,30800 | 0,28563 | 1,25517 | 4,454 | 49,49 |
| 34 | ACOm | ant colony optimization M | 0,88190 | 0,66127 | 0,30377 | 1,84693 | 0,85873 | 0,58680 | 0,15051 | 1,59604 | 0,59667 | 0,37333 | 0,02472 | 0,99472 | 4,438 | 49,31 |
| 35 | BFO-GA | bacterial foraging optimization - ga | 0,89150 | 0,55111 | 0,31529 | 1,75790 | 0,96982 | 0,39612 | 0,06305 | 1,42899 | 0,72667 | 0,27500 | 0,03525 | 1,03692 | 4,224 | 46,93 |
| 36 | SOA | simple optimization algorithm | 0,91520 | 0,46976 | 0,27089 | 1,65585 | 0,89675 | 0,37401 | 0,16984 | 1,44060 | 0,69538 | 0,28031 | 0,10852 | 1,08422 | 4,181 | 46,45 |
| 37 | ABHA | artificial bee hive algorithm | 0,84131 | 0,54227 | 0,26304 | 1,64663 | 0,87858 | 0,47779 | 0,17181 | 1,52818 | 0,50923 | 0,33877 | 0,10397 | 0,95197 | 4,127 | 45,85 |
| 38 | ACMO | atmospheric cloud model optimization | 0,90321 | 0,48546 | 0,30403 | 1,69270 | 0,80268 | 0,37857 | 0,19178 | 1,37303 | 0,62308 | 0,24400 | 0,10795 | 0,97503 | 4,041 | 44,90 |
| 39 | ADAMm | adaptive moment estimation M | 0,88635 | 0,44766 | 0,26613 | 1,60014 | 0,84497 | 0,38493 | 0,16889 | 1,39880 | 0,66154 | 0,27046 | 0,10594 | 1,03794 | 4,037 | 44,85 |
| 40 | CGO | chaos game optimization | 0,57256 | 0,37158 | 0,32018 | 1,26432 | 0,61176 | 0,61931 | 0,62161 | 1,85267 | 0,37538 | 0,21923 | 0,19028 | 0,78490 | 3,902 | 43,35 |
| 41 | ATAm | artificial tribe algorithm M | 0,71771 | 0,55304 | 0,25235 | 1,52310 | 0,82491 | 0,55904 | 0,20473 | 1,58867 | 0,44000 | 0,18615 | 0,09411 | 0,72026 | 3,832 | 42,58 |
| 42 | ASHA | artificial showering algorithm | 0,89686 | 0,40433 | 0,25617 | 1,55737 | 0,80360 | 0,35526 | 0,19160 | 1,35046 | 0,47692 | 0,18123 | 0,09774 | 0,75589 | 3,664 | 40,71 |
| 43 | ASBO | adaptive social behavior optimization | 0,76331 | 0,49253 | 0,32619 | 1,58202 | 0,79546 | 0,40035 | 0,26097 | 1,45677 | 0,26462 | 0,17169 | 0,18200 | 0,61831 | 3,657 | 40,63 |
| 44 | MEC | mind evolutionary computation | 0,69533 | 0,53376 | 0,32661 | 1,55569 | 0,72464 | 0,33036 | 0,07198 | 1,12698 | 0,52500 | 0,22000 | 0,04198 | 0,78698 | 3,470 | 38,55 |
| 45 | CSA | circle search algorithm | 0,66560 | 0,45317 | 0,29126 | 1,41003 | 0,68797 | 0,41397 | 0,20525 | 1,30719 | 0,37538 | 0,23631 | 0,10646 | 0,71815 | 3,435 | 38,17 |
| RW | random walk | 0,48754 | 0,32159 | 0,25781 | 1,06694 | 0,37554 | 0,21944 | 0,15877 | 0,75375 | 0,27969 | 0,14917 | 0,09847 | 0,52734 | 2,348 | 26,09 | |
Выводы
Разработав и протестировав алгоритм успешного ресторатора (SRA), я могу с уверенностью сказать, что он показал себя достойно. На данный момент алгоритм занимает 20-е место в рейтинговой таблице, что для новой концепции весьма неплохо. Анализируя результаты, я заметил некоторые особенности в его поведении. На задачах малой размерности наблюдается разброс результатов. Особенно это заметно на дискретной функции "Megacity", где алгоритм имеет особенно большой разброс значений. Эта функция очень сложная для алгоритмов и застревание в локальных экстремумах является больше правилом, чем исключением.
На задачах большой размерности SRA показывает результаты немного слабее, чем хотелось бы. Вероятно, это связано с тем, что в многомерных пространствах стратегия улучшения наихудших решений требует более тонкой настройки параметров температуры и скорости охлаждения.
Тем не менее я считаю SRA достойным алгоритмом с потенциалом для дальнейшего улучшения. Его кулинарная метафора не только делает алгоритм понятным, но и открывает путь для интуитивно понятных модификаций, доработки механизма адаптивной мутации и можно поэкспериментировать с различными схемами отбора "донорских блюд".
Создавая алгоритм успешного ресторатора, я стремился не столько к достижению превосходства над существующими методами оптимизации, сколько к раскрытию новых концептуальных горизонтов через оригинальную жизненную метафору. Результаты исследования убедительно демонстрируют, что этот подход заслуживает своего места в экосистеме метаэвристических алгоритмов.
Неожиданно продуктивной оказалась идея фокусирования на худшем решении в популяции, используя его как базу для экспериментов — концепция, которая на первый взгляд может показаться бредовой. Однако, именно этот принцип "реабилитации аутсайдеров" раскрывает удивительный потенциал для оптимизации. Подобно искусному ресторатору, преображающему непопулярное блюдо в будущий хит, алгоритм трансформирует слабые решения в более совершенные, используя ингредиентный материал лидеров.
Этот опыт подтверждает ценное правило в научном поиске: даже самые неортодоксальные идеи при правильной реализации могут принести практическую пользу. Нестандартные подходы часто открывают те грани проблемы, которые остаются незамеченными при использовании традиционных методологий.

Рисунок 2. Цветовая градация алгоритмов по соответствующим тестам

Рисунок 3. Гистограмма результатов тестирования алгоритмов (по шкале от 0 до 100, чем больше, тем лучше, где 100 — максимально возможный теоретический результат, в архиве скрипт для расчета рейтинговой таблицы)
Плюсы и минусы алгоритма SRA:
Плюсы:
- Простая реализация.
- Хорошие результаты.
Минусы:
- Без серьезных минусов.
К статье прикреплён архив с актуальными версиями кодов алгоритмов. Автор статьи не несёт ответственности за абсолютную точность в описании канонических алгоритмов, во многие из них были внесены изменения для улучшения поисковых возможностей. Выводы и суждения, представленные в статьях, основываются на результатах проведённых экспериментов.
Программы, используемые в статье
| # | Имя | Тип | Описание |
|---|---|---|---|
| 1 | #C_AO.mqh | Включаемый файл | Родительский класс популяционных алгоритмов оптимизации |
| 2 | #C_AO_enum.mqh | Включаемый файл | Перечисление популяционных алгоритмов оптимизации |
| 3 | TestFunctions.mqh | Включаемый файл | Библиотека тестовых функций |
| 4 | TestStandFunctions.mqh | Включаемый файл | Библиотека функций тестового стенда |
| 5 | Utilities.mqh | Включаемый файл | Библиотека вспомогательных функций |
| 6 | CalculationTestResults.mqh | Включаемый файл | Скрипт для расчета результатов в сравнительную таблицу |
| 7 | Testing AOs.mq5 | Скрипт | Единый испытательный стенд для всех популяционных алгоритмов оптимизации |
| 8 | Simple use of population optimization algorithms.mq5 | Скрипт | Простой пример использования популяционных алгоритмов оптимизации без визуализации |
| 9 | Test_AO_SRA.mq5 | Скрипт | Испытательный стенд для SRA |
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Удаленный профессиональный риск-менеджер Forex на Python
Нейросети в трейдинге: Двойная кластеризация временных рядов (DUET)
Создание самооптимизирующихся советников на языках MQL5 и Python
Возможности Мастера MQL5, которые вам нужно знать (Часть 34): Эмбеддинг цены с нетрадиционной RBM
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования