что такое динамический метод
Практическое руководство. Определение и выполнение динамических методов
В следующих процедурах показаны способы определения и выполнения простого динамического метода и динамического метода, привязанного к экземпляру класса. Дополнительные сведения о динамических методах см. в описании класса DynamicMethod и в разделе Сценарии динамических методов порождаемого отражения.
Определение и выполнение динамического метода
Создайте массив, в котором будут указаны типы параметров динамического метода. В этом примере единственным параметром является int ( Integer в Visual Basic), поэтому массив содержит только один элемент.
Нет необходимости предоставлять имена динамических методов, они не могут быть вызваны по именам. Несколько динамических методов могут иметь одинаковое имя. Но это имя отображается в стеках вызовов и может оказаться полезным при отладке.
Выпустите основную часть метода. В этом примере объект ILGenerator используется для выпуска MSIL. В качестве альтернативы объект DynamicILInfo может быть использован вместе с генераторами неуправляемого кода для выпуска основной части метода для DynamicMethod.
Создайте экземпляр делегата (объявлен на этапе 1), который представляет динамический метод посредством вызова метода CreateDelegate. Создание делегата завершает этот метод, любые дальнейшие попытки изменить этот метод, например добавить MSIL, будут игнорироваться. В следующем коде создается и вызывается делегат с помощью универсального делегата.
Определение и выполнение динамического метода, привязанного к объекту
Объявите тип делегата для выполнения метода. Рассмотрите возможность использования универсального делегата для уменьшения числа типов делегата, которые необходимо будет объявлять. В следующем примере кода объявляется делегат универсального типа, который может быть использован для выполнения любого метода с одним параметром и возвращаемым значением или метода с двумя параметрами и возвращаемым значением, если делегат привязан к объекту.
Выпустите основную часть метода. В этом примере объект ILGenerator используется для выпуска MSIL. В качестве альтернативы объект DynamicILInfo может быть использован вместе с генераторами неуправляемого кода для выпуска основной части метода для DynamicMethod.
Создайте экземпляр делегата (объявленного на этапе 1), который представляет динамический метод посредством вызова перегрузки метода CreateDelegate(Type, Object). Создание делегата завершает этот метод, любые дальнейшие попытки изменить этот метод, например добавить MSIL, будут игнорироваться.
Можно вызвать метод CreateDelegate несколько раз для создания делегатов, привязанных к другим экземплярам целевого типа.
Пример
В следующем примере кода показано выполнение простого динамического метода и динамического метода, привязанного к экземпляру класса.
Простой динамический метод принимает один аргумент, 32-разрядное целое число, и возвращает 64-разрядное значение квадрата этого целого числа. Для вызова этого метода используется универсальный делегат.
В этом примере кода определяются делегаты, которые могут быть использованы для выполнения методов.
Всё, что вы хотели знать о динамическом программировании, но боялись спросить
Я был крайне удивлён, найдя мало статей про динамическое программирование (далее просто динамика) на хабре. Мне всегда казалось, что эта парадигма довольно сильно распространена, в том числе и за пределами олимпиад по программированию. Поэтому я постараюсь закрыть этот пробел своей статьёй.
Основы
Пожалуй, лучшее описание динамики в одно предложение, которое я когда либо слышал:
Динамическое программирование — это когда у нас есть задача, которую непонятно как решать, и мы разбиваем ее на меньшие задачи, которые тоже непонятно как решать. (с) А. Кумок.
Чтобы успешно решить задачу динамикой нужно:
1) Состояние динамики: параметр(ы), однозначно задающие подзадачу.
2) Значения начальных состояний.
3) Переходы между состояниями: формула пересчёта.
4) Порядок пересчёта.
5) Положение ответа на задачу: иногда это сумма или, например, максимум из значений нескольких состояний.
Порядок пересчёта
Существует три порядка пересчёта:
1) Прямой порядок:
Состояния последовательно пересчитывается исходя из уже посчитанных.
2) Обратный порядок:
Обновляются все состояния, зависящие от текущего состояния.
3) Ленивая динамика:
Рекурсивная мемоизированная функция пересчёта динамики. Это что-то вроде поиска в глубину по ацикличному графу состояний, где рёбра — это зависимости между ними.
Элементарный пример: числа Фибоначчи. Состояние — номер числа.
Все три варианта имеют права на жизнь. Каждый из них имеет свою область применения, хотя часто пересекающуюся с другими.
Многомерная динамика
Пример одномерной динамики приведён выше, в «порядке пересчёта», так что я сразу начну с многомерной. Она отличается от одномерной, как вы уже наверно догадались, количеством измерений, то есть количеством параметров в состоянии. Классификация по этому признаку обычно строится по схеме «один-два-много» и не особо принципиальна, на самом деле.
Многомерная динамика не сильно отличается от одномерной, в чём вы можете убедиться взглянув на пару примеров:
Пример №1: Количество СМСок
Раньше, когда у телефонов были кнопки, их клавиатуры выглядели примерно так:
Требуется подсчитать, сколько различных текстовых сообщений множно написать используя не более k нажатий на такой клавиатуре.
Прямой пересчёт:
Обратный пересчёт:
При использовании обратного пересчёта всё проще: мы всегда обращаемся вперёд, так что в отрицательные элементы мы не уйдём.
5) Ответ — это сумма всех состояний.
Пример №2: Конь
4) А теперь самое интересное в этой задаче: порядок. Здесь нельзя просто взять и пройтись по строкам или по столбцам. Потому что иначе мы будем обращаться к ещё не пересчитанным состояниям при прямом порядке, и будем брать ещё недоделанные состояния при обратном подходе.
Есть два пути:
1) Придумать хороший обход.
2) Запустить ленивую динамику, пусть сама разберётся.
Если лень думать — запускаем ленивую динамику, она отлично справится с задачей.
Если не лень, то можно придумать обход наподобие такого:
Этот порядок гарантирует обработанность всех требуемых на каждом шаге клеток при прямом обходе, и обработанность текущего состояния при обратном.
Динамика и матрица переходов
Если никогда не умножали матрицы, но хотите понять этот заголовок, то стоит прочитать хотя бы вики.
А теперь, зачем всё это надо. Умножение матриц обладает свойством ассоциативности, то есть (но при этом не обладает коммутативностью, что по-моему удивительно). Это свойство даёт нам право сделать так:
.
А теперь пример посерьёзнее:
Пример №3: Пилообразная последовательность
Для начала решение без матрицы перехода:
Динамика по подотрезкам
Это класс динамики, в котором состояние — это границы подотрезка какого-нибудь массива. Суть в том, чтобы подсчитать ответы для подзадач, основывающихся на всех возможных подотрезках нашего массива. Обычно перебираются они в порядке увеличения длины, и пересчёт основывается, соответственно на более коротких отрезках.
Пример №4: Запаковка строки
Вот Развернутое условие. Я вкратце его перескажу:
Необходимо по строке s узнать длину самой короткой сжатой строки, разжимающийся в неё.
Решается эта задача, как вы уже наверняка догадались, динамикой по подотрезкам.
1) Состояние динамики: d[l][r] — сжатая строка минимальной длины, разжимающаяся в строку s[l:r]
2) Начальные состояния: все подстроки длины один можно сжать только в них самих.
3) Пересчёт динамики:
У лучшего ответа есть какая-то последняя операция сжатия: либо это просто строка из заглавных букв, или это конкатенация двух строк, или само сжатие. Так давайте переберём все варианты и выберем лучший.
Пример №5: Дубы
Динамика по поддеревьям
Параметром состояния динамики по поддеревьям обычно бывает вершина, обозначающая поддерево, в котором эта вершина — корень. Для получения значения текущего состояния обычно нужно знать результаты всех своих детей. Чаще всего реализуют лениво — просто пишут поиск в глубину из корня дерева.
Пример №6: Логическое дерево
Требуется найти минимальное количество изменений логических операций во внутренних вершинах, такое, чтобы изменилось значение в корне или сообщить, что это невозможно.
Динамика по подмножествам
В динамике по подмножествам обычно в состояние входит маска заданного множества. Перебираются чаще всего в порядке увеличения количества единиц в этой маске и пересчитываются, соответственно, из состояний, меньших по включению. Обычно используется ленивая динамика, чтобы специально не думать о порядке обхода, который иногда бывает не совсем тривиальным.
Пример №7: Гамильтонов цикл минимального веса, или задача коммивояжера
Динамика по профилю
Классическими задачами, решающимися динамикой по профилю, являются задачи на замощение поля какими-нибудь фигурами. Причём спрашиваться могут разные вещи, например, количество способов замощения или замощение минимальным количеством фигур.
Профиль — это k (зачастую один) столбцов, являющиеся границей между уже замощённой частью и ещё не замощённой. Эта граница заполнена только частично. Очень часто является частью состояния динамики.
Почти всегда состояние — это профиль и то, где этот профиль. А переход увеличивает это местоположение на один. Узнать, можно ли перейти из одного профиля в другой можно за линейное от размера профиля время. Это можно проверять каждый раз во время пересчёта, но можно и предподсчитать. Предподсчитывать будем двумерный массив can[mask][next_mask] — можно ли от одной маски перейти к другой, положив несколько фигурок, увеличив положение профиля на один. Если предподсчитывать, то времени на выполнение потребуется меньше, а памяти — больше.
Пример №8: Замощение доминошками
Здесь профиль — это один столбец. Хранить его удобно в виде двоичной маски: 0 — не замощенная клетка столбца, 1 — замощенная. То есть всего профилей .
0) Предподсчёт (опционально): перебрать все пары профилей и проверить, что из одного можно перейти в другой. В этой задаче это проверяется так:
Примеры переходов (из верхнего профиля можно перейти в нижние и только в них):
Полученная асимптотика — .
Динамика по изломанному профилю
Это очень сильная оптимизация динамики по профилю. Здесь профиль — это не только маска, но ещё и место излома. Выглядит это так:
Теперь, после добавления излома в профиль, можно переходить к следующему состоянию, добавляя всего одну фигурку, накрывающую левую клетку излома. То есть увеличением числа состояний в N раз (надо помнить, где место излома) мы сократили число переходов из одного состояния в другое с до
. Асимптотика улучшилась с до
.
Переходы в динамике по изломанному профилю на примере задачи про замощение доминошками (пример №8):
Восстановление ответа
Иногда бывает, что просто знать какую-то характеристику лучшего ответа недостаточно. Например, в задаче «Запаковка строки» (пример №4) мы в итоге получаем только длину самой короткой сжатой строки, но, скорее всего, нам нужна не её длина, а сама строка. В таком случае надо восстановить ответ.
В каждой задаче свой способ восстановления ответа, но самые распространенные:
Небольшие оптимизации
Память
Зачастую в динамике можно встретить задачу, в которой состояние требует быть посчитанными не очень большое количество других состояний. Например, при подсчёте чисел Фибоначчи мы используем только два последних, а к предыдущим уже никогда не обратимся. Значит, можно про них забыть, то есть не хранить в памяти. Иногда это улучшает асимптотическую оценку по памяти. Этим приёмом можно воспользоваться в примерах №1, №2, №3 (в решении без матрицы перехода), №7 и №8. Правда, этим никак не получится воспользоваться, если порядок обхода — ленивая динамика.
Время
Иногда бывает так, что можно улучшить асимптотическое время, используя какую-нибудь структуру данных. К примеру, в алгоритме Дейкстры можно воспользоваться очередью с приоритетами для изменения асимптотического времени.
Замена состояния
В решениях динамикой обязательно фигурирует состояние — параметры, однозначно задающие подзадачу, но это состояние не обязательно одно единственное. Иногда можно придумать другие параметры и получить с этого выгоду в виде снижения асимптотического времени или памяти.
Пример №9: Разложение числа
Решение №1:
Решение №2:
Строки здесь обозначают слагаемые.
Первое решение последовательно добавляет по одной строчке внизу таблицы, а второе — по одному столбцу слева таблицы. Вариантов размера следующей строчки много — главное, чтобы она была больше предыдущей, а столбцов — только два: такой же как предыдущий и на единичку больше.
Заключение
Основным источником была голова, а туда информация попала с лекций в Летней Компьютерной Школе (для школьников), а также кружка Андрея Станкевича и спецкурса Михаила Дворкина (darnley).
Спасибо за внимание, надеюсь эта статья кому-нибудь пригодится! Хотя мне уже пригодилась — оказывается, написание статьи это хороший способ всё вспомнить.
Что такое динамический метод
Динамические методы о снованы на дисконтированных оценках, т.е. учитываю т фактор времени.
Чистый дисконтированный доход проекта определяется как разница между суммой настоящих стоимостей всех денежных потоков доходов и суммой настоящих стоимостей всех денежных потоков затрат, т.е. как чистый денежный поток от проекта, приведенный к настоящей стоимости. Коэффициент дисконтирования при этом принимается равным средней стоимости капитала. Чистый дисконтированный доход показывает, превышает ли текущая стоимость ожидаемых доходов/расходов по проекту (дисконтированный доход) инвестиционные затраты в начальный момент времени.
Обозначим элементы денежного потока ,
, …,
в соответствии с моментами времени, а инвестиционные затраты нулевого периода
, r ставка дисконтирования, n число периодов для реализации проекта, t текущий период. Получим формулу для расчета:
. (1.8)
Из соотношения (1.2) следует:
. (1.9)
Также можно заметить:
, (1.10)
где k величина, вычисляемая по формуле:
, (1.11)
Проект одобряется, если чистая настоящая стоимость проекта больше нуля. Использование данного метода осложняется трудностью прогнозирования ставки дисконтирования и/или ставки банковского процента.
Индекс рентабельности инвестицийPI ( Profitability Index ).
Показывает, сколько единиц современной величины денежного потока приходится на единицу предполагаемых первоначальных затрат. Этот метод является, по сути, следствием метода чистой современной стоимости.
Расчет индекса рентабельности инвестиционного проекта осуществляют, относя дисконтированный (современный) доход по нему к начальным затратам
. (1.12)
Внутренняя норма доходности (рентабельности)IRR ( Internal Rate of Return ).
Это такое значение нормы математического дисконтирования, при котором текущая стоимость денежного потока абсолютно равна инвестициям. Все поступления и затраты по проекту приводятся к настоящей стоимости по ставке дисконтирования. Она получена не на основе задаваемой извне средней стоимости капитала, а на основе внутренней нормы прибыли самого проекта, которая определяется как ставка доходности, при которой настоящая стоимость поступлений равна настоящей стоимости затрат, т.е. чистая настоящая стоимость проекта равна нулю. Внутренняя норма доходности является корнем IRR неявного уравнения, в левой части которого стоит многочлен (полином) степени n :
. (1.13)
Справедливо следующее утверждение: если
, …,
≥ 0, то существует единственное решение (1+IRR) > 0, то есть IRR > –1.
IRR > 0 при условии > 0.
Полученная таким образом чистая приведенная стоимость проекта сопоставляется с чистой настоящей стоимостью затрат. Одобряются проекты с внутренней нормой прибыли, превышающей среднюю стоимость капитала (принимаемую за минимально допустимый уровень доходности).
Данный метод предполагает сложные вычисления и не всегда выделяет самый прибыльный проект, предполагает малореалистичную ситуацию реинвестирования всех промежуточных денежных поступлений от проекта по ставке внутренней доходности. Однако он учитывает изменения стоимости денег во времени.
Модифицированная внутренняя норма доходности (рентабельности)MIRR ( Modified Internal Rate of Return ).
Представляет собой более совершенную модификацию метода внутренней ставки рентабельности, расширяющую возможности последнего. MIRR – это ставка в коэффициенте дисконтирования, уравновешивающая притоки и оттоки средств по проекту. Все денежные потоки доходов приводятся к будущей (конечной) стоимости по средневзвешенной цене капитала, складываются, сумма приводится к настоящей стоимости по ставке внутренней рентабельности; из настоящей стоимости доходов вычитается настоящая стоимость денежных затрат и исчисляется чистая настоящая стоимости проекта, которая сопоставляется с настоящей стоимостью затрат. Метод дает более правильную оценку ставки реинвестирования и снимает проблему множественности ставки рентабельности.
Дисконтированный срок окупаемости инвестицийDPP ( Discounted Payback Period ).
Определяется срок, через который дисконтированные денежные потоки доходов сравняются с дисконтированными денежными потоками затрат. При этом используется концепция денежных потоков, учитывается возможность реинвестирования доходов и временная стоимость денег. Модификация данного метода проста в понимании и применении и позволяет судить о ликвидности и рискованности проекта, поскольку длительная окупаемость означает длительную иммобилизацию средств (пониженную ликвидность проекта) и повышенную рискованность проекта. Однако модификация игнорирует денежные поступления после истечения срока окупаемости проекта. Метод успешно применяется для быстрой оценки проектов, а также в условиях значительной инфляции, политической нестабильности или при дефиците ликвидных средств т.е. в обстоятельствах, ориентирующих предприятие на получение максимальных доходов в кратчайшие сроки.
Динамические методы
Динамические методы оценки эффективности применяют тогда, когда объем продаж, выручка, себестоимость и прочие составляющие притоков и оттоков средств изменяются из периода в период – как, например, при создании предприятия, когда диапазон планирования невозможно ограничить одним, отдельно взятым отрезком времени. Динамические методы основаны на теории денежных потоков и учитывают фактор времени. К ним относятся:
· метод дисконтированной стоимости;
· метод наращенной стоимости;
Наиболее распространенным динамическим методом оценки эффективности является метод дисконтированной (приведенной) стоимости, а критериями служат следующие показатели эффективности:
· чистый денежный приток;
· чистая дисконтированная стоимость (или текущая приведенная стоимость, чистый дисконтированный доход);
· период возврата капитала или дисконтированный срок окупаемости.
Например, необходимо оценить экономическую эффективность инвестиций в создание коммерческого предприятия. Диапазон планирования восемь кварталов. Для создания предприятия планируется внести собственный капитал – 5180 ден.ед., привлечь заемные средства и использовать лизинг.
Для оценки эффективности инвестиций:
1) составляется таблица денежных потоков в разрезе операционной, инвестиционной и финансовой деятельности, табл.1;
2) поступления от продаж и расходы запланировать исходя из анализа рынка и оценки производственных возможностей;
3) делается расчет дисконтированных финансовых результатов,табл. 2;
4) строится график определения внутренней рентабельности проекта; рис.1.
5) рассчитываются показатели эффективности инвестиций, табл.3.
Денежные потоки для оценки эффективности собственника, тыс.руб.
Вывод: по данным таблицы можно сделать вывод о том, что вложение собственного капитала в данное предприятие эффективно по сравнению с альтернативной доходностью финансовых инструментов, не превышающей 6,5 %. С учетом этой ставки дисконтирования инвестиции окупятся за 8 кварталов.
| ||||||
| | | | | ||
5% | 6% | 7% | 8% | 9% | 10% |
Рис. 1. График определения внутренней рентабельности проекта
Дисконтирование финансовых результатов
Периоды планирования = степень дисконтирования t | Итого | ||||||||
Свободный остаток денежных средств на конец периода | -5180 | 515,9 | 48,1 | 293,9 | 1137,7 | 1381,7 | 1354,7 | 2413,7 | 1965,7 |
Дисконтированный чистый денежный поток (NCFt) при: | NCFt * (1 + i) | ||||||||
t = 0,10 | -4709,1 | 426,4 | 36,1 | 200,7 | 706,4 | 779,9 | 695,2 | 1126,0 | -738,3 |
t = 0,05 | -4933,3 | 467,9 | 41,6 | 241,8 | 891,4 | 1031,0 | 962,8 | 1633,7 | 336,9 |
t = 0,06 | -4886,8 | 459,1 | 40,4 | 232,8 | 850,2 | 97,0 | 901,0 | 1514,4 | 85,1 |
t = 0,07 | -4841,1 | 450,6 | 39,3 | 224,2 | 811,2 | 920,7 | 843,6 | 1404,8 | -146,8 |
t = 0,08 | -4796,3 | 442,3 | 38,2 | 216,0 | 774,3 | 870,7 | 790,5 | 1304,0 | -360,3 |
t = 0,09 | -4752,3 | 434,2 | 37,1 | 208,2 | 739,4 | 823,9 | 741,1 | 1211,4 | -557,0 |
Показатели эффективности инвестиций
Для собственных средств | ||||
1. Ставка дисконтирования i, % | ||||
2. Чистая дисконтированная стоимость, тыс.руб. | NPV | 1965,7 | 336,9 | -738,3 |
3. Инвестиции, тыс.руб. | CK | 4933,3 | 4709,1 | |
4. Внутренняя норма доходности, приближенно % в квартал/год | 6,5/30 | |||
5.Индекс доходности | PI | 1,38 | 1,07 | 0,84 |
6. Срок окупаемости | PB | 8 кв. | 8 кв. | Не опред. |
7. Горизонт планирования | 8 кварталов |
Вопросы для самоконтроля
1. Дайте характеристику статическим методам экономической оценки инвестиций.
2. Дайте характеристику динамическим методам экономической оценки инвестиций.
Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет