Идём в глубь острова сокровищ с названием "Алгоритм".  Перед Вами новая статья серии "Что такое алгоритм?". И снова непростая задача. Нам необходимо "нырнуть глубже" в структуры памяти живого организма. К сожалению, в ракурсе, предлагаемом статьёй, это направление еще исследовано слабо. Что делает материал, приведённый далее, более сложным по сравнению с излагаемым в предыдущих частях, в которых использовалась близость с методами "генетических алгоритмов", автоматизированных систем управления, систем машинного обучения с учителем и подкреплением. Поэтому прокладывать тропинку в глубь неизведанных "территорий" процессов памяти придется во многом самостоятельно. С одной стороны это очень интересно. Ведь мы с Вами первопроходцы! А с другой стороны есть опасность "заблудиться". Чтобы приободрить в начале дороги, могу лишь сказать, что путь один раз уже пройден, туры сложены вдоль нашей дороги, карта местности прорисовывается, а клад в конце пути обещает быть внушительным. Но как бы ни был ценен конечный пункт назначения, текущая статья — просто еще один шаг в пути к эффективным методам работы с алгоритмами. И предлагаемые решения опять требуют обсуждения. Жду в комментариях конструктивную критику. Хочется еще раз упомянуть, что описание всех важных аргументов в поддержку полученных решений, не получается разместить в одной статье, в которой важно максимально подробно представить одну сторону теории. Поэтому подкрепление этих решений со стороны процессов коммуникации, обучения и формирования естественного языка будет приведено в следующих частях. Для вскрытия структуры памяти потребуются все результаты, полученные в предыдущих статьях серии (Часть 1 "Действие", Часть 2 "Исполнение", Часть 3 "Память"). Без перечисленных там выкладок читать дальше будет сложнее. Давайте приступим. Структура запоминания в мозге "немного" сложнее, чем было описано в статье №3. Для начала описания было необходимо представить эту структуру упрощенно и выделить только самое важное: Если посмотреть на множество алгоритмов в мозге "глазами программиста", то можно увидеть, что их совокупность похожа на программный проект в процессе развития. А что помогает программисту разобраться с незнакомым и запутанным проектом без документации? При наличии в проекте системы контроля версий ему будет полезно использовать анализ истории. В нашем "программном проекте мозга" нам тоже это может помочь. Нужно пробовать отследить переходы от более простых к последующим сложным состояниям "программного кода" и при этом записывать решения, фиксируемые каждым "коммитом". Если вспомнить генетиков, то этот способ — подобие эволюционной геномике. Но мы будем анализировать не структуру генов, а структуру Памяти. И, конечно, следует обратить внимание на то, что этот разбор скорее "археологический", реальной последовательности развития никто не видел, и она наверняка отличается от приведенной далее. Но для нас не так важен порядок этой последовательности. Важны принимаемые с каждым шагом решения развития. И, похоже, первое важное решение для организма было использование "действия". Но отложим немного новое рассмотрение действия организма. Потому что для начала необходимо указать на существующие факторы, помогающие природе осуществлять развитие тех алгоритмов организма, которые не завязаны на структуры его Памяти. Первым важным фактором ("двигателем" эволюции) является неравномерность распределения ресурсов и условий в среде обитания. Например, если в месте расположения организма в любой момент времени есть "Еда", то организму никогда не понадобится алгоритм "Двигаться в поиске еды", а вместе с ним может не понадобиться и обязательное действие этого алгоритма — действие("Двигаться"). Вторым фактором развития биологических организмов является смерть. Никогда бы не подумал, что придётся сказать фразу следующего содержания, но: "Смерть полезна". Она позволяет выполнить развитие алгоритмов в группе родственных организмов. И очень хорошо, что, используя Память, природа изобрела более эффективные способы синтеза алгоритмов, так что смерть современному программисту в своей работе не требуется. Но нам предстоит рассмотреть ранние этапы развития алгоритмов организма. Тогда в среде, где еда стала распределяться неравномерно, организмы, которые не научились двигаться, вымерли. А выжившие обзавелись действием("Двигаться"). Можно подумать, что нельзя придумать алгоритм для одного действия("Двигаться"), без использования датчиков, рецепторов выделяющих признаки. Но на самом деле это сделать нужно. Потому что в создании этого простого алгоритма появляется понимание, как организм синтезирует алгоритмы более сложные. Как организм может повлиять на действие? Он может его использовать или не использовать. Он может его использовать изредка и часто. Он может исполнять его периодически. Для организма в ситуации с едой, целесообразно использовать действие("Двигаться") время от времени: В виде цикла, описанного последовательностью действий, этот алгоритм можно было бы выдать программисту, но рассматриваемый организм еще не программист, и у него еще нет 10-ти пальцев и клавиатуры, чтобы "закодить" эту программу. Что может обеспечить исполнение периодического процесса в таком простом организме? Вариантов много. Например, это может быть некая структура с длительным накоплением потенциала и с выполнением быстрой разрядки накопленного потенциала по превышению некоторого порогового значения. Если за процесс разрядки этого потенциала зацепить исполнение действия, то получается реализация алгоритма циклического повторения действия. И время, затрачиваемое на накопления потенциала, определяет период такого цикла. Для дальнейшего повествования способ реализации периодического процесса не так важен, поэтому без перебора других вариантов примем за основу эту "функциональную базу". Первый алгоритм собран! Он тривиален, но уже может работать (помогать организму выжить). Его реализация доступна даже на биологической элементной "функциональной базе", а у программиста эта простая задача даже интереса не вызовет. Но перед тем как усложнить программисту ТЗ, давайте введём структуру описания "коммита" (этапа эволюции памяти). Для каждого этапа развития памяти необходимо указать следующие сведения:  Здесь, конечно, стоит уточнить, что использование Памяти на текущем шаге развития организма минимально (это лишь запоминание удачного интервала времени между запусками действия). И формируемый алгоритм не имеет свя́зного исполнения (в терминах статьи №2), что несколько умаляет его ценность. Но и бесконечный цикл бывает полезен программисту. А нам пора двигаться дальше и эволюционно ввести признаки в алгоритмы поведения организма. Давайте вернемся к примеру "Еда + Движение". В этом примере для исполнения действия("Двигаться") организму требуется "энергия" (не будем отвлекаться на уточнение типа энергии). Чтобы получить эту энергию организму необходима "еда". Поглощая энергию, запасенную в еде, организм накапливает эту энергию (потенциал действия) и при достаточном количестве — выполняет действие. Накопление энергии в указанном примере обусловлено внешними для организма признаками — количеством еды в текущем месте среды. Это очень похоже на описание функции "Накопление потенциала — разрядка исполнением". Но c точки зрения организма такая формируемая естественным образом стратегия является вредной. Потому что в месте, где много еды, организм быстро накопит потенциал, и стратегия вынудит поменять это место на новое. А еды в новом месте может не быть. Значит накапливаемый потенциал исполнения действия должен быть внутренним процессом, и как показывает рассмотренный пример "убегания от еды", даже при накопленном потенциале полезно не использовать действия("Двигаться"), если в текущем месте много еды. Мы нашли новый эволюционный фактор! Значит надо делать шаг развития.  И было бы всё хорошо с организмом и его алгоритмом поочередного перемещения и поедания еды. Но среда изменилась, и в следующем этапе организм сам стал едой для более проворных организмов-хищников. В такой среде полезно убегать, то есть исполнять действие("Двигаться") в ситуации, когда рядом опасность (хищник). Предыдущим предложением мы записали новый эволюционный фактор, значит пора формировать новый тип алгоритма поведения. На этот раз новый тип алгоритма — это рефлекс (почти в классическом его биологическом значении).  По общей схеме, не потребовавшей от организма никаких новых функциональных возможностей, произошло построение двух следующих типов алгоритмов, использующих объединение признаков по ИЛИ (OR). Простота их структуры позволяет сразу перейти к их табличным формулам. Первой рассмотрим универсализацию нескольких ограничений.  Универсализация нескольких признаков для рефлекса представлена далее.  На этом этапе простая и классическая часть повествования закончилась. И мы переходим к интересным "сложностям". Как и прежде этап начинается с неприятного подарка среды, подготовленного для "многострадального" организма. Этот "подарок" — возможность нахождения и "еды", и "опасности" в одном месте. Организму никак не выработать алгоритм поведения на основе типов алгоритмов, которые имеются в его арсенале. Значит "придётся" развиваться.  Давайте рассмотрим в чём сложность текущего этапа в плане реализации. На этом этапе появляется необходимость запоминать и сопоставлять соотношение полезности для ранее синтезированных алгоритмов поведения. Для программиста эта операция — лишь добавление весов к условию и к ограничению, и последующая коррекция этих весов по результатам оценки полезности исполнения действия при одновременном участии в инициализации исполнения этих признаков (условия и ограничения). Причём коррекция весов может быть "глобальной процедурой". То есть затрагивать большое количество не используемых в текущий момент признаков. Она обеспечивается простым увеличением веса одного текущего признака. Но при этом меняются все соотношения с весами других связанных признаков. И после изменения веса этого признака для сохранения в рабочем состоянии ранее выявленных приоритетов признаков необходимо выполнить процедуру внесения поправок в веса всех существующих признаков, которые связанны приоритетами с измененным. Такая глобальная коррекция очень накладная операция, и в большом множестве связанных признаков может стать неразрешимой в силу наличия циклических зависимостей. Вторым и более эффективным способом коррекции является локализация сочетания исходных признаков (конкретного условия и ограничения) путем формирования на их основе макро-признака и синтеза цепочки-алгоритма с завязыванием действия уже на этот макро-признак. Тогда можно не модифицировать весов исходных признаков, то есть не нужно проводить глобальной процедуры внесения поправок в уже связанные приоритетами другие признаки. И новую стратегию с приоритетом её использования становится проще выработать. Ведь у макро-признака отдельный вес! Скорее всего объединение этих двух способов коррекции весов и является способом биологического решения, где первый вариант во многих ситуациях позволяет найти сочетание приоритетов стратегий, синтезированных и используемых организмом даже с простой организацией структуры памяти. А вариант второй служит решением комплексной сложности при увеличении в памяти количества признаков. В любом случае мы переходим к одному из наиболее важных процессов в памяти — группировке признаков. Цепочки памяти во всех предыдущих этапах были односвязными. То есть в них запоминалась (то есть укреплялась) и взвешивалась (то есть оценивалась пользой) одна связь "признак-действие". Для разбора группировки признаков нужно запоминать больше связей. На этом этапе появляется необходимость в объединении связей в "цепь" друг за другом. И у появления такой цепочки опять есть виновница — это среда, подбрасывающая организму новые и особые ситуации, в которых полезно исполнить действие (или, наоборот, вредно его исполнять). При этом особенность каждой такой ситуации заключается в характерном одновременном наличии в среде двух (и более) признаков. И каждый из этих признаков, появляющийся в среде по отдельности, не достаточен для детектирования этой особенной ситуации. Если перейти на "программистский", то организму необходима операция И (AND) по признакам. К счастью для природы биологический вариант этой операции получился не такой ограниченный как у программиста, и его первоначальный синхронный вариант можно достаточно легким преобразованием "распространить" во времени, что обеспечивает организм возможностью детектирования не только синхронного появления признаков, но и появления последовательного (с фиксированными временными интервалами).  Теперь опишем "сложности" признаковой операции И (AND) и особенности их решения методом построения цепочки. Первая и самая главная сложность состоит в том, что если количество базовых признаков у организма , то количество макро-признаков, которые возможно выделить на синхронном парном сочетании из этих признаков — . Это число больше  (для ). И общее число макро-признаков увеличивается с добавлением каждой дополнительной возможности детектировать сочетания базовых признаков. Таких возможностей как: То есть количество макро-признаков может быть очень большим. Если на каждое появления сочетания базовых признаков пробовать применять действие и ждать подкрепление от среды или учителя, то процесс перебора обещает быть настолько долгим, что времени жизни организма может не хватить на построение алгоритма, использующего полезный макро-признак. К счастью для организма в нашей среде полезность макро-признака можно проверить без выполнения действия и без ожидания подкрепления от среды или учителя. Способ это осуществить — выявление Повтора (которому посвящена статья №3). Только повторяющиеся сочетания-последовательности ("узоры") из базовых признаков являются полезными для построения алгоритма (статья №1). Поэтому на иллюстрации группировки признаков оранжевая линия стрелок, представляющая собой цепочку, ограничена своей областью. Эта область ответственна за выявление макро-признака с оценкой повторяемости. В ней "записываются" последовательности базовых признаков, и в сопоставлении с записью определяются повторные появления таких же последовательностей. Каждое появление повтора записанной последовательности укрепляет запись этой последовательности, то есть укрепляет её формирующие связи. А те связи, которые не прошли проверку, в итоге могут ослабеть и использоваться для записи нового сочетания базовых признаков. Описанный способ отделения формирования макро-признака от оценки исполненного действия позволяет: Примечательно, что если посмотреть в сторону технологии машинного обучения с использованием нейронных сетей, то использование свёрточных слоев имеет в своей основе похожее решение, описывающее способ изолировать "обучение" выделяемых признаков фрагментов предыдущего слоя от решений принимаемых по этим признакам на слое следующем. Тем самым получается выстроить иерархию признаков с минимизацией влияния подкрепления от обучающего механизма обратного распространения ошибки на внутренние слои и сосредоточение этой функции (обучения ошибками) на слое конечном, где для каждого макро-признака учитель назначает "имя". Если перейти от искусственной нейронной сети, работающей с изображением, к зрительной коре, то почти общепринято, что механизма обратного распространения ошибки там нет. Макро-признаки изображения (и движений) в биологическом варианте учатся полностью "автономно". Возможно биологическое решение распознавания зрительных образов — Повтор?? И если признак повторяемости является дискуссионным в биологическом распознавании зрительных образов, то его использование для группировки действий — сомнения почти не вызывает (вспомним пример игры на фортепиано, рассмотренный в статье №3). Основа способа формирования алгоритма, использующего последовательность действий, — это повтор организмом требуемой последовательности действий! Но о каких действиях мы говорим? Ранее у организма мы рассматривали лишь одно действие, и он учился им пользоваться с пользой для себя. Такое ограничение было использовано намеренно (в угоду простоты описания вышеизложенных шагов развития). Давайте пожалеем организм и снимем это ограничение. И на этот раз нам нужен эволюционный фактор, потребовавший от организма группировки действий. Этим фактором стало наличие ситуаций, в которых бóльшей полезностью обладает последовательность действий по сравнению с их одиночным исполнением.  Схема, конечно, красивая. Но. Давайте разберем эти "сложности" по порядку. Ответ на первый вопрос (о способе подборе действий) достаточно прост. Таким способом является то, что биологи называют игровой активностью. Справедливости ради стоит сказать, что не все аспекты игровой активности выделимы на рассматриваемом этапе развития организма. Многие её важные компоненты необходимо рассмотреть отдельно (что запланировано сделать в следующей статье). Но основа игровой активности уже видна — это спонтанная активация организмом своих действий (обусловленная признаками или накоплением внутреннего потенциала) и анализ признаков и подкреплений, полученных в результате. После спонтанного выполнения действия у организма есть два способа проверить полезность этого действия в пережитой ситуации. Первый способ привычный нам и хорошо проработанный — подкрепление от среды или от учителя. Но есть и способ другой. И для его реализации нам снова на выручку приходит Повтор. Этот способ помогает организму определить, что исходная ситуация, описанная признаками, после воздействия исполненных действий трансформировалась в новую ситуацию. И признаки исходной ситуации, сопровожденные такими действиями, каждый раз приводят к признакам ситуации конечной. Выделив такой закон повторением, "игривый" организм сохраняет цепочку-алгоритм даже не получив подкрепления. И снова переходит в режим спонтанного поиска новых алгоритмов. Второй вопрос сложнее. Но можно сделать несколько предположений по поводу хранения оценки полезности цепочки действий. Самым легким решением является хранение этой оценки на стыке признака исходной ситуации и цепочки, обеспечивающей последовательность действий реакции. То есть во входном признаковом узле области. Активация этого узла будет тормозиться, в случае если стратегия запомненная организмом вредна, и обеспечит торможение последующих действий цепочки. А последний вопрос — самый простой. Потому что мы на него уже почти ответили на этапе "Группировки признаков". Цепочку из последовательности действий организм синтезирует в области "Памяти", в которой запоминается последовательность активации узлов отвечающих за старт исполнения действий, например, спонтанно исполняемых организмом в игре. Единственным (и не ключевым) отличием от группировки в цепочку узлов признаков является связь рассматриваемых на этом этапе внутренних узлов с инициализацией внешних действий организма. Общая схема памяти завершена? Хотелось бы чтобы всех перечисленных этапов было достаточно, чтобы завершить разбор процессов протекающих в мозге. Но пока это не так. Природа долго работала и на основе уже описанного создала действительно красивый инструмент по работе с алгоритмами. В следующих статьях нам придется познакомиться с большим количеством шагов развития и эволюционных факторов, толкнувших организм на введение: Мы на финальной черте этой статьи. Высадка на остров сокровищ "Алгоритм" произошла. Она получилась длиннее (по количеству букв), чем мне бы этого хотелось, но нас не должно волной прибоя отбросить обратно в море. Поэтому пришлось укрепиться на берегу основательней. С другой стороны количества букв в статье явно не хватает, чтобы описать всё что хочется рассказать, и некоторые подводные камни остались неосвещенными за бортом повествования. Есть предложение — выстроить диалог обсуждения этих сложностей в формате вопрос-ответ в отдельной ветке Issues (Open source (GPL) проекта на GitLab). Да, и совсем забыл про яблоко. Этот бессменный спутник моих публикаций пролетел мимо всех иллюстраций текущей статьи. Это несправедливо. Пусть хоть в заключении его подержит главный весельчак острова сокровищ — доктор Ливси.  Спасибо Вам за внимание. Буду очень благодарен за отзывы, пожелания и предложения, так как они помогают мне скорректировать направление развития своей работы. Отдельное волнение у меня есть по стилю повествования и форматированию, используемым в статье (кавычки, абзацы, курсив). Напишите, пожалуйста, если у Вас есть замечания к ним. Можно личным сообщением. Наука и Разработка программных комплексов