Содержание

Что такое рекурсия, рекурсивный и итеративный процесс в программировании

В этой статье разбираемся, какой бывает рекурсия, как с ее помощью можно решать задачи и что такое рекурсивные функции.

  • Рекурсия vs рекурсивный или итеративный процесс: в чем разница
  • Методы решения задач с помощью рекурсии
  • В чем отличие рекурсивного процесса от итеративного
  • Что такое рекурсивные функции и в чем особенность их применения
  • Что такое хвостовая рекурсия

Вы читаете обновленную и улучшенную версию нашей старой статьи

Рекурсия vs рекурсивный или итеративный процесс: в чем разница

Рекурсия — это функция, которая вызывает саму себя, но с другими значениями параметров.

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

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

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

Читайте также: Что такое callback-функция в JavaScript?

Методы решения задач с помощью рекурсии

Есть два метода решения задач с использованием рекурсии: рекурсивный процесс и итеративный процесс. Рекурсия в них не отличается: в каждом из подходов функция вызывает саму себя, рекурсивно. Отличаются способы использования идеи рекурсии.

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

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

В чем отличие рекурсивного процесса от итеративного

Рекурсивный процесс на каждом шаге рекурсии говорит «я это запомню и потом посчитаю». «Потом» наступает в самом конце.

  • Если рекурсивный процесс считает факториал 6, то ему нужно запомнить 5 чисел, чтобы посчитать их в самом конце, когда уже никуда не деться и рекурсивно двигаться вниз больше нельзя
  • Когда мы находимся в очередном вызове функции, то где-то снаружи этого вызова в памяти хранятся эти запомненные числа

На этой картинке видно, как растет использование памяти: процессу нужно запоминать все больше и больше чисел

Рекурсивный процесс — это процесс с отложенным вычислением.

Итеративный процесс постоянно говорит «я сейчас посчитаю все что можно и продолжу» на каждом шаге рекурсии. Ему не нужно ничего запоминать вне вызова, он всегда все считает в первый возможный момент. Каждый шаг рекурсии может существовать в изоляции от прошлых, потому что вся информация передается последовательно.

  • Когда итеративный процесс считает факториал 6, то ему не нужно запоминать числа. Нужно лишь считать и передавать результат дальше, в новый вызов
  • Когда мы находимся в очередном вызове функции, снаружи этого вызова в памяти ничего не нужно запоминать

А на этой картинке видно, что использование памяти не растет.

Подытожим в шуточной форме. Рекурсивный процесс — это чувак, который все дела откладывает на вечер пятницы. В течение недели у него мало работы, а в пятницу завал. Но ему так нравится.

Итеративный процесс — это чувак, который все делает при первой возможности. У него работа равномерно распределена по неделе, а пятница — просто обычный день, но последний.

Что такое рекурсивные функции и в чем особенность их применения

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

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

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

Читайте также: Как проверить качество кода: функциональное и нефункциональное тестирование

В контексте каждого рекурсивного вызова такой функции хранится вся необходимая информация для его успешного выполнения. Он самодостаточен и никак не зависит от предыдущих контекстов. Помните, что этот чувак ничего не откладывает на потом, на вечер пятницы?

В наших практиках на Хекслете мы реализовывали такое поведение благодаря использованию аккумулятора acc, который передается в качестве аргумента из одного вызова в другой и накапливает в себе результат вычисления необходимого значения.

Получается, что, грубо говоря, на каком бы по уровню вложенности рекурсивном вызове мы не находились, все предыдущие уже не имеют значения и являются «бесполезной обузой», нагружающей память. Это распространяется в том числе и на самый последний рекурсивный вызов, где срабатывает терминальное условие. Он готов вернуть готовое вычисленное значение из функции сразу, ему не нужны для этого предыдущие контексты в стеке.

Что такое хвостовая рекурсия

Как использовать преимущества итеративного процесса и одновременно избавиться от недостатка рекурсивных функций, то есть от неумолимого роста использования памяти? Можно избавить процесс от заполнения стека «ненужными» контекстами предыдущих вызовов и обеспечить прямой возврат из функции при достижении терминального условия.

Для этого служит так называемая оптимизация хвостовой рекурсии (Tail call optimization). Итеративный процесс, который мы рассмотрели, как раз можно отнести к хвостовой рекурсии. Благодаря оптимизации состояния стека, она придает итеративному процессу вид «плоской» итерации. Так исключается его переполнение из-за большой глубины рекурсии.

Хвостовая рекурсия и ее оптимизация широко используется при написании программ на функциональных языках программирования.

Никогда не останавливайтесь: В программировании говорят, что нужно постоянно учиться даже для того, чтобы просто находиться на месте. Развивайтесь с нами — на Хекслете есть сотни курсов по разработке на разных языках и технологиях

Рекурсивные вычислительные системы

М. Б. Игнатьев, Ю. Е. Шейнин, Санкт-Петербургский государственный университет аэрокосмического приборостроения

Истоки разработки

В феврале 1972 г. на базе кафедры технической кибернетики в Ленинградском институте авиационного приборостроения (ЛИАП) была создана кафедра вычислительных систем и сетей, возглавил которую д.  т. н. М. Б. Игнатьев – один из авторов этих строк. С момента своего основания эта кафедра помимо традиционных направлений исследования в области робототехники стала развивать новое направление, связанное с разработкой развивающихся вычислительных систем нетрадиционной архитектуры.

В тот период в Советском Союзе шла борьба между двумя тенденциями дальнейшего развития вычислительной техники. Первая ориентировалась на проведение и совершенствование собственных разработок, таких, как серии машин БЭСМ, «Урал» и др. Вторая нацеливалась на использование зарубежного опыта, прежде всего копирование машин фирмы ИБМ.

Необходимо отметить, что в это время фирма ИБМ занимала практически монопольное положение в сфере производства ЭВМ и их продвижения на рынок, нередко при этом грубо нарушая законы о монополиях и ведя судебные процессы как в США, так и за рубежом. Этот монополизм проявлялся и в компьютерной литературе – там описывались машины ИБМ и почти ничего не говорилось о машинах конкурирующих фирм, например, Контрол Дейта Корпорейшен, Бэрроуз и др. В машинах же фирмы ИБМ реализовывалась классическая неймановская архитектура, которая в целом ряде ситуаций уже не могла удовлетворить потребителей.

В этой ситуации наша молодая кафедра, выделившаяся из кафедры технической кибернетики ЛИАП в феврале 1972 г., решила развивать нетрадиционные многопроцессорные вычислительные системы, которые в перспективе могли обеспечить более высокую производительность и надежность. Для нас такое решение было продолжением работ в области цифровых дифференциальных анализаторов, которые являлись многопроцессорными специализированными рекурсивными структурами с обратными связями, высокопроизводительными и надежными за счет введения избыточности методом избыточных переменных, который ранее был нами разработан [1, 2, 4–9]. Важный шаг был сделан доцентом ЛИАП В. А. Торгашевым, предложившим распространить и развить эти принципы на универсальные вычислительные машины. В итоге и родилась концепция рекурсивных машин, которая получила поддержку Государственного Комитета СССР по науке и технике в Москве и Института кибернетики во главе с академиком В.  М. Глушковым в Киеве. Сложился коллектив из москвичей, которых представлял В. А. Мясников, киевлян, руководимых В. М. Глушковым, и ленинградцев с общим центром в ЛИАП.

Наиболее ярко предложенная нами концепция была представлена в докладе на международном конгрессе ИФИП в Стокгольме в 1974 г. [10]. Этот доклад сделал М. Б. Игнатьев; советская делегация отнеслась к докладу очень холодно, зато иностранцы приветствовали доклад, который фактически ниспровергал компьютерные авторитеты и традиционную архитектуру и провозглашал нетрадиционную рекурсивную архитектуру. Так впервые советская компьютерная разработка была анонсирована на международной арене, что привлекло к ней внимание многих. Итогом этой акции явилось, во-первых, включение работы в программу ГКНТ с выделением финансирования на создание экспериментального образца рекурсивной машины; во-вторых, заключение соглашения с фирмой Контрол Дейта о создании образца рекурсивной машины на основе предложенных нами архитектурных решений; в-третьих, предоставление в наше распоряжение самой лучшей для того времени элементной базы и средств отладки. Руководителем рабочей группы по сотрудничеству с фирмой Контрол Дейта Корпорейшен стал М. Б. Игнатьев, который и в дальнейшем в этом качестве развивал проект по рекурсивной машине, и, в частности, занимался покупкой машины Сайбер для Ленинградского научного центра АН СССР.

На базе этой машины фактически организовался сначала Ленинградский научно-исследовательский вычислительный центр, а потом и Ленинградский институт информатики и автоматизации АН СССР.

Следует отметить, это было время некоторого потепления советско-американских отношений, сопровождавшееся и расширением научного сотрудничества, именно в этот период реализовывался, например, проект Союз-Апполон. Таким образом, в результате стечения благоприятных обстоятельств нам удалось развернуть деятельность по реальному созданию рекурсивной машины. Закипела работа, в которой принимали участие многие сотрудники нашей кафедры – В. А. Торгашев, В. И. Шкиртиль, С. В. Горбачев, В. Б. Смирнов, В. М. Кисельников, А. М. Лупал, Ю.  Е. Шейнин и многие другие. В результате к началу 1979 г. были изготовлены многие блоки машины, и в том же году экспериментальный образец рекурсивной машины был предъявлен государственной комиссии во главе с академиком А. А. Дородницыным.

В специальном Постановлении ГКНТ СССР и Комиссии Президиума Совета Министров СССР от 14.09.1979 г. за №472/276 отмечалось, что «запуск первого в мире экспериментального образца многопроцессорной рекурсивной машины высокой производительности и надежности является достижением мирового уровня». Были разработаны планы дальнейшего развития этой работы, но в декабре 1979-го советские войска вошли в Афганистан, и правительство США разорвало все научно-технические связи с СССР, в том числе и контакты по линии фирмы Контрол Дейта, что нанесло нам большой ущерб. Но начатая работа продолжалась, хотя к этому времени наш коллектив разделился – часть сотрудников во главе с В. А. Торгашевым в январе 1980 г. перешла в только что образованный Ленинградский научно-исследовательский вычислительный центр АН СССР, другая часть продолжала работать на нашей кафедре над созданием различных модификаций многопроцессорных систем. Отдел рекурсивных машин был создан в Институте кибернетики в Киеве. Таковы внешние контуры этой пионерской работы.

Принципы организации рекурсивных машин и систем

В математике существует большой раздел – рекурсивные функции [3]. Долгое время термин «рекурсия» употреблялся математиками, не будучи чётко определённым. Его приблизительный интуитивный смысл можно описать следующим образом. Значение искомой функции Ф в произвольной точке Х (под точкой подразумевается набор значений аргументов) определяется, вообще говоря, через значения этой же функции в других точках Н, которые в каком-то смысле предшествуют Х. Само слово «рекурсия» означает возвращение [17]. Рекурсивные функции – это вычислимые функции. По сути дела все вычислимые на компьютерах функции – это рекурсивные функции, но разные компьютерные архитектуры по-разному ведут вычислительные процессы. Чем лучше соответствует структура компьютера структуре задач, тем меньше затраты памяти и времени. Так что когда мы говорим о рекурсивных машинах, мы говорим о соответствии структур машины и решаемых задач, а так как задачи бывают разные, то структура машин должна гибко подстраиваться к структурам задач. Математика в настоящее время погружена в программирование, и в программировании рекурсивные операции распространены.

ЭВМ выступает как средство материализации логико-математических преобразований. ЭВМ являет собой иллюстрацию концепции потенциальной осуществимости, поскольку при отсутствии ограничений на время работы и емкость памяти любая ЭВМ в состоянии провести любые вычисления. Конкретное же протекание процессов вычисления проявляется лишь на уровне организации преобразований информации (задействуются конкретные регистры, коммутаторы, процессоры, линии передачи данных в определенном порядке и сочетании и т. д.). С этой точки зрения архитектура ЭВМ – это её структура в состоянии (процессе) реализации алгоритма, т. е. как бы ожившая структура. Философской основой такого представления является теория отражения, раскрывающая отображение категорий и явлений одной природы (числа, алгоритмы) на объекты другой природы (физические элементы, сигналы). Причем это отображение взаимно неоднозначно – алгоритму аj может соответствовать множество архитектур {А} и обратно – архитектуре Аj непосредственно не соответствует какой-либо алгоритм аj. Специфика взаимодействия {а} и {А} раскрывает глубинные свойства диалектического процесса развития математики и вычислительной техники как частного случая взаимодействия абстрактного и конкретного. Как отмечает С. А Яновская, «лицо машинной математики все более зависит от развития философских и логических оснований математики» [23]. Не представляется возможным непротиворечивая формализация отображения {а} -> {А} из-за его неоднозначности. Поэтому построить соответствующую аксиоматическую теорию проектирования ЭВМ не представляется возможным [24].

Когда мы формулировали принципы организации рекурсивных машин, мы исходили из потребностей развития вычислительных машин и систем. Мы получили множество авторских свидетельств [13, 14, 15 и др. ], это был интересный творческий процесс и с точки зрения достоверности сделанного тогда, в 1974–1979 гг., стоило бы полностью воспроизвести наш доклад на конгрессе ИФИП в Стокгольме [10]. Он содержал анализ недостатков машин традиционной архитектуры, ревизию принципов фон Неймана, принципы архитектуры рекурсивных машин, основные особенности языка рекурсивных машин, фрагментарное описание рекурсивной машины.

В качестве иллюстрации рекурсивной структуры можно привести систему 3М – модульную микропроцессорную систему [18]. Система 3М строится из модулей трех типов – операционных, коммуникационных и интерфейсных. Операционные модули выполняют основную работу по обработке данных, реализации объектов математической памяти, процессов определения готовности и выполнения операторов программы на внутреннем языке. Коммуникационный модуль предназначен для реализации коммуникационной системы – установления логического соединения между модулями, обмена информацией между модулями, поиска в системе ресурсов запрошенного типа. Интерфейсные модули подключаются к внешним устройствам своими блоками ввода-вывода. Вопросы организации обмена информацией с внешним миром имеют большое значение для существенно многопроцессорных систем, оказывают значительное влияние на их фактические характеристики. Различные классы задач требуют разной интенсивности обмена с внешними устройствами. Вычислительная система должна обеспечивать построение таких ее конфигураций для каждого конкретного применения, которые бы обладали оптимальными для этого применения характеристиками по вводу-выводу. Система 3М обеспечивает инкрементное наращивание вычислительной мощности до любого необходимого значения путем подключения дополнительных блоков без внесения изменений в имеющуюся систему и ее программное обеспечение как на этапе разработки системы, так и в ходе ее эксплуатации. Методология проектирования и реализации системы 3М базируется на рассмотрении вычислительной системы как иерархии виртуальных машин. Система 3М имеет рекурсивно-организованную многоуровневую структуру. Рекурсивность структуры состоит в том, что структура всякой модификации системы задается рекурсивным определением. Динамически меняющиеся в ходе вычислений виртуальные процессы требуют постоянной динамической реконфигурации связей между модулями. В настоящее время реализуются системы, содержащие тысячи и миллионы процессоров.

Экспериментальная реализация параллельных вычислительных систем для динамических параллельных вычислений

Ниже в хронологическом порядке рассматриваются экспериментальные образцы, разработанные начиная с 1974 года.

1979 год

Первой параллельной ВС на микропроцессорных СБИС стал разработанный в 1979 г. экспериментальный четырехпроцессорный образец Рекурсивной ЭВМ (РВМ).

Структура экспериментального образца микропроцессорной РВМ

Экспериментальный образец РВМ включал два вычислительных модуля, один коммуникационный модуль и интерфейсный модуль (процессор ввода-вывода). Его структура представлена на рис. 1. Построенный на секционных микропроцессорах, он показал принципиальную возможность создания модульных параллельных ВС с распределенной архитектурой, с распределенными параллельными вычислениями. Их эффективная поддержка реализовывалась в архитектуре и структуре модулей параллельной ВС – вычислительных модулях, реализовывавших собственно вычисления и новые механизмы децентрализованного управления; в коммуникационных модулях, аппаратно-микропрограммно реализовывавших протоколы коммуникационной системы для взаимодействия параллельных процессов, идущих в вычислительных модулях. Операторы внутреннего языка РВМ – языка высокого уровня, соответствовали среднегранулярным, микропрограммно-реализованным процессам обработки информации. Управляющие операторы внутреннего языка реализовывали основные механизмы управления параллельными вычислениями на уровне сети таких операторов.

1982–1985 гг.

Диплом ГКНТ СССР за разработку высокопроизводительных рекурсивных многопроцессорных комплексов

По результатам испытаний экспериментального образца микропроцессорной ВС были организованы работы по созданию высокопроизводительных параллельных ЭВМ – Рекурсивных ЭВМ. Они проводились в сотрудничестве ИК и ЛИАП с привлечением ряда промышленных организаций. В Институте кибернетики АН УССР создавался образец большого вычислительного комплекса – макроконвейерного вычислительного комплекса для решения больших задач, в ЛИАП (ныне СПбГУАП) – модульная масштабируемая параллельная ВС «Система 3М» на микропроцессорной элементной базе. Было создано два параллельных ВС – большая макроконвейерная ВС класса mainframe для вычислений большой разрядности (64–128 разрядов), с перспективами масштабирования на уровень суперкомпьютерных ВС, – в ИК АН УССР, и в ЛИАП – модульная масштабируемая микропроцессорная ВС «Система 3М», для решения задач с разрядностью 16–32 разряда. Работа было высокого оценена государственной комиссией ГКНТ СССР (рис. 2).

Проект 32-процессорной микропроцессорной параллельной ВС «Система 3М»

В проекте «Системы 3М» большое внимание уделялось модульности и масштабируемости. Общая структура проекта «Системы 3М» приведена на рис. 3, который иллюстрирует топологию этой системы. Структура разработанной параллельной ВС включала 32 вычислительных модуля, 16 коммуникационных модулей. Модульная структура с рекурсивно определяемой топологией связи обеспечивала масштабирование параллельной ВС путем увеличения числа модулей при сохранении как структуры модулей, так и системного и прикладного ПО.

Структура экспериментального образца параллельной ВС «Система 3М»

Поддержка свойства масштабируемости в системных механизмах распределенной ОС и коммуникационных модулей позволяет создавать на типовых узлах ограниченной номенклатуры программно-совместимые параллельные ВС с широким диапазоном характеристик по производительности, объему памяти и пропускной способности ввода-вывода (использовалось три типа модулей – вычислительные модули, коммуникационные модули и интерфейсные модули).

Общий вид экспериментального образца параллельной ВС «Система 3М»

Был создан экспериментальный образец «Системы 3М» (рис. 4, 5), разработано его системное ПО, проведен большой комплекс исследований и экспериментов по решению на нем прикладных задач различного класса.

1986–1988 г.

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

При реализациях параллельных ВС на готовых микропроцессорных узлах (спустя десятилетие этот подход получил название COTS – Commercial Off The Shelf) функциям и свойствам ВМ уровня логической структуры на уровне физической структуры наиболее полно будет соответствовать пара ВМ – терминальный коммуникационный модуль (ТКМ). Комбинация ВМ-ТКМ дает основу для реализации полного набора функций ВМ. ТКМ в таких системах подключается на системную (локальную) шину серийного микропроцессорного узла (Q-bus, VME, PCI) и занимает место коммуникационного контроллера (КК).

Параллельная ВС на базе серийных микроЭВМ «Электроника 81Б»

Параллельная ВС такого класса была разработана нами на основе серийной микроЭВМ «Электроника 81Б», пригодных и для возимых, и для бортовых применений (рис. 6). На стандартную системную шину (для «Электроники 81Б» – шина Q-bus) в качестве КК подключается специальная относительно несложная плата, реализующая высокоскоростной дуплексный внутрисистемный интерфейс параллельной ВС. Учитывая ограниченный диапазон масштабируемости для разрабатывавшихся параллельных ВС, а также целевые области применения, в данном проекте параллельной ВС (название «РВМС» – Распределенная мультипроцессорная ВС) была принята линия на перенос сложности реализации внутрисистемных протоколов с КК вычислительных модулей на коммуникационные модули. Для РМВС в качестве КМ был разработан специализированный коммуникационный транспьютерный модуль РТ841. Аппаратно-микропрограммная реализация внутрисистемных протоколов нижнего уровня, доступный микропрограммный уровень и специализированные на логическую обработку параллельные блоки при достаточно высокой тактовой частоте позволили сбалансировать характеристики коммуникационной системы на базе такого ТКМ с максимальной пропускной способностью, которую могут обеспечить вычислительные модули на базе «Электроники 81Б», в конфигурациях до 8 вычислительных модулей на один КМ. Большие конфигурации (до 18 ВМ) комплексируются с использованием 3 КМ, объединенных в полносвязанную структуру, где удельная пропускная способность КС (пропускная способность на 1 ВМ) остается в том же диапазоне, что и для базовой мультипроцессорной конфигурации с одним ВМ. Для созданного в ЛИАП экспериментального образца РМВС (конфигурация с 8 ВМ и 1 КМ) была разработана распределенная ОС, система программирования на языке Си, система отладки с распределенным отладочным монитором («РОМ») [25]. Операционная система РМВС послужила прообразом разработанной в 90-х годах операционной системы НевОС . Опыт создания системы параллельного программирования для РМВС, ее применения для программирования достаточно больших программных комплексов послужили отправной точкой для постановки работ по системам визуального параллельного программирования, создания в последующие годы языка и системы программирования ВИЗА.

1989–1992 гг.

Другая линия развития параллельных ВС, объединяющая разработку специальной структуры ВМ с использованием в качестве его ядра СБИС микропроцессора с фиксированной системой команд, была предложена для отечественных проектов 32-разрядных микропроцессоров новой архитектуры, создававшихся в конце 80-х – начале 90-х годов. В качестве ядра ВМ были рассмотрены (совместно с НПО «Элас», Зеленоград) микропроцессор «Салют» – микропроцессор, разрабатывавшийся для бортовых ВК перспективных космических аппаратов, и микропроцессор «Эль-90» – микропроцессорная реализация архитектуры «Эльбрус» (совместно с Институтом точной механики и вычислительной техники). И в том и в другом микропроцессорном наборе имелись возможности интеграции в структуру ядра ВМ специализированного коммуникационного контроллера и расширения базовой системой команд некоторой формой экстракодов. Структура ВМ на базе МП «Салют» приведена на рис. 7.

Структура вычислительного модуля на базе микропроцессорного набора «Салют»

Учитывая вариант включения функцией ТКМ в перечень прямо аппаратно-программно реализуемых в ВМ функций (с исключением ТКМ как самостоятельного компонента физической структуры) и в духе транспьютерных технологий можно считать такое «поглощение» ТКМ вычислительным модулем наиболее перспективным вариантом. Это позволило погрузить в архитектуру вычислительных модулей КК для внутрисистемных коммуникаций в параллельной ВС, реализовать алгоритмы КС с высокой эффективностью. Оценки и моделирование свидетельствовали, что достижимые в таких системах показатели задержки доставки сообщений между ВМ (L), накладных расходов ЦП ВМ на передачу сообщения (o), интервал между последовательно передаваемыми сообщениями (g) сбалансированы с характеристиками производительности вычислительного ядра ВМ. Расширение системы команд экстракодами управления процессами позволяло в два-три раза снизить накладные расходы на переключение процессов s, снизить показатель o.

1992–1994 гг.

Развитие в мире транспьютерных технологий определило интерес отечественной промышленности к этому классу ВС и направление ряда наших проектов в области параллельных ВС. Проведенные исследования и эксперименты с транспьютерными модулями на основе транспьютеров Т805 показало преимущества глубокой интеграции механизмов управления процессами, мультипрограммного режима работы транспьютера как компонента параллельной ВС с распределенной архитектурой. В то же время были видны и преимущества наших подходов с инкапсулированием последовательных программ внутри процессов – целостных компонентов параллельной схемы программы, с более высоким уровнем сервиса КС и используемых в ней протоколов, развитых средств сегментации и управления памятью в архитектуре ВМ.

Структура макета транспьютерной БВС на серийных транспьютерных модулях («гиперТРАМАах»)

Выводы наших исследований были подтверждены и практикой развития самих транспьютерных технологий, появлением нового поколения транспьютеров – Т9000. Т9000 развивал транспьютерные архитектуры именно в тех направлениях, которые указывались нами как ограничения семейства Т800, имевшиеся в наших архитектурных и структурных решениях в указанных выше проектах. Хотя и в Т9000 мы не увидели полного набора искомых функциональных возможностей для системной поддержки динамических параллельных вычислений в параллельных ВС с распределенной архитектурой, в целом они давали хорошую основу для построения параллельных ВС. Недостающие механизмы реализовывались на них программно в ядре ОС с приемлемой эффективностью. Нами был разработан проект параллельной ВС на транспьютерах. Структура макета такой параллельной ВС показана на рис. 8.

Кластерная ВС на серийных высокопроизводительных системных блоках и сетевых средствах

Следующим этапом работы стал проект высокопроизводительной кластерной ВС с масштабируемой конфигурацией, реализованный полностью на серийных технических средствах: системных блоках ПЭВМ, серийных сетевых контроллерах и коммутаторах с диапазоном производительности от 10 до 100 Гфлоп при стоимости порядка 0,3 долл. за 1 Мфлоп (300 долл. за 1 Гфлоп, оценки по техническим характеристикам микропроцессоров на июнь 2001 г.). На рис. 9 и 10 представлены структуры 8-и 36-процессорных конфигураций кластерной ВС.

Структура кластерной ВС на серийных системных блоках и сетевых средствах

Разработка параллельных кластерных ВС лежит в русле основных современных тенденций создания высокопроизводительных вычислительных средств (СВТ) широкого применения для решения современных сложных нерегулярных вычислительных задач [26]. С другой стороны, для нас это возврат на новом этапе к созданию параллельных ВС на основе серийно выпускаемых блоков вычислительной техники, который был нами апробирован в параллельной ВС на микроЭВМ «Электроника 81Б».

Однако в отличие от предыдущего проекта на «Электроника 81Б» проект кластерных ВС строился с ориентацией на создание СВТ широкого применения, где кроме показателя абсолютной производительности ВС важное значение имеют технико-экономические характеристики, удельная стоимость достигаемой производительности. Это определяет отличия в подходах к проектированию кластерной ВС, ориентацию на максимальное использование серийных (за счет этого – дешевых) технических средств для реализации физического уровня параллельной ВС. Если в проекте параллельной ВС на микроЭВМ «Электроника 81Б» готовым компонентом были микроЭВМ – основа ВМ параллельной ВС, а средства реализации коммуникационной системы были специальной разработки, то проект кластерной ВС использует готовые, серийно выпускаемые технические средства и в качестве основы построения КС. Средства реализации КС составляют существенную часть затрат на построение кластерных ВС. Например, Томас Стерлинг оценивает приемлемый уровень расходов на КС кластерной системы как 25–30% всех расходов на аппаратуру кластерной ВС [27].

Такой подход в нашем проекте стал возможен благодаря существенным сдвигам в развитии архитектуры и структуры сетевых средств, методов их взаимодействия с ЭВМ, которые стали реальностью со времени создания нашей параллельной ВС на «Электронике 81Б». Выросли технико-экономические характеристики средств локальных сетей массового применения. Сетевые контроллеры Fast Ethernet для шины PCI стали массовой продукцией по цене 15–35 долл., стоимость сетевых контроллеров Gigabit Ethernet с тысяч долларов уменьшилась до сотен долларов.

В сетевых средствах массового производства произошел переход от моноканальных архитектур, с использованием физической или логической шины (концентраторы) к архитектурам с коммутацией кадров. Замена моноканала на коммутатор с масштабируемой структурой позволяет варьировать пропускную способность КС с ростом числа абонентов – ВМ, иметь низкие значения задержек передачи сообщений L и сохранять их при росте числа ВМ в кластерной ВС.

Кроме того, построенная на коммутаторах структура ЛВС (а в кластерной ВС – ее КС) переводит все связи между узлами физической структуры параллельной ВС в категорию каналов «точка – точка» как на физическом, так и на канальном уровне. Это позволило во многих серийно выпускаемых сетевых блоках перейти на дуплексный режим работы канала подключения КК в ВМ к сетевой инфраструктуре, что дает почти двойное увеличение пропускной способности стыка ВМ с КС.

Ранее в нашем проекте параллельной ВС на «Электронике 81Б» были реализованы все эти возможности, только на базе коммуникационных средств специальной разработки. Теперь же можно использовать серийные, существенно более дешевые блоки. Конечно, пока не все из тех средств архитектурной поддержки, которые нужны для параллельных ВС, мы можем найти в сетевых средствах современных локальных сетей. Однако потери от их программной эмуляции – это плата за дешевизну серийных средств и таким образом всей кластерной ВС в целом.

Другая оборотная сторона применения серийных средств локальных сетей для КС – ограниченная масштабируемость кластерных ВС на серийных технических средствах (в данном контексте – сетевых средств). Для малых конфигураций кластерных ВС (например, с одним коммутатором средней стоимости) удельная пропускная способность КС на одного абонента, показатели L, o, g, будут определяться тем, что позволяют получить используемые технические средства ВМ, узла параллельной кластерной ВС – сетевого контроллера, системного блока. Наращивание конфигурации в пределах, определяемых заложенными в серийный коммутатор возможностями наращивания (stackable switches) и комплексирования с другими коммутаторами по каналам повышенной пропускной способности (например, каналов Gigabit Ethernet для коммутаторов FastEthernet), позволяет не ухудшать эти показатели при масштабировании системы. Так, удельные показатели КС 36-процессорной конфигурации кластерной ВС (рис. 10) будут практически такими же, как и для 8-процессорной конфигурации (рис. 8).

36-процессорная кластерная ВС

Конечно, можно поставить и тысячу, и десять тысяч системных блоков ПЭВМ и соединить их некоторой структурой КС с сетью из коммутаторов и кабелей между ними. В мире известны десятки кластерных ВС с числом процессоров больше тысячи. Однако для каждого из имеющегося на рынке набора серийных сетевых блоков будут свои ограничения на возможность масштабирования структуры сети с сохранением удельной пропускной способности на один абонент КС. Дальнейшее увеличение числа абонентов сети ведет к уменьшению пропускной способности КС в расчете на одного абонента, к росту показателей L, o, g, критичных для функционирования параллельной ВС. И такая кластерная ВС будет работоспособна, и она сможет решать задачи. Однако все на большем числе задач будут расти потери ресурса процессорного времени и падать эффективная производительность. Эти факторы и приводят к тому, что эффективная производительность кластерных ВС (real applications performance – RAP) оценивается как 5–15% от их пиковой производительности (Peak Advertised Performance, PAP) [28]. Для сравнения: у лучше сбалансированных профессиональных высокопроизводительных ВК – малопроцессорных ВК из векторных процессоров – это соотношение оценивается как 30–50%.

Наконец, большое значение имеет появление поддержки архитектуры виртуального интерфейса (Virtual Interface Architecture, VIA) в архитектуре коммуникационных контроллеров и сопровождающих их драйверах для серийных ОС (в нашем случае – для ОС Linux). Один из авторов настоящей статьи, Шейнин Ю. Е., был участником (contributing member) международной рабочей группы, разрабатывавшей и исследовавшей спецификацию VIA. Качественно новый уровень организации взаимодействия ПО, выполняющегося на центральном процессоре ВМ, с коммуникационным контроллером позволяет существенно снизить накладные расходы o и задержки передачи сообщений L. Так, накладные расходы o удается сократить до 4 мкс [29]. В нашей кластерной ВС мы используем сетевые контроллеры типа Intel Pro 100 с драйверами M-VIA для ОС Linux.

Еще лучшие характеристики можно получать при использовании коммуникационной среды, построенной по технологии АТМ [30]. Для этой технологии также серийно выпускаются и КК, и коммутаторы. Однако современный рынок СВТ сложился таким образом, что сетевые средства по технологии АТМ не получили столь массового распространения, как современные технологии Ethernet. В результате сетевые узлы и блоки не стали столь массовой продукцией и цены на них существенно, в несколько раз выше.

Перспективы развития вычислительных систем

Высокопроизводительные вычислительные средства давно стали ключевым аспектом развития науки и техники. Компьютерное моделирование широко используется в естественных науках для исследования явлений и процессов реального мира, в прикладных дисциплинах – для анализа и оптимизации инженерных решений. Прогнозируется дальнейший рост значимости компьютерного моделирования вычислительных экспериментов для развития фундаментальных и прикладных наук, прогресса в инженерных дисциплинах разного профиля, перехода от натурных экспериментов к исследованиям на компьютерных моделях. Яркий пример – замена ядерных взрывов на компьютерное моделирование и вычислительные эксперименты.

Это требует разработки самых передовых методов компьютерного моделирования и суперкомпьютерных вычислительных средств, на что направлена, например, целевая научно-техническая программа министерства энергетики США DOE/ASCI Program (Department of Energy, DOE; Accelerated Strategic Computing Initiative, ASCI) [32].

Представление о широте спектра задач для массово-параллельных систем и типовых классов вычислительных алгоритмов дает их сводка на рис. 11 [33]. Очевидно, что это сегодняшнее представление является лишь малой частью тех задач, которые придется решать массово-параллельным системам в ближайшее десятилетие.

Перспективные задачи для массово-параллельных ВС

Сформировались и получили признание дисциплины, базирующиеся на высокопроизводительной компьютерной обработке и моделировании: вычислительная метеорология (моделирование погодных и климатических процессов), астрономия и астрофизика (исследование звезд, суперновых, нейтронных звезд, космология), вычислительная физика, вычислительная химия (Computational Chemistry), молекулярное моделирование (Molecular Modelling) и др.

Они играют все более значимую роль в развитии современных научных знаний. Например, Нобелевскую премию в области химии в 1998 г. получил профессор Walter Kohn за создание теории Density Functional Theory, составляющей теоретическую основу многих вычислительных экспериментов на суперкомпьютерах в области вычислительной химии [34].

Наряду с ними развиваются новые научные дисциплины, новые отрасли знаний [33]: вычислительная экономика (Computational Economics), вычислительная логика (Computational Logic), вычислительная экология (Computational Ecology), биоинформатика (Bioinformatics), вычислительная лингвистика (Computational Linguistics), вычислительная электроника (Computational Electronics) и др.

Не меньшее значение придается расширению применения методов и технологий суперкомпьютерной обработки данных в новых сферах, за рамками традиционно научных и инженерных областей, для улучшения сервисов для широких слоев населения и накопления знаний человеческим обществом. Базирующиеся на суперкомпьютерных возможностях обработки информации «интеллектуальные» экспертные системы смогут оперативно вырабатывать оптимальные решения в различных областях – от здравоохранения до прогноза поведения рынков.

Перспективная задача – извлечение и накопление знаний на основе сложных алгоритмов извлечения данных из огромных накопленных баз данных (data mining). Пример нового направления – Web-mining, извлечение знаний из информации, хранящейся в Интернете на веб-серверах – самом большом и постоянно расширяющемся источнике информации в современном мире. Задача является еще более сложной, чем data mining (в силу отсутствия единообразного структурированности информации), требующая для своего решения интеграции методов data mining, компьютерной лингвистики, понимания образов, социальных наук, помноженного на огромные вычислительные мощности перспективных массово-параллельных компьютеров. Получаемые в результате знания могут стать основной развития новых направлений в социальных и гуманитарных исследованиях.

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

Массово-параллельные вычисления с терафлоповой и петафлоповой (1015) производительностью необходимы и в сложных приборных комплексах. Источники рентгеновского излучения в исследовательских центрах, гигагерцовые NMR-системы, ускорители элементарных частиц, аэродинамические трубы и другие научные приборные комплексы генерируют огромные потоки данных, сотни мегабайт в секунду и более [35, 36]. Все эти данные требуют сложной обработки и комплексного анализа [37, 38]. Дальнейшее развитие и методик экспериментальных научных исследований, и научных приборных комплексов требует анализа поступающих с приборов потоков данных в реальном времени так, чтобы по их результатам учеными мог контролироваться, модифицироваться и управляться ход самого научного эксперимента.

Еще более захватывающая научная проблема, обещающая качественно-новые возможности научных исследований, – непосредственная интеграция приборных комплексов для проведения экспериментов и массово-параллельных суперкомпьютерных вычислительных средств, ведущих в реальном времени моделирование лежащих в основе проводимого эксперимента физических, химических и т.  п. процессов. При этом появляется возможность прямого взаимодействия эксперимента, теории и научных представлений исследователей (scientific insight), их взаимовлияния в единой интерактивной среде научных исследований.

Перспективные задачи характеризуются большими размерностями обрабатываемых массивов данных, большими объемами вычислений, требуют огромных вычислительных ресурсов [39]. Среди перечисленных выше типовых задач многие относятся к задачам большой вычислительной интенсивности (computation intensive), объем вычислений которых растет значительно быстрее роста размерности задачи и быстрее роста объема обрабатываемых данных. Например, даже для традиционной задачи умножения матриц многие известные алгоритмы параллельного умножения матриц требуют O(N3) операций вычислений и O(N2) пересылок данных [40]. Для широкого класса задач трехмерного моделирования физических систем отмечен рост вычислительной сложности (объема вычислений) как n4, при росте объема требуемой памяти как n3. В вычислительной химии имеется большое число задач, вычислительная сложность которых характеризуется как n5, n7, n! и др.

В этих условиях достигнутый терафлоповый (1012 операций с плавающей запятой в секунду) уровень производительности суперкомпьютерных систем является недостаточным. Уже сегодня есть реальные, актуальные и готовые к решению задачи, требующие производительности в десятки и сотни терафлоп, ясны постановки ряда задач, требующие производительности в 1000 терафлоп. На повестке дня – создание в ближайшее десятилетие вычислительных систем с производительностью, измеряемой в петафлопах – 1015 операций в секунду, которые уже называют петафлоповыми компьютерами (Petaflop Computers). По оценкам PITAC (Консультативного совета по информационным технологиям при президенте США) задача создания петафлоповых суперкомпьютеров должна быть решена к 2007 г. [41].

Вычислительные машины предназначены для решения задач.

Общая схема решения задач имеет вид Ячел -> Яос ->Япр ->Ямаш -> Ярез, где Ячел – формулировка задачи на естественном языке, Яос – формулировка задачи на языке основных соотношений, Япр – формулировка задачи на языке программирования, Ямаш – формулировка задачи на машинном языке, Ярез – формулировка задачи на языке результата в виде графиков, таблиц, изображений, текстов, звуков и т. п.

К сожалению, для большинства задач имеется только формулировка на естественном языке, множество задач плохо формализованы. Поэтому актуальным является переход от описания на естественном языке к описанию на языке основных соотношений; лингвокомбинаторное моделирование является одним из способов такой формализации [22]. В результате такой формализации порождаются рекурсивные структуры со структурированной неопределенностью. Таким образом, рекурсивная структура машин должна включать три составляющих – явления, смыслы и структурированную неопределенность, которые наличествуют в любой задаче.

Литература

  1. А. А. Воронов, А. Р. Гарбузов, Б. Л. Ермилов, М. Б. Игнатьев, Г. Н. Соколов, Ян Си Зен. Цифровые аналоги для систем автоматического управления. Изд. АН СССР, 1960.
  2. М. Б. Игнатьев. Голономные автоматические системы. Л.–М., Изд. АН СССР, 1963.
  3. А. И. Мальцев. Алгоритмы и рекурсивные функции. М., 1965.
  4. М. Б. Игнатьев. О совместном использовании принципов введения избыточности и обратной связи для построения ультраустойчивых систем. Труды Ш Всесоюзного совещания по автоматическому управлению, т. 1. Изд. АН СССР, 1968.
  5. М. Б. Игнатьев. Метод избыточных переменных для функционального кодирования цифровых автоматов. Сб. «Теория автоматов», №4. Киев, ИК АН УССР, 1969.
  6. М. Б. Игнатьев. О лингвистическом подходе к анализу и синтезу сложных систем. Тезисы Межвузовской научно-технической конференции «Техническая кибернетика». Изд. МВТУ, 1969.
  7. М. Б. Игнатьев. Избыточность в многоцелевых системах. Труды IV симпозиума по проблеме избыточности. Л., 1970.
  8. М. Б. Игнатьев, Ф. М. Кулаков, А. М. Покровский. Алгоритмы управления роботами-манипуляторами. М., Машиностроение, 1972. США, Вирджиния пресс, 1973.
  9. Г. С. Бритов, М. Б. Игнатьев, Л. А. Мироновский, Ю. М. Смирнов. Управление вычислительными процессами. ЛГУ, 1973.
  10. V. Glushkov, M. Ignatyev, V. Miasnikov, V. Torgashev. Recursive machines and computing technology. Proceedings IFIP-74, computer hardware and architecture, p. 65–70, Stockholm, August 5–10, 1974.
  11. М. Б. Игнатьев, В. А. Мясников, А. М. Покровский. Программное управление оборудованием. Изд. 2-е. М., Машиностроение, 1984.
  12. М. Б. Игнатьев, В. А. Мясников, В. А. Торгашев. Рекурсивные вычислительные машины. Препринт №12. ИТМ и ВТ АН СССР, 1977.
  13. М. Б. Игнатьев, В. М. Кисельников, В. А. Торгашев, В. Б. Смирнов. Ассоциативное запоминающее устройство. А. с. 4844562. Опубл. в Б. И., №34, 1975.
  14. А. А. Бекасова, С. В. Горбачев, М. Б. Игнатьев, В. А. Мясников, В. А. Торгашев. Процессор с микропрограммным управлением. А. с. 814118 с приоритетом от 18.10.1979.
  15. С. В. Горбачев, М. Б. Игнатьев, В. М. Кисельников, В. А. Мясников, В. А. Торгашев. Многопроцессорная вычислительная система. А. с. 962965 с приоритетом от 27 августа 1974. Опубл. в Б. И., №36, 1982.
  16. М. Б. Игнатьев, В. А. Мясников, В. В. Фильчаков. Организация вычислительного процесса при решении прикладных задач на многопроцессорной системе с рекурсивной организацией. Журнал АН УССР, сер. Кибернетика, 1984, №3, с. 30–37.
  17. Рекурсия. Ст. в Математической энциклопедии, т. 4. М, 1984, с. 962–966.
  18. В. А. Мясников, М. Б. Игнатьев, А. А. Кочкин, Ю. Е. Шейнин. Микропроцессоры – системы программирования и отладки. М., Энергоатомиздат, 1985.
  19. С. В. Горбачев, М. Б. Игнатьев, Ю. Е. Шейнин. Рекурсивные ЭВМ массового применения. Тезисы 11-й Всесоюзной конференции по актуальным проблемам информатики и вычислительной техники. Ереван, АН Армянской ССР, 1987.
  20. М. Б. Игнатьев, Я. Комора. Обобщенная параметрическая модель реализации локально-рекурсивных структур в трехмерных интегральных схемах. ДАН СССР, 1991, т. 320, №5, с. 1058–1062.
  21. М. Б. Игнатьев, В. В. Фильчаков, Л. Г. Осовецкий. Активные методы обеспечения надежности алгоритмов и программ. Политехника, 1992.
  22. М. Б. Игнатьев. Лингвокомбинаторное моделирование плохо формализованных систем. Информационно-управляющие системы, 2003, №6, с. 34–37.
  23. С. А. Яновская. Методологические проблемы науки. М, 1972.
  24. П. Г. Суворова. Диалектика абстрактного и конкретного в понятии «архитектура ЭВМ». Сб. «Новые идеи в философии науки и научном познании». Под ред. Ю. И. Мирошникова. Екатеринбург, 2002.
  25. Т. Е. Аладова, М. Б. Игнатьев, Ю. Е. Шейнин. Распределенный монитор для отладки программного обеспечения мультипроцессорных систем. Микропроцессорные средства и системы, 1990, №5, с. 49–56.
  26. High Performance Cluster Computing: Architectures and Systems. Rajkumar Buyya (editor), ISBN 0–13–013784–7, Prentice Hall PTR, NJ, USA, 1999, v.1, 2.
  27. Th. Sterling. The Future of Cluster Interconnects: Infiniband or Ethernet. A Beowulf Perspective. Panel Presentation at IEEE Cluster 2000 Conference.
  28. G. Bell, J. Gray. High Performance Computing: Crays, Clusters, and Centers. What Next? Microsoft Research, Technical Report MSR-TR-2001–76, 2001. 7 p.
  29. Ph. Buonadonna, A. Geweke, D. Culler. An Implementation and Analysis of the Virtual Interface Architecture. Proceedings of SC98, Orlando, Florida, November 1998. 9 p.
  30. S. Gorbachev, E. Gontcharova, M. Ignatiev, Y. E. Sheynin. Distributed High Performance Computing Over ATM Networks. In: Proceedings of the High Performance Computing (HPC ’98), ASTC’98 Conference, Boston, USA, April 1998, p. 216–221.
  31. М. Б. Игнатьев, Ю. Е. Шейнин. 25 лет со времени создания рекурсивной вычислительной машины высокой производительности и надежности и проблемы параллельных вычислений. Доклад на пленарном заседании 23-й международной конференции по школьной информатике и проблемам устойчивого развития, Санкт-Петербург, 16 апреля 2004 г.
  32. G. G. Weigand. Petaflop II. The ASCI Challenge. Petaflops II. 2nd Conference on Enabling Technologies for Peta(fl)ops Computing. Santa Barbara, California, USA, February 1999.
  33. R. Stevens. Applications for PetaFLOPS. Petaflops II. 2nd Conference on Enabling Technologies for Peta(fl)ops Computing. Santa Barbara, California, USA, February 1999.
  34. J. Bashor. Researchers Achieve One Teraflop Performance With Supercomputer Simulation Of Magnetism. Berkeley Research News, 1998, November 9.
  35. W. E. Johnston. Real-Time Widely Distributed Instrumentation Systems. The Grid: Blueprint for a New Computing Infrastructure. Ed. by Ian Foster and Carl Kesselman. Morgan Kaufmann. Pubs. August 1998.
  36. W. E. Johnston e. a. High-Speed Distributed Data Handling for On-Line Instrumentation Systems. Proceedings of ACM/IEEE SC97: High Performance Networking and Computing. Nov., 1997.
  37. William E. Johnston e. a. High-Speed Distributed Data Handling for High-Energy and Nuclear Physics. Invited lecture (W. Johnston) at the 1997 CERN School of Computing, Pruhonice (Prague), Czech Republic. 17–30 August 1997. Published in the «Proceedings of the 1997 CERN School of Computing.» Also published in the proceedings of Computing in High Energy Physics, Berlin, Germany. April, 1997.
  38. W. Johnston e. a. Real-Time Generation and Cataloguing of Large Data-Objects in Widely Distributed Environments. International Journal of Digital Libraries May, 1998.
  39. D. H. Bailey. Petaflops Algorithms. Petaflops II. 2nd Conference on Enabling Technologies for Peta(fl)ops Computing. Santa Barbara, California, USA, February 1999.
  40. J. Choi. A New Parallel Matrix Multiplication Algorithm on Distributed-Memory Concurrent Computers. Center for Research on Parallel Computation, Rice University, September 1997, CRPC-TR97758, 19 р.
  41. Information Technology Research: Investing in Our Future. PITAC – Report to the President, February 24, 1999.

Статья опубликована 08.12.2005 г.

8. Рекурсивные функции

Рекурсивные функции очень хорошо иллюстрируют понятие алгоритма. Если рассуждать упрощенно, то для рекурсивной функции должен существовать алгоритм, вычисляющей ее значения. Вообще говоря, большая часть известных числовых функций являются рекурсивными.

Полезно вспомнить, как определяются Элементарные функции. Вначале рассматривается несколько классов функций: алгебраические, тригонометрические, показательные, логарифмические. Элементарная функция определяется как Суперпозиция (или сложная функция) этих функций.

Рекурсивные функции строятся аналогичным образом.

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

Рассмотрим вначале примитивно-рекурсивные функции.

Простейшие примитивно-рекурсивные функции Задаются следующим образом.

· Функция следования задается формулой: (или ).

· Функция аннулирования задается формулой: .

· Функция тождества определяется следующим образом: , то есть эта функция произвольному -мерному вектору сопоставляет его -ю координату.

Из простейших примитивно-рекурсивных функций можно получить примитивно-рекурсивные функции с помощью следующих двух операторов.

· Оператор суперпозиции. Пусть , , , …, – примитивно-рекурсивные функции. Тогда функция

Получена с помощью оператора суперпозиции.

Оператор суперпозиции – это оператор построения сложной функции. Если мы умеем вычислять функции , , …, и , то значения функции могут быть получены последовательным вычислением значений функций , , …, на некотором наборе значений переменных , и вычислением значения функции на наборе значений , , …,

Пример. Функция получается суперпозицией функций 0(X) и S(X): . Аналогичным образом можно получить функции вида для всех значений N.

· Оператор примитивной рекурсии из известных примитивно-рекурсивных функций и позволяет строить новую функцию . Так,

,

.

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

Таким образом, сначала (при фиксированных значениях ) определяется значение функции при , а затем каждое следующее значение функции (зависящее от ) выражается через предыдущее значение (зависящее от ).

Пусть . Тогда функция есть постоянная. Обозначим ее следующим образом: . Функция зависит от двух переменных. Обозначим ее так: . Тогда

,

.

Для произвольного получаем (обозначения , , , …, вводятся в предположении, что набор фиксирован):

,

,

,

. . . . . . . . . . . . . . . . . .

.

. . . . . . . . . . . . . . . . . .

Пример. Даны функции и . Определим функцию , полученную из данных функций по схеме примитивной рекурсии.

Решение. Найдем значения функции .

,

;

;

.

Можно предположить, что .

Докажем последнюю формулу методом математической индукции по переменной .

1. Проверим формулу при .

, то есть при формула верна.

2. Допустим, что предположение индукции верно при , то есть, верна формула .

Докажем, что предположение индукции верно при , то есть, верна формула . Выразим с помощью схемы примитивной рекурсии.

.

Таким образом, на основании метода математической индукции формула доказана для всех .

Теперь строго определим примитивно-рекурсивные функции.

Определение. 1) Простейшие примитивно-рекурсивные функции примитивно-рекурсивны.

2) Примитивно-рекурсивными являются функции, полученные из примитивно-рекурсивных функций с помощью операторов суперпозиции и (или) примитивной рекурсии.

3) Функция является примитивно-рекурсивной тогда и только тогда, когда это следует из 1) и 2).

Пример. Покажем, что функция примитивно-рекурсивна.

Доказательство. , , следовательно, функция должна зависеть от одной переменной, а функция – от трех. Пользуясь заданием функции, найдем ее значения:

.

То есть .

Таким образом, функция получена по схеме примитивной рекурсии () из примитивно-рекурсивных функций, следовательно, сама является примитивно-рекурсивной.

Примитивно-рекурсивными, в частности, являются следующие функции: , , , , , ,

Операция минимизации по -ой переменной функции обозначается следующим образом: , и определяется так.

Рассмотрим уравнение относительно :

. (1)

Это уравнение решается подбором, вместо переменной последовательно подставляются 0,1,2,… При этом возможны случаи.

· На некотором шаге левая часть соотношения (1) не определена. Следовательно, на наборе операция минимизации не определена.

· На каждом шаге левая часть соотношения (1) определена, но равенство не выполняется ни при каких значениях . Следовательно, на наборе операция минимизации не определена.

· Левая часть соотношения (1) определена при , но при равенство не выполняется, а при выполняется. В этом случае число считается значением операции минимизации на наборе .

Пример. [13]. Найти функции, получаемые из данной числовой функции с помощью оператора минимизации по каждой ее переменной.

Решение. Минимизируем функцию по переменной . Рассмотрим уравнение

. (2)

1. Если , , то при подстановке получаем верное равенство.

2. Если , то левая часть равенства (2) не определена.

3. Если , , то при подстановке в левой части равенства (2) появляется выражение , не имеющее смысла, и в этом случае операция минимизации не определена.

4. Если , то получаем равенство . Оно имеет смысл при , то есть , что рассмотрено в первом пункте, и при , то есть . При равенство не имеет смысла.

Таким образом,

Минимизируем функцию по переменной . Рассмотрим уравнение

.

Это уравнение на самом первом шаге, при подстановке вместо нуля теряет смысл, значит, операция минимизации по второй переменной нигде не определена.

Минимизируем функцию по переменной . Рассмотрим уравнение

. (3)

Если левая часть соотношения (3) имеет смысл и равенство (3) выполнено, то оно выполнено и при подстановке в это соотношение переменной на первом шаге, то есть при . В остальных случаях значение операции минимизации не определено.

Определение. Частично-рекурсивной функцией называется числовая функция, получаемая за конечное число шагов из простейших примитивно-рекурсивных функций с помощью операторов суперпозиции, примитивной рекурсии и минимизации.

Определение. Числовая функция называется Общерекурсивной, если она частично-рекурсивна и всюду определена.

Определение. Функция называется Эффективно вычислимой, если существует алгоритм, позволяющий вычислить ее значения.

В данном определении алгоритм понимается в интуитивном значении, следовательно, интуитивным является и понятие эффективно вычислимой функции.

Имеет место следующий тезис.

Тезис Черча. Каждая интуитивно вычислимая функция является частично-рекурсивной.

Тезис является недоказуемым, так как он связывает нестрогое понятие интуитивно вычислимой функции и строгое математическое понятие частично-рекурсивной функции.

Тезис может быть опровергнут построением примера интуитивно вычислимой, но не частично-рекурсивной функции.

< Предыдущая   Следующая >

Рекурсия в Python

Сумма чисел от 1 до n

Если бы я хотел узнать сумму чисел от 1 до n, где n — натуральное число, я мог бы посчитать вручную 1 + 2 + 3 + 4 + … + (несколько часов спустя) + n. А можно просто написать цикл for:

n = 0
for i in range (1, n+1):
    n += i

Или использовать рекурсию:

def recursion(n):
	if n == 1:
		return 1
	return n + recursion(n - 1)

У рекурсии есть несколько преимуществ в сравнении с первыми двумя методами. Рекурсия занимает меньше времени, чем выписывание 1 + 2 + 3 на сумму от 1 до 3.

Для recusion(4) рекурсия может работать в обратную сторону:

Вызов функций: (4 -> 4 + 3 -> 4 + 3 + 2 -> 4 + 3 + 2 + 1 -> 10)

Принимая во внимание, что цикл [for] работает строго вперед: (1 -> 1 + 2 -> 1 + 2 + 3 -> 1 + 2 + 3 + 4 -> 10). Иногда рекурсивное решение проще, чем итеративное решение. Это очевидно при реализации обращения связанного списка.

Как и когда происходит рекурсия


Рекурсия появляется когда вызов функции повторно вызывает ту же функцию до завершения первоначального вызова функции. Например, рассмотрим известное математическое выражение x! (т.е. факториал). Факториал определяется для всех неотрицательных целых чисел следующим образом:

Если число равно 0, то будет 1.

В противном случае ответом будет то, что число умножается на факториал на единицу меньше этого числа.

В Python наивная реализация факториала может быть определена как функция следующим образом:

def factorial(n):
	if n == 0:
		return 1
	else:
		return n * factorial(n - 1)

Иногда функции рекурсии трудно понять, поэтому давайте рассмотрим поэтапно.

Рассмотрим выражение factorial(3). Эта и все остальные вызовы функций создают новую среду. Среда представляет собой таблицу, которая сопоставляет идентификаторы (например, n, factorial, print и т.д.) с их соответствующими значениями.

В любой момент времени вы можете получить доступ к текущей среде с помощью locals(). В первом вызове функции единственная локальная переменная, которая определяется n = 3.Поэтому locals() будет показывать {"n": 3}. Так как n == 3, возвращаемое значение становится n * factorial(n - 1).

На следующем этапе ситуация может немного запутаться. Глядя на наше новое выражение, мы уже знаем, что такое n. Однако мы еще не знаем, что такое factorial(n - 1).

Во-первых, n - 1 принимает значение 2.Затем 2 передаётся factorial как значение для n. Поскольку это новый вызов функции, создаётся вторая среда для хранения нового n.

Пусть A — первое окружение, а B — второе окружение. A всё ещё существует и равен {"n": 3} , однако B (что равно {"n": 2}) является текущей средой. Если посмотреть на тело функции, возвращаемое значение, опять же, n * factorial(n - 1).

Не определяя это выражение, заменим его на исходное выражение return. Делая это, мы мысленно отбрасываем B, поэтому не забудьте заменить n соответственно (т.е. ссылки на B n заменены на n - 1) который использует A n ). Теперь исходное обратное выражение становится n * ((n - 1) * factorial((n - 1) - 1)). Подумайте, почему так?

Теперь давайте определим factorial((n - 1) - 1)). Так как A n == 3, мы пропускаем 1 через factorial. Поэтому мы создаем новую среду C, которая равна {"n": 1}. Мы снова возвращаем значение n * factorial(n - 1). Итак, заменим исходный factorial((n - 1) - 1)) выражения return аналогично тому, как раньше мы скорректировали исходное выражение return. Исходное выражение теперь n * ((n - 1) * ((n - 2) * factorial((n - 2) - 1))).

Почти закончили. Теперь нам нужно оценить factorial((n - 2) - 1). На этот раз мы пропустим через 0.  Следовательно, должно получиться 1.

Теперь давайте проведём нашу последнюю замену. Исходное выражение return теперь n * ((n - 1) * ((n - 2) * 1)). Напомню, что исходное выражение возврата оценивается под A , выражение становится 3 * ((3 - 1) * ((3 - 2) * 1)). Здесь получается 6.

Чтобы убедиться, что это правильный ответ, вспомните, что 3! == 3 * 2 * 1 == 6. Прежде чем читать дальше, убедитесь, что вы полностью понимаете концепцию среды и то, как они применяются к рекурсии.

Утверждение, if n == 0: return 1, называется базовым случаем. Потому что это не рекурсия. Базовый случай необходим, без него вы столкнетесь с бесконечной рекурсией. С учетом сказанного, если у вас есть хотя бы один базовый случай, у вас может быть столько случаев, сколько вы хотите. Например, можно записать факториал  таким образом:

def factorial(n):
	if n == 0:
    	return 1
    elif n == 1:
    	return 1
   	else:
    	return n * factorial(n - 1)

У вас может также быть несколько случаев рекурсии, но мы не будем вдаваться в подробности, потому что это редкий случай, и его трудно мысленно обрабатывать.

Вы также можете иметь «параллельные» рекурсивные вызовы функций. Например, рассмотрим последовательность Фибоначчи, которая определяется следующим образом:

  • Если число равно 0, то ответ равен 0.
  • Если число равно 1, то ответ равен 1.

В противном случае ответ представляет собой сумму двух предыдущих чисел Фибоначчи.

Мы можем определить это следующим образом:

def fib(n):
    if n == 0 or n == 1:
        return n
    else:
        return fib(n - 2) + fib(n - 1)

Я не буду разбирать эту функцию также тщательно, как и с factorial(3), но окончательное значение возврата fib(5) эквивалентно следующему (синтаксически недействительному) выражению:

(
  fib((n - 2) - 2)
  +
  (
    fib(((n - 2) - 1) - 2)
    +
    fib(((n - 2) - 1) - 1)
  )
)
+
(
  (
    fib(((n - 1) - 2) - 2)
    +
    fib(((n - 1) - 2) - 1)
  )
  +
  (
    fib(((n - 1) - 1) - 2)
    +
    (
      fib((((n - 1) - 1) - 1) - 2)
      +
      fib((((n - 1) - 1) - 1) - 1)
    )
  )
)

Решением (1 + (0 + 1)) + ((0 + 1) + (1 + (0 + 1))) будет 5.

Теперь давайте рассмотрим еще несколько терминов:

Tail call  — это просто вызов рекурсивной функции, который является последней операцией и должна быть выполнена перед возвратом значения. Чтобы было понятно, return foo(n - 1) — это хвост вызова, но return foo(n - 1) + 1 не является (поскольку операция сложения будет последней операцией).

Оптимизация хвоста вызова (TCO или tail cost optimization) — это способ автоматического сокращения рекурсии в рекурсивных функциях.

Устранение хвоста вызова (TCE или tail cost elimination) — это сокращение хвостового вызова до выражения, которое может быть оценено без рекурсии. TCE — это тип TCO.

Оптимизация хвоста вызова может пригодиться по нескольким причинам:

Интерпретатор может снизить объём памяти, занятый средами. Поскольку ни у кого нет неограниченной памяти, чрезмерные рекурсивные вызовы функций приведут к переполнению стека.

Интерпретатор может уменьшить количество переключателей кадров стека.

В Python нет TCO по нескольким причинам, поэтому для обхода этого ограничения можно использовать другие методы. Выбор используемого метода зависит от варианта использования. Интуитивно понятно, что factorial и fib можно относительно легко преобразовать в итеративный код следующим образом:

def factorial(n):
    product = 1
    while n > 1:
        product *= n
        n -= 1
    return product

def fib(n):
    a, b = 0, 1
    while n > 0:
        a, b = b, a + b
        n -= 1
    return a

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

Другим полезным инструментом является декодер lru_cache, который можно использовать для уменьшения количества лишних вычислений.

Теперь вы знаете, как избежать рекурсии в Python, но когда её нужно использовать? Ответ «не часто». Все рекурсивные функции могут быть реализованы итеративно. Это просто вопрос, как именно сделать. Однако есть редкие случаи, когда можно использовать рекурсию. Рекурсия распространена в Python, когда ожидаемые вводы не вызовут значительного количества вызовов рекурсивных функций.

Если вы интересуетесь рекурсией, стоит изучить функциональные языки, такие как Scheme или Haskell. На таких языках рекурсия намного полезней.

Хотя приведённый выше пример последовательности Фибоначчи, хорошо показывает, как применять определение в python и позже использовать кэш lru, при этом он имеет неэффективное время работы, из-за того, что выполняет 2 рекурсивных вызова. Количество вызовов функции растет экспоненциально до n.

В таком случае лучше использовать линейную рекурсию:

def fib(n):
    if n <= 1:
        return (n,0)
    else:
        (a, b) = fib(n - 1)
        return (a + b, a)

Но у этого примера есть проблема в возвращении пары числе вместо одного. Это показывает, что не всегда стоит использовать рекурсию.

Исследование дерева с рекурсией

Допустим, у нас есть такое дерево:

root
- A
  - AA
  - AB
- B
  - BA
  - BB
    - BBA

Если мы хотим перечислить все имена элементов, мы можем сделать это с помощью простого цикла for. У нас есть функция get_name(), которая возвращает строку с именем узла, функция get_children(), которая возвращает список всех подузлов данного узла в дереве, и функция get_root() для получить корневой узел.

root = get_root(tree)
for node in get_children(root):
    print(get_name(node))
    for child in get_children(node):
        print(get_name(child))
        for grand_child in get_children(child):
            print(get_name(grand_child))
# Выводит: A, AA, AB, B, BA, BB, BBA

Этот код работает хорошо и быстро, но что если под-узлы получили свои под-узлы? И эти под-узлы могут иметь больше под-узлов … Что если вы не знаете заранее, сколько их будет? Решением этой проблемы будет использование рекурсии.

def list_tree_names(node):
    for child in get_children(node):
        print(get_name(child))
        list_tree_names(node=child)
list_tree_names(node=get_root(tree))
# Выводит: A, AA, AB, B, BA, BB, BBA


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

def list_tree_names(node, lst=[]):
    for child in get_children(node):
        lst.append(get_name(child))
        list_tree_names(node=child, lst=lst)
    return lst

list_tree_names(node=get_root(tree))
# returns ['A', 'AA', 'AB', 'B', 'BA', 'BB', 'BBA']

Увеличение максимальной глубины рекурсии

Существует предел глубины возможной рекурсии, который зависит от реализации Python. Когда предел достигнут, возникает исключение RuntimeError:

RuntimeError: Maximum Recursion Depth Exceeded

Пример программы, которая может вызвать такую ошибку:

def cursing(depth):
  try:
    cursing(depth + 1) # actually, re-cursing
  except RuntimeError as RE:
    print('I recursed {} times!'.format(depth))
cursing(0)
# Out: I recursed 1083 times!

Можно изменить предел глубины рекурсии с помощью

sys.setrecursionlimit(limit)

Чтобы проверить текущие параметры лимита, нужно запустить:

sys. getrecursionlimit()

Если запустить тот же метод выше с новым пределом, мы получаем

sys.setrecursionlimit(2000)
cursing(0)
# Out: I recursed 1997 times!

В Python 3.5 ошибка стала называться RecursionError, которая является производной от RuntimeError.

Хвостовая рекурсия — как не надо делать

Хвостовая рекурсия — частный случай рекурсии, при котором любой рекурсивный вызов является последней операцией перед возвратом из функции.

Вот пример обратного отсчета, написанного с использованием хвостовой рекурсии:

def countdown(n):
    if n == 0:
        print("Blastoff!")
    else:
        print(n)
        countdown(n-1)


Любое вычисление, которое может быть выполнено с использованием итерации, также может быть выполнено с использованием рекурсии. Вот версия find_max, написанная с использованием хвостовой рекурсии:

def find_max(seq, max_so_far):
    if not seq:
        return max_so_far
    if max_so_far < seq[0]:
        return find_max(seq[1:], seq[0])
    else:
        return find_max(seq[1:], max_so_far)


Хвостовую рекурсию лучше не использовать, поскольку компилятор Python не обрабатывает оптимизацию для хвостовых рекурсивных вызовов. В таких случаях рекурсивное решение использует больше системных ресурсов, чем итеративное.

Оптимизация хвостовой рекурсии с помощью интроспекции стека

По умолчанию рекурсивный стек Python не превышает 1000 кадров. Это ограничение можно изменить, установив sys.setrecursionlimit(15000) который быстрее, однако этот метод потребляет больше памяти. Вместо этого мы также можем решить проблему рекурсии хвоста, используя интроспекцию стека.

#!/usr/bin/env python2.4
# Эта программа показыает работу декоратора, который производит оптимизацию хвостового вызова. Он делает это, вызывая исключение, если оно является его прародителем, и перехватывает исключения, чтобы вызвать стек.
import sys
class TailRecurseException:
  def __init__(self, args, kwargs):
  	self.args = args
    self.kwargs = kwargs
# Эта программа показыает работу декоратора, который производит
# оптимизацию хвостового вызова. Он делает это, вызывая исключение, если
# оно является его прародителем, и перехватывает исключения, чтобы
# подделать оптимизацию хвоста Эта функция не работает, если функция
# декоратора возвращается без хвоста. 
def tail_call_optimized(g):
  def func(*args, **kwargs):
    f = sys._getframe()
    if f.f_back and f.f_back.f_back \
        and f.f_back.f_back.f_code == f.f_code:
      raise TailRecurseException(args, kwargs)
    else:
      while 1:
        try:
          return g(*args, **kwargs)
        except TailRecurseException as e:
            args = e.args
            kwargs = e.kwargs
  func.__doc__ = g.__doc__
  return func

Чтобы оптимизировать рекурсивные функции, мы можем использовать декоратор @tail_call_optimized для вызова нашей функции. Вот несколько примеров общей рекурсии с использованием декоратора, описанного выше:

Факториальный пример:

#  "calculate a factorial"
@tail_call_optimized
def factorial(n, acc=1):
  if n == 0:
    return acc
  return factorial(n-1, n*acc)
print(factorial(10000))
# печатает очень большое число
# и не достигает лимита рекурсии.

Пример Фибоначчи:
@tail_call_optimized
def fib(i, current = 0, next = 1):
  if i == 0:
    return current
  else:
    return fib(i - 1, next, current + next)
print(fib(10000))
# также выводит большое число,
# но не доходит до лимита рекурсии

Чтобы выйти из рекурсии, нужно ввести команду stopCondition.

Исходная переменная должна быть передана рекурсивной функции, чтобы сохранить её.

Рекурсивный подход — Большая Энциклопедия Нефти и Газа, статья, страница 1

Cтраница 1

Рекурсивный подход обычно предпочитается итеративному в тех случаях, когда рекурсия более естественно отражает математическую сторону задачи и приводит к программе, которая проще для понимания и отладки. Другой причиной для выбора рекурсивного решения является то, что итеративное решение может не быть очевидным.  [1]

Рекурсивный подход полезен прежде всего для алгоритмов на графах ( см. разд.  [2]

Обычно рекурсивный подход предпочитают итеративному, если он более естественно отражает задачу и ее результаты, то есть более нагляден и легче отлаживается. Другая причина предпочтения рекурсивного решения состоит в том, что итеративное решение может не быть очевидным.  [3]

Используя рекурсивный подход, аналогичный программе 13. 6, реализуйте операции construct, search и insert для таблиц символов, в основе которых лежат структуры данных в виде сбалансированных по высоте ( AVL) деревьев.  [4]

Используя RB-представление и рекурсивный подход, аналогичный программе 13.6, реализуйте операции construct, search и insert для таблиц символов, в основе которых лежат структуры данных в виде восходящих сбалансированных 2 — 3-де-ревьев.  [5]

Используя RB-представление и рекурсивный подход, аналогичный программе 13.6, реализуйте операции construct, search и insert для таблиц символов, в основе которых лежат структуры данных в виде восходящих сбалансированных 2 — 3 — 4-деревьев. Совет: код может выглядеть аналогично программе 13.6, но должен выполнять операции в другом порядке.  [6]

Используя RB — представление и рекурсивный подход, аналогичный программе ] 3.6, ревизуйте операции construct t № urch к / iufrt ии та & шц t и мнило в, ь основе которых лежат структуры данных ь виде вое ходя а дик сбгизнснршнишмк деревьев, С и: кат может ьыглддеть анпогичтю программе 13, ft, nn выполнять операции в другом порядке.  [7]

Некоторые неприятности могут поджидать любителей рекурсивного подхода к написанию функции. Возможны, в принципе, ситуации, когда рекурсивные вызовы переполнят внутренний стек данных сопроцессора, рассчитанный на восемь уровней рекурсии, и возникнет сбой программы.  [8]

Решение не всякой проблемы выигрывает от использования рекурсивного подхода, а порой и невозможно применить рекурсию. Однако если Вы в состоянии управлять списком LIFO в любом виде, то Ваша задача по существу является рекурсивной. Даже в том случае, когда рекурсия невозможна, целесообразно выполнить первоначальный вариант в виде рекурсивной программы, затем отбросить рекурсию, моделируя LIFO-память с помощью Ваших собственных связанных списков или индексированных структур данных. Полученная в результате программа будет гораздо яснее и проще для понимания, чем в случае ее разработки с пустого места.  [9]

Программа, иллюстрирующая области действия ( часть 2 из 2.  [10]

Сначала мы рассмотрим рекурсию обобщенно, а затем исследуем несколько программ, содержащих рекурсивные функции. Рекурсивные подходы к решению задач имеют ряд общих элементов. Для решения задачи вызывается рекурсивная функция. Фактически функция знает решение только простейшего случая ( случаев), или так называемого основного случая. Если функция вызывается для решения основного случая, то она просто возвращает результат. Если функция вызывается для решения более сложной проблемы, функция делит задачу на две обобщенных части: часть, для которой функция имеет способ решения, и часть, для которой функция решения не имеет. Чтобы сделать рекурсию возможной, последняя часть должна быть похожа на первоначальную задачу, но она должна быть более простым, или редуцированным ее вариантом. Поскольку эта новая задача похожа на первоначальную, функция запускает ( вызывает) свою новую копию, чтобы продолжить решение меньшей задачи. Этот процесс называется рекурсивным вызовом или шагом рекурсии.  [11]

Эту программу было бы трудно понять без двух уровней абстракции, разработанных для ее реализации. Несложно убедиться, что рекурсивный подход реализует ротации, изображенные на рис. 13.17; затем можно убедиться, что программа реализует высокоуровневый алгоритм в 2 — 3 — 4-деревьях — разделяет 4-узлы на пути вниз по дереву, а затем вставляет новый элемент в 2 — или 3-узел в месте завершения пути поиска в нижней части дерева.  [12]

Лисп входит в число наиболее значимых и долговечных языков программирования. Его влияние на исследования в области искусственного интеллекта и технологии знаний особенно проявилось в интерактивном программировании, методах функционального программирования, в распространении в программировании идей рекурсивного подхода, а также в том, что многие идеи в последствии были включены Китайский в более новые языки программирования.  [13]

Страницы:      1

Рекурсивная модель — Энциклопедия по экономике

Пример рекурсивной модели  [c. 300]

Независимо от того, хотим ли мы оценить одно из уравнений системы или же намерены оценить каждое уравнение модели, мы оказываемся в ситуации, когда ни обыкновенный метод наименьших квадратов, ни его модификации, рассмотренные в главах о модели, состоящей из одного уравнения, в общем случае не обеспечивают удовлетворительную процедуру оценивания. Если обыкновенный метод наименьших квадратов применяется к уравнению модели, в которое обычно будут входить несколько текущих значений эндогенных переменных, то придется одну из них выбрать в качестве зависимой переменной для данного уравнения. Тогда оставшиеся (одно или несколько) текущие значения эндогенных переменных, участвующие в этом соотношении, будут, вообще говоря, коррелировать с возмущающим воздействием и поэтому оценки, найденные обыкновенным методом наименьших квадратов, окажутся смещенными и несостоятельными. Только в случае рекурсивных моделей обыкновенный метод наименьших квадратов, как мы увидим в параграфе 13.1, дает нам оптимальный способ оценивания.  [c.375]


Мы уже знаем, что трудности при оценивании систем одновременных уравнений возникают из-за корреляции между возмущениями и эндогенными переменными и поэтому нам теперь необходимо убедиться в том, что специальные свойства рекурсивной модели позволяют эти трудности преодолеть.  [c.376]

X2. таблица 431 Распределенный лаг 292 Регрессия трех переменных 63 Рекурсивные модели 375  [c.441]

Большинство используемых финансовых моделей имеют рекурсивный и/или параллельный характер. Рекурсивность означает, что для решения очередного уравнения в его правую часть вместо переменной подставляется предыдущее уравнение, решенное относительно этой переменной, и т. д.  [c.300]

Рекурсивными являются модели, в которых неправильные конфигурации повторяются при  [c.44]

Если из модели исключить тождество дохода, число предопределенных переменных модели уменьшится на 1 (из модели будет исключена переменная G,). Число эндогенных переменных модели также снизится на единицу — переменная Y, станет экзогенной. В правых частях функции потребления и функции денежного рынка будут находиться только предопределенные переменные. Функция инвестиций постулирует зависимость эндогенной переменной I, от эндогенной переменной г, (которая зависит только от предопределенных переменных) и предопределенной переменной /,.]. Таким образом, мы получим рекурсивную систему. Ее параметры можно оценивать обычным МНК, и нет необходимости исследования системы уравнения на идентификацию.  [c.121]


Однако если зависимая переменная у одного уравнения выступает в виде фактора х в другом уравнении, то исследователь может строить модель в виде системы рекурсивных уравнений  [c.179]

Как уже отмечалось, не все эконометрические модели имеют вид системы одновременных уравнений. Так, широкий класс функций спроса на ряд потребительских товаров часто представляет собой рекурсивную систему, в которой с уравнениями можно работать последовательно и проблемы одновременного оценивания не возникают.  [c.212]

Здесь j указывает на объясняющую переменную, связь которой с объясняемой переменной / раскрывается в структурной модели, к пробегает по подмножеству всех переменных, непосредственно влияющих на j-ю переменную (на графе эти вершины связаны с вершиной / дугами). Соотношение (4.20) справедливо для любой рекурсивной системы.  [c.221]

Формальное содержание этого подхода заключается в гипотезе о полностью специфицированной линейной рекурсивной причинной модели, оценке ее параметров, а затем использовании этих значений для воспроизведения эмпирической корреляционной матрицы. Основная идея процедуры — это положение о том, что модель, которая не воспроизводит эмпирических корреляций, должна быть отвергнута.  [c.222]

Второй ситуацией является случай с неизвестным каузальным приоритетом среди переменных. Допустим, что мы имеем набор переменных, для которых не известен каузальный порядок причина-следствие, и имеются две гипотезы, каждая по-своему устанавливающая его, постулируя отсутствие тех или иных возможных отношений. Описываемый подход может быть применен как для сравнения этих теорий, так и для их отбрасывания. Заметим, что в процедуре сравнения одна модель-гипотеза может оказаться лучше другой, но никогда — правильной. Более того, если одна из гипотез близка к тому, чтобы описываться полной рекурсивной системой, то обычно она работает, лучше воспроизводя корреляционную матрицу, и, естественно, будет выбираться как более удачная, даже если она весьма далека от истины.  [c.223]


Модель включает как рекурсивные, так и одновременно решаемые уравнения, причем наличие последних позволяет учесть и некоторые обратные связи процесса энергопотребления. Это делает модель адекватной реальным взаимосвязям, что, в свою очередь, повышает надежность и достоверность прогнозных расчетов.  [c.201]

Необходимость рассматривать системы, отличные от рекурсивных, возникает в связи с тем, что исследователь обычно располагает некоторыми усредненными (агрегированными) данными. Например, данные о рыночной конъюнктуре могут быть усреднены по недельным или месячным периодам. Предположим, что известны величины Pt — средняя цена за неделю t и Qt — средний объем ежедневных продаж за неделю /. Если считать время реакции рынка, как и раньше, равным одному дню, то соотношение Pt = a0 + a j. + UL вряд ли можно признать разумным. В этой ситуации рассмотренная в 14.1 модель представляется более естественной.  [c.414]

МОДЕЛЬ РЕКУРСИВНАЯ — одна из эконометрических моделей, в которой причинно-следственные связи эндогенных переменных находятся в строгой односторонней последовательности. В данной модели матрица параметров представлена в виде треугольника, а отклонения случайных величин не находятся в прямой или обратной корреляции.  [c.385]

Это модель, в которой текущие значения одного множества переменных определяют текущие значения первого. Простейший пример модели рекурсивной имеет следующий вид  [c.385]

Одним из случаев успешного применения МНК для оценки структурных коэффициентов модели является его использование для рекурсивных (треугольных) моделей. В этих моделях эндогенные переменные последовательно (рекурсивно) связаны друг с другом. А именно, первая эндогенная переменная YI зависит лишь от экзогенных переменных Хь i = 1, 2,. .., m и случайного отклонения Si. Вторая эндогенная переменная Y2 определяется лишь значениями экзогенных переменных Х i = 1, 2,. .., m случайным отклонением 82, а также эндогенной переменной YI. Третья эндогенная переменная Y3 зависит от тех же переменных, что и Y2, случайного отклонения з, а также от предыдущих эндогенных переменных (Yi, Y2) и т. д.  [c.326]

Рекурсивность функции оптимизации. В результате анализа было выявлено, что модель оптимизации ассортимента, как правило, предполагает с учетом ограничений увеличить долю той продукции, которая имеет наибольшую маржинальную рентабельность или какой-либо коэффициент перспективности или привлекательности, и на этом оптимизационные расчеты заканчиваются. Однако увеличение объема реализации требует либо снижения цены, либо увеличения затрат на продвижение. Поэтому, вполне возможно, стремление увеличить объем реализации будет сопровождаться снижением рентабельности, что в свою очередь может потребовать пересмотра оптимальной структуры. Поскольку обычно в оптимизационную модель не закладываются затраты на достижение определенного уровня рентабельности, объема реализации (так как неизвестно, каким будет этот оптимальный объем реализации), то расчетный теоретический уровень прибыли является на практике не достижимым при существенных расчетных изменениях структуры ассортимента. Разрешение данного противоречия следует проводить путем имитации возможных затрат на достижение определенного объема реализации продукции.  [c.39]

Раздумывая над этими рекурсивными моделями, заливами внутри заливов, Мандельброт назвал этот феномен «фрактально-стью». Что интересно в отношении фракталов, так это то, что они показывают, что система может постоянно повторять свои модели в различных масштабах или шкалах. Другими словами, является самомоделируемой.  [c.62]

Рекурсивная модель (re ursive model) — динамическая модель, обладающая математическим свойством рекурсии, т. е. если даны, например, все переменные модели до момента (t— 1), то модель обеспечивает и получение одного за другим значений переменных для t, по ним для (t+1) и т. д. — Прим. научи, ред.  [c.62]

Для предсказания волатильности при помощи GAR H можно использовать рекурсивную модель следующего вида  [c.361]

Величины Ut и Vt обозначают накопленные за неделю возмущения. Без введения дополнительных переменных эта модель оказывается теперь даже неидентифицируемой, однако если бы идентифицирующие ее переменные и существовали, то мы убедились бы, что в общем случае вынужденное агрегирование по временнь ш периодам может превратить чисто рекурсивную модель в полностью одновременную со всеми вытекающими отсюда проблемами ее оценивания.  [c.379]

Рассмотрим подразделение hevrolet. Система I может включать различные производственные цехи. Система II будет координировать взаимодействие производственных цехов, система III — размещать инвестиции на модернизацию различных цехов. Система IV будет рассматривать вопрос о том, нужны ли новые производственные методы или модели. Система V будет решать, когда вводить новые модели или производственные методы. Рекурсивные уровни опускаются вниз до определенного уровня в зависимости от того, что предпочтет индивид, который должен выполнять поставленные задачи (системы I, II и III), — поменять работу или получить новые знания (системы IV и V).  [c.302]

Фрактальная геометрия, она же — рекурсивная геометрия — геометрия динамических форм, моделей, которые обладают математическим свойством рекурсии. Это значит, что если даны, например, все переменные модели до момента (t-1), то модель обеспечивает и получение одного за другим значений переменных для t, по ним — для (t+1) и тд. Вообще, рекурсия (re urren e) — в общем смысле вычисление функции по определенному алгоритму. Примерами таких алгоритмов являются рекуррентные формулы, выводящие вычисления заданного члена последовательности (чаще всего числовой) из вычисления нескольких предыдущих ее членов. Например, если X1=2,Xk+1=2Xk+2, то задана числовая последовательность 2,4,10,22…  [c.3]

На основании собственного опыта я разработал довольно интересную гипотезу о фондовых рынках я постулировал, что фондовый рынок при адаптации теории научного метода Поппера действует во многом так же, как и я, с той лишь разницей, что он не знает, что так поступает. Другими словами, он выбирает некий тезис и проверяет его когда он оказывается ошибочным, как это обычно и бывает, он проверяет другой тезис. Это и вызывает колебания на рынке. Такой процесс происходит на разных уровнях, а получаемые модели являются рекурсивными, как и фракталы Мандельброта10.  [c.44]

И последнее модель может быть включена в качестве составной части в многосетевую среду принятия решений, а полученная общая производительность — измеряться, исходя из заданного решающего правила (см. [290]). Наконец, более динамичные подходы можно получить, используя рекурсивные сети с механизмами обратной связи.  [c.227]

Для формальной верификации гипотез необходимо соответствие между графом и системой уравнений, его описывающей. Алгебраическая система, соответствующая графу без контуров (петель), является рекурсивной системой, позволяющей рекур-рентно определять значения входящих в нее переменных. В такой системе в уравнения для признака xt включаются все переменные, за исключением расположенных выше его по графу связей. Формулировка гипотез в структуре рекуррентной модели обычно не вызывает затруднений при использовании данных в динамике. Если же анализируются статистические данные, то следует учитывать зависимость системы от ее прошлых состояний.  [c.213]

Паутинообразная модель ( obweb) в теории цены является рекурсивной.  [c.425]

СВЯЗИ В СИСТЕМЕ. Определений термина связь — десятки. Самое общее таково это то, что объединяет элементы системы в одно целое. Связи между элементами системы могут быть жесткими (таковы они обычно в технике) и гибкими, изменяющя-мися в процессе функционирования системы, — таковы они в экономике, в живых существах, в обществе. С точки зрения кибернетики связь— это процесс обмена информацией, который регулирует поведение систем (т. е. управляет ими). Наиболее важными считаются следующие виды связей обратные, рекурсивные, синерги-ческие (т. е. усиливающие) и циклические. В экономико-математической модели они выражаются через уравнения связи или неравенства связи  [c.51]

Вместе с тем учтённый в модели Леонтьева принцип формирования цен мирового рынка в какой-то мере отражает процессы, происходящие в реальности. Вопрос в том, как относиться к этим процессам считать ли их естественными и заслуживающими дальнейшего распространения или, наоборот, противодействующими прогрессу и требующи.ми замены. Ответ может быть получен при изучении свойств динамич. рекурсивно-балансовой модели, требующей изменяющихся цен. Они вводятся в такие модели как оценки баланса прошлого года. Если бы в проекте Будущее мировой экономики была осуществлена динамизация модели, то использованный метод определения цен привёл бы к реализации долгосрочной стратегии развития, основанной на принципе сравнительных издержек. Выигрыш от такой стратегии получает сильнейший из внешнеторговых партнёров, поскольку остальные деформируют структуру своего х-ва в соответствии с его интересами. При введении оптимизации в долгосрочные модели, опирающиеся на межотраслевой баланс, стратегия сравнительных издержек, в силу к-рой каждый регион должен специализироваться на том, что он умеет производить лучше в данный момент, становится господствующей, а возможности выбора иной стратегии долгосрочного развития практически исключаются. Проекция подобного подхода на региональную структуру способ-па породить лишь наиболее нереалистич. рекомендации по размещению нроиз-ва и разделению труда между  [c.616]

Следовательно, нам достаточно освоить только эту рекурсивную процедуру, с тем чтобы любой руководитель предприятия, владеющий общей ситуацией на предприятии и в подразделениях, а также знающий цели и задачи предприятия, смог без особого труда создать подобную модель (Модель2) применительно к предприятию в целом.  [c.322]

Рекурсивный алгоритм экспоненциального скользящего среднего выглядит так для каждой точки данных коэффициент (с), определяющий эффективную длину скользящего среднего (m), умножается на значение данной точки данных и к результату прибавляется разность 1,0 — с, умноженная на текущее значение скользящего среднего, что и дает новое значение. Коэффициент с приравнивается к2,0/(т+1),где т— период скользящей средней. Чанд в 1992 г. модифицировал данный алгоритм. В его модели значение коэффициента с не является константой, а зависит от текущей волатильности рынка — громкости рынка, выраженной в виде стандартного отклонения цен за некоторое количество последних точек данных. Поскольку стандартное отклонение сильно варьируется на разных рынках и показатель волатильности должен быть относительным, Чанд предложил делить наблюдаемое стандартное отклонение для каждой точки на среднее значение стандартного отклонения для всех точек в имеющемся образце данных. Для каждого бара коэффициент 2,0/(т + 1)) рассчитывается заново, умножаясь на относительную волатильность, таким образом получается скользящее среднее с периодом, динамически подстраивающимся под активность рынка.  [c.134]

И главный фактор успеха здесь — это понимание того, что такое рациональное инвестиционное поведение, плюс качественная и количественная математическая модель такого поведения. Много сил в науке было отдано тому, чтобы описать рациональный инвестиционный выбор (например, через функцию инвестиционной полезности). Однако, если исследование аспектов рационального инвестиционного поведения не опирается на детальный анализ фондового рынка и макроэкономической обстановки в стране, где осуществляются инвестиции, то такой анализ рационального инвестиционного поведения является бесполезным. А в такой постановке задача практически не звучит. Приятным исключением является подход, применяемый компанией Latti e Finan ial [129], где прослеживается детальная модельная связь между макроэкономическими факторами и количественными оценками тенденций фондового рынка. Но здесь другая крайность слишком велика в моделях [129] доля механистического понимания связей на макро- и микроуровне, когда возникает прямой соблазн рекурсивного прогнозирования , где будущее с точностью до вероятностно расред елейного случайного сигнала определяется настоящим. Фактор рационализации выбора совершенно выпадает из моделей такого сорта.  [c.95]

Рекурсивное определение и значение | Dictionary.com

  • Лучшие определения
  • Викторина
  • Связанный контент
  • Подробнее о рекурсивном
  • Примеры

Показывает уровень оценки в зависимости от сложности слова.

[ ri-kur-siv ]

/ rɪˈkɜr sɪv /

Сохранить это слово!

См. синонимы слова «рекурсивный» на Thesaurus.com

Показывает уровень оценки в зависимости от сложности слова.


прилагательное

, относящееся к правилу или процедуре, которые можно применять повторно, или использующие их.

Математика, Вычислительная техника. относящийся к математическому процессу рекурсии или использующий его: рекурсивная функция; рекурсивная процедура.

ВИКТОРИНА

Сыграем ли мы в «ДОЛЖЕН» ПРОТИВ. «ДОЛЖЕН» ВЫЗОВ?

Должны ли вы пройти этот тест на «должен» или «должен»? Это должно оказаться быстрым вызовом!

Вопрос 1 из 6

Какая форма используется для указания обязательства или обязанности кого-либо?

Происхождение рекурсивного

Впервые записано в 1935–1940 гг.; рекурс(ион) + -ive

ДРУГИЕ СЛОВА ИЗ рекурсивный

рекурсивный лы, наречие курсивность, существительное

Слова рядом рекурсивный

повторяющийся, повторяющийся десятичный, рецидивирующая цифровая фиброма детства, рекурсия, формула рекурсии, рекурсия, рекурсивное определение, рекурсивная функция, рекурсивная подпрограмма, рекурсия, рекурсия

Dictionary.com Unabridged Основано на словаре Random House Unabridged Dictionary, © Random House, Inc., 2022 г.

ПОДРОБНЕЕ О РЕКУРСИИ

Что означает

рекурсивный ?

Что-то рекурсивное зациклено, особенно таким образом, что процесс может повторяться.

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

Пример: Программа является рекурсивной: как только она завершает свою функцию поиска, она автоматически начинает сначала.

Откуда

рекурсивное ?

Рекурсивный существует как минимум с конца 1700-х годов. Оно происходит от комбинации латинского recursiōn-, , что означает «бегущий назад», и суффикса прилагательного -ive . Его форма существительного, рекурсия , был записан с начала 1600-х годов. Бит -curs- в recursive происходит от слова, означающего бежать, которое также встречается в таких словах, как . Таким образом, вы можете думать о рекурсивном как о повторном выполнении .

Рекурсивный первоначально просто означало «постоянно повторяющийся», но к середине 1900-х годов он приобрел специальный математический смысл. Математический смысл относится к применению функции к ее собственным значениям для создания бесконечной последовательности значений. Уравнение, которое дает нам знаменитую последовательность Фибоначчи, является таким процессом.

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

Если вы еще не до конца понимаете рекурсивное , было бы неплохо прочитать эту статью еще раз с начала (и рекурсивное !).

Знаете ли вы…?

Как

рекурсивное используется в реальной жизни?

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

Я определенно добавляю свой сайт-портфолио в качестве одного из своих проектов на моем сайте-портфолио 🙂.

Рекурсивное нечто 😋

— И Ф Е Д И Л И ⚡ (@SauceCodee) 8 декабря 2019 г.

К сожалению, крупные телевизионные награды по-прежнему чрезвычайно важны для определения основных показателей того, как выглядит «хороший» фильм. Это рекурсивное явление.

— Дана Шварц (@DanaSchwartzzz) 9 декабря 2019 г.

Мать Мадонны тоже была Мадонной, поэтому представьте картину эпохи Возрождения под названием «Мадонна с младенцем», которая представляет собой рекурсивное изображение поп-звезды 80-х, держащей уменьшенную версию себя, которая держит уменьшенную версию себя, которая держит уменьшенную версию себя. … pic.twitter.com/FTG25JWPRY

— ВРЕМЯ СКАНЕР (@timescanner) 4 декабря 2019 г.

Какое из следующих слов не соответствует общему значению рекурсивного ?

A. циклический
B. повторяющийся
C. рекуррентный
D. завершающий

Слова, относящиеся к рекурсивному

циклический, циклический, рекуррентный, повторяющийся, периодический, итеративный, повторяющийся

Как использовать рекурсивный в предложении

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

    Говорить — значит бросать друг в друга вымышленные миры — Выпуск 89: Темная сторона|Кевин Бергер|9 сентября 2020|Наутилус

  • Просто он думает, что иерархическая структура плоская, и поэтому Пираха не использует этого массивного рекурсивного устройства.

    Разговоры — это бросание вымышленных миров друг в друга — выпуск 89: Темная сторона|Кевин Бергер|9 сентября 2020 г. |Наутилус

  • То, как Дэн читал статью Хаузера-Хомски-Фитча, — это рекурсия языка.

    Говорить — значит бросать друг в друга вымышленные миры — Выпуск 89: Темная сторона|Кевин Бергер|9 сентября 2020 г.|Наутилус

  • Участников исследования обучали составлять из двух наборов символов рекурсивные шаблоны.

    Обезьяны могут иметь общие с людьми ключевые навыки, связанные с грамматикой|Брюс Бауэр|26 июня 2020 г.|Новости науки

  • Одно из двух животных оказалось в среднем более склонным к формированию новых рекурсивных последовательностей, чем примерно три четверти дошкольников и примерно половина жителей боливийских деревень.

    Обезьяны могут иметь общие с людьми навыки грамматики|Брюс Бауэр|26 июня 2020|Новости науки

  • С тех пор на Ирак обрушились черные миазмы рекурсивной мести.

    Что бы ты ни делал, кто-то умрет. Короткая история о невозможном выборе в Ираке|Натан Брэдли Бети|31 августа 2014 г. |DAILY BEAST 9Определение 0015

в кембриджском словаре английского языка

Примеры рекурсии

рекурсии

Хитрость в том, что эти три вещи подпитывают друг друга, иногда рекурсивно способами.

Из проводного