Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Метод динамического программирования

Читайте также:
  1. A. гностическим методам
  2. Amp;Сравнительная характеристика различных методов оценки стоимости
  3. C) Методы стимулирования поведения деятельности
  4. E) мировоззренческая, гносеологическая, методологическая.
  5. I ОРГАНИЗАЦИОННО-МЕТОДИЧЕСКИЕ УКАЗАНИЯ ПО ВЫПОЛНЕНИЮ КУРСОВОЙ РАБОТЫ
  6. I. Из истории развития методики развития речи
  7. I. ОБЩИЕ МЕТОДИЧЕСКИЕ УКАЗАНИЯ
  8. I. Определение эпидемического процесса и методологическое обоснование разделов учения об эпидемическом процессе.
  9. I. Определение эпидемического процесса и методологическое обоснование разделов учения об эпидемическом процессе.
  10. I. ОРГАНИЗАЦИОННО-МЕТОДИЧЕСКИЙ РАЗДЕЛ

Итак, одна из проблем рекурсивных алгоритмов (и эта проблема возникает весьма часто, не только в рассмотренном примере) -- длительная работа рекурсии за счет повторяющихся вызовов рекурсивной функции для одного и того же набора параметров. Чтобы не тратить машинное время на вычисление значений рекурсивной функции, которые мы уже когда-то вычислили, можно сохранить эти значения в массиве и вместо рекурсивного вызова функции мы будем брать это значение из массива. В задаче вычисления числа сочетаний создадим двумерный массив B и будем в элементе массива B[n][k] хранить величину C nk. В результате получим следующий массив (по строчкам -- значения n, начиная с 0, по столбцам -- значения k, начиная с 0, каждый элемент массива B[n][k] равен сумме двух элементов: стоящего непосредственно над ним B[n-1][k] и стоящего над ним слева B[n-1][k-1]).

             
             
             
             
             
             
             

Полученная числовая таблица, составленная из значений C nk, в которой каждый элемент равен сумме двух элементов, стоящих над ним, называется треугольником Паскаля.

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

int C(int n, int k)

{

int B[n+1][n+1]; // Создаем массив B из n+1 строки

for(int i=0;i<=n;++i) // Заполняем i-ю строку массива

{

B[i][0]=1; // На концах строки стоят единицы

B[i][i]=1;

for(int j=1;j<i;++j)

{ // Заполняем оставшиеся элементы i-й строки

B[i][j]=B[i-1][j-1]+B[i-1][j];

}

}

return B[n][k];

}

Приведенный алгоритм для вычисления C nk требует объем памяти O (n 2) и такая же его временная сложность (для заполнения одного элемента массива требуется O (1) операций, всего же элементов в массиве O (n 2)).

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

Тем не менее, приведенный алгоритм тоже имеет небольшие недостатки. Мы вычисляем значения всех элементов последней строки, хотя нам необходим только один из них -- B[n][k]. Аналогично, в предпоследней строке нас интересуют только два элемента -- B[n-1][k-1] и B[n-1][k], в строке, стоящей над ней -- три элемента, и т. д., в то время, как мы вычисляем все элементы во всех строках. Кроме того, мы не используем почти половину созданного массива B[n+1][n+1], а именно все элементы, стоящие выше главной диагонали. От этих недостатков можно избавиться, более того, можно уменьшить объем используемой памяти до O (n), идея для построения такого алгоритма будет изложена в разделе «Маршруты на плоскости».

Если же в программе часто возникает необходимость вычисления числа сочетаний C nk для каких-то ограниченных значений n, то лучше всего создать глобальный массив для хранения всевозможных значений C nk для нужных нам значений n, заполнить его в начале программы, а затем сразу же брать значение числа сочетаний из этого массива, не вычисляя его каждый раз заново.




Дата добавления: 2014-11-24; просмотров: 122 | Поможем написать вашу работу | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2025 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав