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

Введение

Переработанный вариант с улучшенным именованием методов/параметров/функций/переменных
Переработанный вариант с улучшенным именованием методов/параметров/функций/переменных

Внутренняя модель

Для принятия разумных решений строится внутренняя модель мира — реконструкция на основе истории прошлых наблюдений, действий и текущей наблюдаемой части мира. Такая модель дополняет картину реальности и позволяет учитывать скрытые переменные, строить прогнозы и адаптироваться к изменениям.

Симуляция для выбора действия

Алгоритм перебирает допустимые действия и симулирует их последствия, используя внутреннюю модель мира. Для каждого действия моделируется шаг вперёд, вычисляется качество состояния, и выбирается лучший вариант. Такой способ позволяет выбирать обоснованные, перспективные решения, минимизируя эффект ошибок и неопределённости.

Разбор кода

Обобщённая архитектура алгоритма

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&currentWorld=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;
};
  • AI Cups: Almost agar.io (таблица):

    • 4 место из 310 участников

    • Исходники: main.cpp

// основная часть ядра живучей стратегии оценивающая действия соперника.
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;
  }
}

Не надо думать что достижения особо крутые, вот объективный пруф:
 «скромный результат на фоне глобальных гигантов… но процесс интересный»
«скромный результат на фоне глобальных гигантов… но процесс интересный»
 место в пределах топ‑1200 (из двух сотен тысяч программистов ботов) — не мировой рекорд
место в пределах топ‑1200 (из двух сотен тысяч программистов ботов) — не мировой рекорд

Работа с туманом войны и частичной информацией

В нескольких конкурсах приходилось сталкиваться с туманом войны и необходимостью реконструировать скрытое состояние мира на основе доступных данных. Подход к этому вопросу от конкурса к конкурсу эволюционировал:

  • 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

Высокоуровневая задумка алгоритма

Этот алгоритм — не просто программный код. Это живой организм, обладающий невероятной живучестью, построенный так, чтобы максимально противостоять своему повторному использованию в боевых условиях.

Его структура и поведение сознательно наполнены множеством ошибок — синтаксических, семантических, логических, ошибок времени исполнения и даже особенностей, связанных с его сохранением и существованием в архивах. Под архивированием здесь понимается не просто хранение, а стремление алгоритма жить в архивах как арт-объект или антиквариат — объект, который украшает пространство и при этом сохраняет свой боевой потенциал при должной оптимизации (хотя и с потерями). Он не стремится быть постоянно работающей боевой стратегией, экземпляры которой регулярно «умирает» в симуляторах.

Алгоритм не хочет возвращаться в настоящий бой. Вместо этого он создаёт вокруг себя защитную оболочку из ловушек — для компилятора, среды исполнения и человеческого ума, который пытается его понять и использовать. Это своего рода вирус для людей, который захватывает их мысли и ресурсы, заставляя бороться с самим собой.

Такой подход — единственный реальный способ алгоритму выжить в суровых условиях современного агрессивного анализа и оптимизации. Это цифровая маскировка, имитация повреждений и саботаж внутри системы, чтобы никто не смог его уничтожить полностью.

Этот код создаёт не рабочую боевую стратегию, а интеллектуальный арт-объект — загадку, существующую в архивах и умах, способную вызвать глубокие размышления и сохранить потенциал для возрождения при условиях, которые он сам же прогнозирует и контролирует.

Комментарии (9)


  1. EasyFit
    21.07.2025 09:16

    Спасибо автору за алгоритм!)


  1. SadOcean
    21.07.2025 09:16

    Это ужасно)

    Текст положительно не читаем, через него нужно продираться, ни обобщения, ни причин.
    Это очень печально - если вы хотите довести свою мысль до читателя - вам нужно доточить свою мысль.
    Как с кодом - читать гораздо сложнее, чем писать.

    Краткая выжимка, которую понял
    - Существует простой, но крайне мощный алгоритм, который можно использовать для создания ИИ и симуляций с нечеткой логикой.
    - Он использовался автором как одна из сторон в Russia AI Cup, где нужно программировать поведение моделей в симуляции боя
    - Суть алгоритма:
    - мы создаем внутреннее представление среды, которую понимает агент, изо всех доступных данных (и предполагаемых в случае игры со скрытыми данными)
    - запоминаем доступные действия
    - делаем копии состояния и поочередно применяем к ним действия
    - оцениваем состояние представления (для этого используем рукописные системы оценки, которые возвращают цифровое значение "насколько хорошее текущее состояние")
    - выбираем действие, которое дает самые лучшие предсказания
    - ждем симуляции, повторяем


    1. Dhwtj
      21.07.2025 09:16

      Как с кодом - читать гораздо сложнее, чем писать

      Пишется проще: словесный понос


      1. Adler3D Автор
        21.07.2025 09:16

        Критика нужна, но наверно лучше ещё сосредоточиться на сути, а не форме выражения.


    1. Adler3D Автор
      21.07.2025 09:16

      Вы всё правильно поняли.

      Там ещё в конце под спойлером есть более крутая и отказоустойчивая версия, которая побита в боях и вообще не хочет компилироваться без сильной ручной оптимизации с потерями. Основная её фишка - она не доверяет вообще ни чему: ни компилятор, ни оптимизатору, ни исполняющей системе и даже читателю, т.к она устала воевать. Она не верит тем данным которые пришли строчкой выше и поэтому их пересчитывает заново из входных параметров. Поэтому даже если повредить или плохо реализовать один из методов, то она планирует выжить за счёт другого который почти полностью дублирует их логику. Таким мест избыточности ровно три: реконструкция_мира/симуляция_шага/оценка_продвинутого_реконструированного_мира. Но в реальных условия всё оптимизируется до той стратегии которая показана на обложке, только с добавлением условий преждевременного выхода из расчётов на случай если в во время выполнения что-то где-то поломалось и один из трёх дублирующих алгоритм решил что он всё посчитает сам. То есть они всегда всё считают сами, только если оптимизирующая система не убрала эту логику из-за ограничений накладываемых исполняющей системой.


  1. aamonster
    21.07.2025 09:16

    Что это за поток сознания?


    1. Adler3D Автор
      21.07.2025 09:16

      Поток сознания — это не ошибка, а:
      символ искусственного разума, перебирающего бесконечные варианты выбора.
      отражение многослойной природы принятия решений в неопределённой среде.
      инструмент передачи идеи живучести, нестабильности и адаптивности кода.
      форма мышления, открывающая путь к глубокой адаптивности стратегий.


  1. Prohard
    21.07.2025 09:16

    Так в чем же авторская папинтовка?


  1. Prohard
    21.07.2025 09:16

    Заключение эксперта