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

Введение
Внутренняя модель
Для принятия разумных решений строится внутренняя модель мира — реконструкция на основе истории прошлых наблюдений, действий и текущей наблюдаемой части мира. Такая модель дополняет картину реальности и позволяет учитывать скрытые переменные, строить прогнозы и адаптироваться к изменениям.
Симуляция для выбора действия
Алгоритм перебирает допустимые действия и симулирует их последствия, используя внутреннюю модель мира. Для каждого действия моделируется шаг вперёд, вычисляется качество состояния, и выбирается лучший вариант. Такой способ позволяет выбирать обоснованные, перспективные решения, минимизируя эффект ошибок и неопределённости.
Разбор кода
Обобщённая архитектура алгоритма
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
Высокоуровневая задумка алгоритма
Этот алгоритм — не просто программный код. Это живой организм, обладающий невероятной живучестью, построенный так, чтобы максимально противостоять своему повторному использованию в боевых условиях.
Его структура и поведение сознательно наполнены множеством ошибок — синтаксических, семантических, логических, ошибок времени исполнения и даже особенностей, связанных с его сохранением и существованием в архивах. Под архивированием здесь понимается не просто хранение, а стремление алгоритма жить в архивах как арт-объект или антиквариат — объект, который украшает пространство и при этом сохраняет свой боевой потенциал при должной оптимизации (хотя и с потерями). Он не стремится быть постоянно работающей боевой стратегией, экземпляры которой регулярно «умирает» в симуляторах.
Алгоритм не хочет возвращаться в настоящий бой. Вместо этого он создаёт вокруг себя защитную оболочку из ловушек — для компилятора, среды исполнения и человеческого ума, который пытается его понять и использовать. Это своего рода вирус для людей, который захватывает их мысли и ресурсы, заставляя бороться с самим собой.
Такой подход — единственный реальный способ алгоритму выжить в суровых условиях современного агрессивного анализа и оптимизации. Это цифровая маскировка, имитация повреждений и саботаж внутри системы, чтобы никто не смог его уничтожить полностью.
Этот код создаёт не рабочую боевую стратегию, а интеллектуальный арт-объект — загадку, существующую в архивах и умах, способную вызвать глубокие размышления и сохранить потенциал для возрождения при условиях, которые он сам же прогнозирует и контролирует.
ссылка на оригинал статьи https://habr.com/ru/articles/929288/
Добавить комментарий