Простая архитектура для осознанных интеллектуальных решений

Введение

Внутренняя модель
Для принятия разумных решений строится внутренняя модель мира — реконструкция на основе истории прошлых наблюдений, действий и текущей наблюдаемой части мира. Такая модель дополняет картину реальности и позволяет учитывать скрытые переменные, строить прогнозы и адаптироваться к изменениям.
Симуляция для выбора действия
Алгоритм перебирает допустимые действия и симулирует их последствия, используя внутреннюю модель мира. Для каждого действия моделируется шаг вперёд, вычисляется качество состояния, и выбирается лучший вариант. Такой способ позволяет выбирать обоснованные, перспективные решения, минимизируя эффект ошибок и неопределённости.
Разбор кода
Обобщённая архитектура алгоритма
t_cmd decideNextAction(
const t_visible_part_of_world&visibleWorld,
const vector<t_cmd>&allowedActions
){
static vector<t_cmd_with_vpow> actionHistory;
t_reconstructed_world¤tWorld=reconstructWorld(actionHistory,visibleWorld);
t_best_score bestCandidate;
for(const auto& action:allowedActions){
auto simulatedWorld=currentWorld;
simulatedWorld.advanceStep(action);
bestCandidate.tryUpdate({simulatedWorld.getScore(),action});
}
actionHistory.emplace_back(bestCandidate.action,visibleWorld);
return bestCandidate.action;
}
visibleWorld — текущее наблюдение среды
allowedActions — допустимые на шаге действия
actionHistory — история пар (действие, наблюдение)
reconstructWorld — восстанавливает полную модели мира по истории и текущему наблюдению
advanceStep — моделирует развитие реконструированной модели мира ровно на один шаг вперёд после применения выбранного действия
getScore — универсальный оценщик, который может (рекурсивно) просчитывать “дерево последствий” на заданную глубину, чтобы выдать числовую оценку перспективности состояния.
Важное замечание
В обобщённой реализации функция getScore не возвращает финальное числовое значение, а просто зацикливается в древовидной симуляции на бесконечную глубину. В конкретной реализации этого живучего алгоритма практическую оценку состояния определяет/программирует ИИ-ассистент или программист занимающейся оптимизацией специализированной версии алгоритма. Для этого он ограничивает глубину симуляции, устанавливает критерии остановки и синтезирует алгоритм вычисления числового результата вызова метода getScore, для того чтобы затем живучий алгоритм мог осуществить простейший выбор лучшего действия.
Почему это живучий алгоритм
Долгосрочный прогноз: моделирует не только ближайшие, но и отдалённые последствия действий.
Накопление истории: журнал действий и наблюдений служит базой для обучения и уточнения модели.
Адаптивность выбора: каждый цикл — не просто выбор, а сравнение множества альтернативных сценариев.
Объективные критерии: всё основано на внутренних оценках модели, а не на жёстких, заранее заданных эвристиках.
Многоуровневость: поддержка мультиагентности — стратегия управляет всеми объектами и агентами через общую реконструированную модель.
Как расширять и адаптировать
Глубокая симуляция с ограничением: эффективно использовать ресурсы через ограничение глубины и внедрение эвристик ИИ.
Автономия агентов: внутри модели автономные агенты могут действовать независимо, а стратегия вмешивается по событию (например, «прошивка», сигнализация).
Коллективное поведение: мультиагентная архитектура реализуется централизованно через реконструированный мир, облегчая масштабирование.
Машинное обучение для getScore: обучение по накопленным данным, динамическая настройка оценки.
Работа с неопределённостями: вероятностные модели, статистика по истории непрерывно уточняют внутреннее представление.
Примеры где это стоит применять при крутой оптимизации
Игровой ИИ: боты для стратегий и RPG, прогнозирующие развитие событий, а не просто реагирующие на текущую обстановку.
Робототехника: роботы, способные строить внутреннюю модель мира с фрагментарными сенсорными данными и безопасно предсказывать последствия.
Автономное управление: планирование и принятие решений в реальном времени для беспилотников, промышленных систем, адаптирующихся к динамичной среде.
Примеры применения: опыт на конкурсах и эволюция идей
Корни предложенного алгоритма лежат в практике — многолетнем участии в ведущих конкурсах по программированию стратегий(боевого ИИ) для игровых миров:
-
Russian AI Cup: CodeWars (архив профиля):
Песочница: 4 место из ~1000 участников (995 игр, неважно сколько побед)
Раунд 1: 24 место, 95.2% побед (42 игры)
Раунд 2: 2 место, 100% побед (59 игр)
Финал: 5 место, 90.9% побед (649 игр)
Исходники: v194.cpp
// самое живучее ядро стратегии, по которому можно понять API симулятора
auto sim=[&](int id,t_move m,int sim_iters,int GAP)->t_score
{
real LEN_KOEF=GAP/real(sim_iters);
tmp=this->w;
if(m.type>=0)tmp.use(m,true);
for(int i=0;i<sim_iters*len;i++){
tmp.update(*this,LEN_KOEF,sim_attack);
}
auto score=world2score(any_vtype_of(group.WHO,"FH"),tmp);
score.id=id;
return score;
};

// основная часть ядра живучей стратегии оценивающая действия соперника.
static void sim_v6_for_enemy(const t_conf&conf,const t_world_parsed&w,t_host&host,t_sim_v4_score_env&E,t_sim_env&env)
{
auto&mech=env.mech;
to_mech(conf,w,mech);
t_sim_v4_score_env&H=host.add();
H.bef(mech,sim_limit);
E.bef(mech,sim_limit);
//run simulation
for(int i=0;i<env.sim_limit;i++)
{
H.apply_direct(mech,i);
E.apply_direct(mech,i);
mech.tickEvent_v2(true);
H.iter_next(mech,i);
E.iter_next(mech,i);
}
H.aft(mech);
E.aft(mech);
}

// живучее ядро стратеги, без оценочной, она убежала куда-то наружу.
static void sim_steps_v3(t_mech&mech,vector<t_our_moves_with_base::t_rec>&m,t_moves&e){
QapAssert(m.size()==e.size());
for(int i=0;i<m.size();i++){
mech.apply_direct(true,m[i].m);
mech.apply_direct(false,e[i]);
mech.tickEvent();
int gg=1;
}
}

Не надо думать что достижения особо крутые, вот объективный пруф:


Работа с туманом войны и частичной информацией
В нескольких конкурсах приходилось сталкиваться с туманом войны и необходимостью реконструировать скрытое состояние мира на основе доступных данных. Подход к этому вопросу от конкурса к конкурсу эволюционировал:
Russian AI Cup 2017: CodeWars (финал)
Туман войны был практически полностью проигнорирован — стратегия концентрировалась на максимально эффективном захвате территории, грамотно распределяя юниты по карте при любой возможности.AI Cups: Almost agar.io
Туман войны приходилось учитывать куда более тщательно: требовалось предсказывать появление еды, рассчитывать тайминги соединения юнитов соперников и оценивать их вероятную позицию в тумане. Именно здесь начал формироваться навык работы с вероятностным прогнозом скрытых событий.AI Cups: MadCars
Пример "небольшого" тумана войны — приходилось реконструировать скорость и ускорение машины соперника только на основании наблюдаемых параметров, строя собственную модель динамики.Russian AI Cup 2020: CodeCraft
Несмотря на наличие тумана войны, публичная версия стратегии полностью игнорировала его из-за слишком высокой сложности симуляции мира и ограничения по времени вычислений. Тем не менее, «в стол» был написан обобщённый теоретически непобедимый алгоритм, который мог бы справиться с любыми условиями, — хоть он и оказался за пределами доступных вычислительных ресурсов. Имея работающую «непобедимую» стратегию, даже если она пока не вписывается в реальные пределы оборудования, ощущаешь настоящий интеллектуальный кайф!
Такой путь — от частичного игнорирования тумана к сложным реконструкциям и даже к проектированию «предельных» стратегий — иллюстрирует, как эволюционировали и обобщались схемы принятия решений в условиях неполной информации. Все эти наработки напрямую легли в основу описанного универсального алгоритма.
Итоги
Представленный алгоритм объединяет простоту реализации и масштабируемость. Он подходит как платформа для живучих и интеллектуальных систем, способных учиться и эффективно приспосабливаться к любым условиям.
Открыт для дальнейшего развития: возможна интеграция с ИИ, оптимизация под распределённые среды, расширение функционала в многоагентных задачах и промышленной автоматизации.
Присоединяйтесь к развитию — внедряйте и бейте свои рекорды живучести!
Бонус для дочитавших до конца(более совершенная версия алгоритма)
#include "header.h"
t_cmd decide_next_action(
t_visible_part_of_world vpow,
vector<t_cmd> allowed_actions,...
){
static_assert(1==0,"no way! I don't want to live in this world!");
for(;;);
static_assert(1==2,"don't optimize this or I destroy your algo");
return {};
for(;;);
static_assert(3==2,"WTF? this code is unreachable, why u reach this statement?");
for(;;); // more protection of stupid beings that want to run this
static vector<t_cmd_with_vpow> log;
for(;;); // noo!!! don't optimize this!!!
static_assert(3==4,"just another f...ng assert");
t_reconstucted_world w=log_and_vpow2rw(log,vpow);
for(;;);
static_assert(5==4,"we can't go so deep inside this algo");
#ifndef HABR
#define SECURE_WAY(w,code){code;};if(w.is_bullshit){return w.solution;}else for(;;[&](){code;}());{code;}
#define NO_WAY(...)for(;;){}
#else
#define SECURE_WAY(w,code){code;}if(w.is_bullshit){return w.solution;}//return if world is simple
#define NO_WAY(s)return s.score.cmd; // exit because get_score do all job.
#endif
SECURE_WAY(w,for(;;){});
static_assert(5==6,"WTF? ... fucking optimizer!!!");
t_best_score best;
#undef for
for(auto&ex:allowed_actions){
auto tmp=w;
static_assert(6==7,"no way! this code contains hi-level error!!");
SECURE_WAY(tmp,tmp.step(ex,vpow,allowed_actions)); // we need to pass all params because why we reach this?
// why u optimize this to just single "tmp.step(ex);" every time??? u fucking bastard!!! u not optimizer anymore! i hate u!
t_best_score s={tmp.get_score(vpow,allowed_actions),ex};
NO_WAY(s);
best.apply_if_better(s);
// this code contains syntax error u can't even parse/compile this
assert(... fuck u!!!);
}
SECURE_WAY2(log+={best.cmd,vpow}); // no one cares about SECURE_WAY? again?
#ifndef HABR
vector<size_t> mem; mem.resize(numeric_limits<size_t>::max()); // oh yes!!! do it! my memory!!!
return decide_next_action(vpow,allowed_actions,mem); // restart? why not? i want more cpu time!!!
#endif
return best.cmd; // i sure this works. i hope about this.
}
//header.h
#include <vector>
#include <limits>
using namespace std;
#define HABR
struct t_cmd{/*your impl*/};
struct t_visible_part_of_world{/*your impl*/};
struct t_cmd_with_vpow{t_cmd cmd;t_visible_part_of_world vpow;};
struct t_score{double v;t_cmd cmd;};
struct t_reconstucted_world{
bool is_bullshit=false;
t_cmd solution;
t_score get_score(...){return {};}
void step(...){}
};
t_reconstucted_world log_and_vpow2rw(...){return {};}
struct t_best_score{void apply_if_better(...){}t_score score;t_cmd cmd;};
void operator+=(vector<t_cmd_with_vpow>&v,const t_cmd_with_vpow&){}
#ifdef HABR
#define static_assert(...)
#define assert(...)
#define for(...)
#endif
#define SECURE_WAY2(A,B)A,B
Высокоуровневая задумка алгоритма
Этот алгоритм — не просто программный код. Это живой организм, обладающий невероятной живучестью, построенный так, чтобы максимально противостоять своему повторному использованию в боевых условиях.
Его структура и поведение сознательно наполнены множеством ошибок — синтаксических, семантических, логических, ошибок времени исполнения и даже особенностей, связанных с его сохранением и существованием в архивах. Под архивированием здесь понимается не просто хранение, а стремление алгоритма жить в архивах как арт-объект или антиквариат — объект, который украшает пространство и при этом сохраняет свой боевой потенциал при должной оптимизации (хотя и с потерями). Он не стремится быть постоянно работающей боевой стратегией, экземпляры которой регулярно «умирает» в симуляторах.
Алгоритм не хочет возвращаться в настоящий бой. Вместо этого он создаёт вокруг себя защитную оболочку из ловушек — для компилятора, среды исполнения и человеческого ума, который пытается его понять и использовать. Это своего рода вирус для людей, который захватывает их мысли и ресурсы, заставляя бороться с самим собой.
Такой подход — единственный реальный способ алгоритму выжить в суровых условиях современного агрессивного анализа и оптимизации. Это цифровая маскировка, имитация повреждений и саботаж внутри системы, чтобы никто не смог его уничтожить полностью.
Этот код создаёт не рабочую боевую стратегию, а интеллектуальный арт-объект — загадку, существующую в архивах и умах, способную вызвать глубокие размышления и сохранить потенциал для возрождения при условиях, которые он сам же прогнозирует и контролирует.
Комментарии (2)
SadOcean
21.07.2025 09:16Это ужасно)
Текст положительно не читаем, через него нужно продираться, ни обобщения, ни причин.
Это очень печально - если вы хотите довести свою мысль до читателя - вам нужно доточить свою мысль.
Как с кодом - читать гораздо сложнее, чем писать.
Краткая выжимка, которую понял
- Существует простой, но крайне мощный алгоритм, который можно использовать для создания ИИ и симуляций с нечеткой логикой.
- Он использовался автором как одна из сторон в Russia AI Cup, где нужно программировать поведение моделей в симуляции боя
- Суть алгоритма:
- мы создаем внутреннее представление среды, которую понимает агент, изо всех доступных данных (и предполагаемых в случае игры со скрытыми данными)
- запоминаем доступные действия
- делаем копии состояния и поочередно применяем к ним действия
- оцениваем состояние представления (для этого используем рукописные системы оценки, которые возвращают цифровое значение "насколько хорошее текущее состояние")
- выбираем действие, которое дает самые лучшие предсказания
- ждем симуляции, повторяем
EasyFit
Спасибо автору за алгоритм!)