~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 9B2B4CE69BA5F6DFEB2F7744F2BC0CD1__1712226600 ✰
Заголовок документа оригинал.:
✰ Memoization - Wikipedia ✰
Заголовок документа перевод.:
✰ Мемоизация — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Memoization ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/9b/d1/9b2b4ce69ba5f6dfeb2f7744f2bc0cd1.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/9b/d1/9b2b4ce69ba5f6dfeb2f7744f2bc0cd1__translat.html ✰
Дата и время сохранения документа:
✰ 16.06.2024 09:26:51 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 4 April 2024, at 13:30 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Мемоизация — Википедия Jump to content

Мемоизация

Из Википедии, бесплатной энциклопедии

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

Этимология [ править ]

Термин мемоизация был придуман Дональдом Мичи в 1968 году. [3] и происходит от латинского слова memorandum («чтобы запомнить»), которое в американском английском обычно сокращается до memo , и, таким образом, означает «превращение [результатов] функции в нечто, что нужно запомнить». Хотя мемоизацию можно спутать с запоминанием (поскольку они являются этимологическими родственниками ), мемоизация имеет особое значение в вычислительной технике.

Обзор [ править ]

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

Мемоизированные функции оптимизированы по скорости в обмен на более активное использование компьютера памяти . Временная/пространственная «стоимость» алгоритмов имеет в вычислительной технике особое название: вычислительная сложность . Все функции имеют вычислительную сложность во времени (т.е. для их выполнения требуется время) и в пространстве .

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

Рассмотрим следующую функцию псевдокода для факториала n : вычисления

функция факториал (  n  — целое неотрицательное число) 
      если  n  равно 0, то 
          return 1 [  по соглашению, что   0!   = 1  ] 
      еще 
          вернуть факториал(  n  – 1) раз  n  [  рекурсивно вызвать факториал  
                                         с параметром 1 меньше n  ] 
      конец, если 
  конечная функция 
 

Для любого целого числа n такого, что n ≥ 0, конечный результат функции factorialявляется инвариантным ; если вызывается как x = factorial(3), результат таков, что x будет всегда присвоено значение 6. Приведенная выше немемоизированная реализация, учитывая природу используемого рекурсивного алгоритма, потребует n + 1 вызовов factorialдля получения результата, и каждый из этих вызовов, в свою очередь, имеет соответствующую стоимость в виде времени, которое требуется функции для возврата вычисленного значения. В зависимости от машины эта стоимость может составлять сумму:

  1. Стоимость настройки кадра функционального стека вызовов.
  2. Стоимость сравнения n с 0.
  3. Стоимость вычитания 1 из n .
  4. Стоимость настройки кадра стека рекурсивных вызовов. (Как указано выше.)
  5. Стоимость умножения результата рекурсивного вызова factorial по н .
  6. Стоимость сохранения возвращаемого результата, чтобы его можно было использовать вызывающим контекстом.

В немемоизированной реализации каждый вызов верхнего уровня factorial включает совокупную стоимость шагов со 2 по 6, пропорциональную начальному значению n .

Мемоизированная версия factorial функция следующая:

функция факториал (  n  — целое неотрицательное число) 
      если  n  равно 0, то 
          return 1 [  по соглашению, что   0!   = 1  ] 
      иначе, если  n  находится в  справочной таблице  , тогда 
          вернуть  значение-таблицы поиска для-n 
      еще 
          let x = Factorial(n – 1) раз  n  [  рекурсивно вызывать факториал 
                                          с параметром 1 меньше n  ] 
          сохранить  x  в  справочной таблице  в  n й slot [  запомнить результат n!   Для последующего  ] 
          вернуть х 
      конец, если 
  конечная функция 
 

В этом конкретном примере, если factorial сначала вызывается со значением 5, а затем вызывается позже с любым значением, меньшим или равным пяти, эти возвращаемые значения также будут запомнены, поскольку factorialбудет вызываться рекурсивно со значениями 5, 4, 3, 2, 1 и 0, а возвращаемые значения для каждого из них будут сохранены. Если затем он вызывается с номером больше 5, например 7, будет выполнено только 2 рекурсивных вызова (7 и 6), а значение 5! будут сохранены с предыдущего вызова. Таким образом, мемоизация позволяет функции более эффективно расходовать время, чем чаще она вызывается, что в конечном итоге приводит к общему ускорению.

Некоторые другие соображения [ править ]

Функциональное программирование [ править ]

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

Автоматическое запоминание [ править ]

Хотя мемоизация может быть добавлена ​​к функциям внутренне и явно программистом, почти так же, как и вышеприведенная мемоизированная версия factorial реализована, ссылочно прозрачные функции также могут автоматически запоминаться извне . [1] Методы, использованные Питером Норвигом, применяются не только в Common Lisp (языке, на котором в его статье продемонстрировано автоматическое запоминание), но и в различных других языках программирования . Применение автоматического запоминания также было официально изучено при изучении переписывания терминов. [4] и искусственный интеллект . [5]

В языках программирования, где функции являются объектами первого класса (например, Lua , Python или Perl [6] ), автоматическое запоминание может быть реализовано путем замены (во время выполнения) функции ее вычисленным значением после того, как значение было рассчитано для данного набора параметров. Функция, выполняющая замену значения на объект-функцию, может в общем случае обертывать любую ссылочно прозрачную функцию. Рассмотрим следующий псевдокод (где предполагается, что функции являются значениями первого класса):

функция memoized-call (  F  — параметр объекта функции) 
      если  F  не имеет присоединенных  значений  массива , тогда 
          выделить  ассоциативный массив  с  именемvalues  ; 
          прикрепить  значения  к  F  ; 
      конец, если; 

      если  Ф.   значения [аргументы]  пусты, тогда 
          Ф.   значения[аргументы]  =  F  (аргументы); 
      конец, если; 

      вернуть F.  значения[аргументы]  ; 
  конечная функция 
 

Чтобы вызвать автоматически сохраненную версию factorial используя описанную выше стратегию, вместо вызова factorial напрямую, код вызывает memoized-call(factorial(n)). Каждый такой вызов сначала проверяет, выделен ли массив-держатель для хранения результатов, и если нет, присоединяет этот массив. Если в позиции нет записи values[arguments] (где arguments используются в качестве ключа ассоциативного массива), реальный вызов осуществляется factorialс предоставленными аргументами. Наконец, запись в массиве в ключевой позиции возвращается вызывающей стороне.

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

функция-конструктор-мемоизированный-функтор (  F  — параметр объекта функции) 
      выделите функциональный объект с именем  memoized-version  ; 

      пусть memoized-версия(аргументы) будет 
          если  у self  нет присоединенных значений массива, тогда [  self  является ссылкой на  этот  объект  ] 
              выделить ассоциативный массив с  именемvalues  ; 
              придавать  ценности  себе  ; 
          конец, если; 

          если сам.   значения [аргументы]  пусты, тогда 
              себя.   значения[аргументы]  =  F  (аргументы); 
          конец, если; 

          вернуть себя.   значения[аргументы]  ; 
      конец пусть; 

      вернуть  мемоизированную версию  ; 
  конечная функция 
 

Вместо того, чтобы позвонить factorial, новый объект функции memfact создается следующим образом:

 memfact = конструкция-мемоизированный-функтор (факториал)
 

В приведенном выше примере предполагается, что функция factorial уже было определено до вызова construct-memoized-functorсделан. Начиная с этого момента, memfact(n) факториал n вызывается всякий раз, когда требуется . В таких языках, как Lua, существуют более сложные методы, которые позволяют заменять функцию новой функцией с тем же именем, что позволяет:

 факториал = конструкция-мемоизированный-функтор (факториал)
 

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

функция-конструктор-мемоизированный-функтор (  F  — параметр объекта функции) 
      выделите функциональный объект с именем  memoized-version  ; 

      пусть  мемоизированная версия  (аргументы) будет 
          если  у self  нет присоединенных значений массива, тогда [  self  является ссылкой на этот объект  ] 
              выделить ассоциативный массив с  именемvalues  ; 
              придавать  ценности  себе  ; 
              выделите новый объект функции с именем  alias  ; 
              прикрепить  псевдоним  к  себе  ;   [  вызывать  F  для последующей возможности косвенно  ] 
              себя.   псевдоним  =  F  ; 
          конец, если; 

          если сам.   значения [аргументы]  пусты, тогда 
              себя.   значения [аргументы]  = self.   псевдоним  (аргументы);   [  не  прямой звонок  F  ] 
          конец, если; 

          вернуть себя.   значения[аргументы]  ; 
      конец пусть; 

      вернуть  мемоизированную версию  ; 
  конечная функция 
 

(Примечание. Некоторые из показанных выше шагов могут неявно управляться языком реализации и приведены для иллюстрации.)

Парсеры [ править ]

Когда нисходящий синтаксический анализатор пытается проанализировать неоднозначные входные данные относительно неоднозначной контекстно-свободной грамматики (CFG), ему может потребоваться экспоненциальное количество шагов (относительно длины входных данных), чтобы опробовать все альтернативы CFG. для создания всех возможных деревьев разбора. В конечном итоге это потребует экспоненциального объема памяти. Мемоизация была исследована как стратегия синтаксического анализа в 1991 году Питером Норвигом, который продемонстрировал, что алгоритм, аналогичный использованию динамического программирования и наборов состояний в алгоритме Эрли (1970), а также таблиц в алгоритме CYK Кока, Янгера и Касами, может генерироваться путем введения автоматического запоминания в простой обратным отслеживанием анализатор рекурсивного спуска с для решения проблемы экспоненциальной временной сложности. [1] Основная идея подхода Норвига заключается в том, что когда к входным данным применяется парсер, результат сохраняется в memotable для последующего повторного использования, если тот же синтаксический анализатор когда-либо повторно применяется к тем же входным данным.

Ричард Фрост и Барбара Шидловски также использовали мемоизацию, чтобы уменьшить экспоненциальную временную сложность синтаксических комбинаторов , описывая результат как запоминающий чисто функциональный языковой процессор с нисходящим обратным отслеживанием. [7] Фрост показал, что базовые мемоизированные комбинаторы парсеров можно использовать в качестве строительных блоков для создания сложных парсеров как исполняемых спецификаций CFG. [8] [9]

Мемоизация была снова исследована в контексте синтаксического анализа в 1995 году Марком Джонсоном и Йохеном Дёрре. [10] [11] В 2002 году он был достаточно глубоко исследован Брайаном Фордом в форме, названной разбором Packrat . [12]

В 2007 году Фрост, Хафиз и Каллаган [ нужна цитата ] описал алгоритм синтаксического анализа сверху вниз, который использует мемоизацию для отказа от избыточных вычислений, чтобы приспособить любую форму неоднозначной CFG за полиномиальное время ( Θ (n 4 ) для леворекурсивных грамматик и Θ(n 3 ) для нелеворекурсивных грамматик). Их алгоритм нисходящего анализа также требует полиномиального пространства для потенциально экспоненциальных неоднозначных деревьев анализа посредством «компактного представления» и «группировки локальных неоднозначностей». Их компактное представление сравнимо с компактным представлением восходящего синтаксического анализа Томиты . [13] Их использование мемоизации не ограничивается только получением ранее вычисленных результатов, когда анализатор многократно применяется к одной и той же позиции ввода (что важно для требования полиномиального времени); он специализируется на выполнении следующих дополнительных задач:

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

Фрост, Хафиз и Каллаган также описали реализацию алгоритма в PADL'08. [ нужна цитата ] как набор функций высшего порядка (называемых комбинаторами синтаксического анализатора ) в Haskell , что позволяет создавать непосредственно исполняемые спецификации CFG как языковых процессоров. Важность способности их полиномиального алгоритма справляться с «любой формой неоднозначных CFG» с нисходящим синтаксическим анализом жизненно важна для синтаксического и семантического анализа во время обработки естественного языка . На сайте X-SAIGA можно найти дополнительную информацию об алгоритме и деталях реализации.

Хотя Норвиг увеличил мощность анализатора за счет мемоизации, расширенный анализатор по-прежнему был таким же сложным по времени, как алгоритм Эрли, который демонстрирует случай использования мемоизации для чего-то другого, кроме оптимизации скорости. Джонсон и Дорре [11] продемонстрировать еще одно такое применение мемоизации, не связанное со скоростью: использование мемоизации для задержки разрешения лингвистических ограничений до момента синтаксического анализа, где накоплено достаточно информации для разрешения этих ограничений. Напротив, в применении мемоизации для оптимизации скорости Форд продемонстрировал, что мемоизация может гарантировать, что синтаксический анализ грамматик выражений может анализировать за линейное время даже те языки , которые приводят к наихудшему поведению с возвратом. [12]

Рассмотрим следующую грамматику :

S → (А  c  ) |   (Б  д  ) 
  А → Икс (  а  |  б  ) 
  Б → Х  б 
  Икс →  х  [Х] 
 

(Примечание: в приведенном выше примере продукция S → (A c ) | (B d ) гласит: «An S — это либо A , за которым следует a c , либо B , за которым следует a d ». Продукция X → x [ X] гласит: « X — это x , за которым следует необязательный X ».)

Эта грамматика генерирует один из следующих трех вариантов строки : xac , xbc или xbd (где x здесь понимается как один или несколько ) x . Далее рассмотрим, как эта грамматика, используемая в качестве спецификации синтаксического анализа, может повлиять на Разбор строки xxxxxxbd сверху вниз и слева направо :

Правило A распознает xxxxxb (сначала спускаясь в X для распознавания одного x и снова спускаясь в X до тех пор, пока все x не будут израсходованы, а затем распознавая b ), а затем возвращаясь в S и не распознавая c . Следующее предложение S затем спустится в B, который, в свою очередь, снова спустится в X и распознает x посредством множества рекурсивных вызовов X , а затем a b , вернется к S и, наконец, распознает a d .

Ключевое понятие здесь заложено во фразе снова спускается X. в Процесс просмотра вперед, неудачи, резервного копирования и повторной попытки следующей альтернативы известен в синтаксическом анализе как возврат назад, и именно возврат назад предоставляет возможности для запоминания при синтаксическом анализе. Рассмотрим функцию RuleAcceptsSomeInput(Rule, Position, Input), где параметры следующие:

  • Rule — имя рассматриваемого правила.
  • Position это смещение, которое в данный момент рассматривается во входных данных.
  • Input является рассматриваемым входом.

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

Когда правило A спускается в X со смещением 0, оно запоминает длину 5 относительно этой позиции и X. правила После неудачи в d , B затем, вместо того, чтобы снова спуститься в X , запрашивает позицию 0 по правилу X в механизме запоминания и возвращает длину 5, тем самым избавляя от необходимости снова спускаться в X , и продолжает как если бы он спускался в X столько же раз, сколько раньше.

В приведенном выше примере может произойти один или несколько спусков на X , что позволяет использовать такие строки, как xxxxxxxxxxxxxxxxbd . Фактически, любое количество x может быть перед b . Хотя вызов S должен рекурсивно спускаться в X столько раз, сколько существует x , B вообще никогда не придется спускаться в X, поскольку возвращаемое значение RuleAcceptsSomeInput(X, 0, xxxxxxxxxxxxxxxxbd) будет 16 (в данном конкретном случае).

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

С → (А)?  А
 A → /* какое-то правило */
 

к одному спуску в A .

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

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

См. также [ править ]

Ссылки [ править ]

  1. ^ Перейти обратно: а б с Норвиг, Питер (1991). «Методы автоматического запоминания с помощью приложений для контекстно-свободного анализа» . Компьютерная лингвистика . 17 (1): 91–98.
  2. ^ Уоррен, Дэвид С. (1 марта 1992 г.). «Мемориалы для логических программ» . Коммуникации АКМ . 35 (3): 93–111. дои : 10.1145/131295.131299 . ISSN   0001-0782 .
  3. ^ Мичи, Дональд (1968). « Функции Memo и машинное обучение» (PDF) . Природа . 218 (5136): 19–22. Бибкод : 1968Natur.218...19M . дои : 10.1038/218019a0 . S2CID   4265138 .
  4. ^ Хоффман, Бертольд (1992). «Переписывание терминов с обменом и мемоизацией». В Киршнере, Х.; Леви, Г. (ред.). Алгебраическое и логическое программирование: Третья международная конференция, материалы, Вольтерра, Италия, 2–4 сентября 1992 г. Конспекты лекций по информатике. Том. 632. Берлин: Шпрингер. стр. 128–142. дои : 10.1007/BFb0013824 . ISBN  978-3-540-55873-6 .
  5. ^ Мэйфилд, Джеймс; и другие. (1995). «Использование автоматического запоминания как инструмента разработки программного обеспечения в реальных системах искусственного интеллекта» (PDF) . Материалы одиннадцатой конференции IEEE по искусственному интеллекту для приложений (CAIA '95) . стр. 87–93. дои : 10.1109/CAIA.1995.378786 . hdl : 11603/12722 . ISBN  0-8186-7070-3 . S2CID   8963326 .
  6. ^ «Бриколаж: Мемоизация» .
  7. ^ Фрост, Ричард; Шидловски, Барбара (1996). «Запоминание чисто функциональных языковых процессоров с нисходящим возвратом» . наук. Вычислить. Программа . 27 (3): 263–288. дои : 10.1016/0167-6423(96)00014-7 .
  8. ^ Фрост, Ричард (1994). «Использование мемоизации для достижения полиномиальной сложности чисто функциональных исполняемых спецификаций недетерминированных нисходящих парсеров». Уведомления SIGPLAN . 29 (4): 23–30. дои : 10.1145/181761.181764 . S2CID   10616505 .
  9. ^ Фрост, Ричард (2003). «Монадическая мемоизация к сокращению поиска, сохраняющему корректность». Канадская конференция по искусственному интеллекту 2003 г. Конспекты лекций по информатике. Том. 2671. стр. 66–80. дои : 10.1007/3-540-44886-1_8 . ISBN  978-3-540-40300-5 .
  10. ^ Джонсон, Марк (1995). «Мемоизация нисходящего синтаксического анализа». Компьютерная лингвистика . 21 (3): 405–417. arXiv : cmp-lg/9504016 . Бибкод : 1995cmp.lg....4016J .
  11. ^ Перейти обратно: а б Джонсон, Марк и Дорре, Йохен (1995). «Мемоизация сопрограммных ограничений». Материалы 33-го ежегодного собрания Ассоциации компьютерной лингвистики . Кембридж, Массачусетс. arXiv : cmp-lg/9504028 . {{cite book}}: CS1 maint: отсутствует местоположение издателя ( ссылка )
  12. ^ Перейти обратно: а б Форд, Брайан (2002). Анализ Packrat: практический алгоритм линейного времени с обратным отслеживанием (магистерская диссертация). Массачусетский Институт Технологий. hdl : 1721.1/87310 .
  13. ^ Томита, Масару (1985). Эффективный синтаксический анализ естественного языка . Бостон: Клювер. ISBN  0-89838-202-5 .
  14. ^ Ачар, Умут А.; и другие. (2003). «Выборочная мемоизация». Материалы 30-го симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования, 15–17 января 2003 г. Том. 38. Новый Орлеан, Луизиана. стр. 14–25. arXiv : 1106.0447 . дои : 10.1145/640128.604133 . {{cite book}}: |journal= игнорируется ( помощь ) CS1 maint: отсутствует местоположение издателя ( ссылка )

Внешние ссылки [ править ]

Примеры мемоизации на различных языках программирования
Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 9B2B4CE69BA5F6DFEB2F7744F2BC0CD1__1712226600
URL1:https://en.wikipedia.org/wiki/Memoization
Заголовок, (Title) документа по адресу, URL1:
Memoization - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)