Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
72
Добавлен:
10.02.2016
Размер:
1.79 Mб
Скачать

4.3.4. Динамическое программирование

Рекурсивная техника полезна, если задачу можно разбить на подзадачи за разумное время, а суммарный размер подзадач будет небольшим. Из теоремы 4.1 вытекает, что если сумма размеров подзадач равна an для некоторой постоянной а>0, то рекурсивный алгоритм, вероятно, имеет полиномиальную временную сложность. Но если очевидное разбиение задачи размера n сводит её к n задачам размера n-1, то рекурсивный алгоритм, вероятно, имеет экспоненциальную сложность.

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

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

Рассмотрим эту технику на примере вычисления произведения k матриц М=М1 x М2 x...x Мk , где Mi - матрица с ri-1 строками и ri столбцами. Порядок, в котором эти матрицы перемножаются, может существенно сказаться на общем числе операций, требуемых для вычисления М, независимо от алгоритма, применяемого для умножения матриц.

Пример 4.1. Будем считать, что умножение (р xq)-матрицы на (q x r)-матрицу требует pqr операций, и рассмотрим произведение (в квадратных скобках указаны размерности матриц).

М= М1 x М2 x М3 x М4

[10 x 20] [20 x 50] [50 x 1] [1 x 100]

Если вычислять М в порядке М1x(М2x(М34)), то потребуется 125000 операций, тогда как вычисления в порядке (М1x(М23))xМ4 занимают лишь 2200 операций.

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

4.3.5. Алгоритмы с возвратом

Особенно интересный раздел программирования - это задачи из области “искусственного интеллекта”. Здесь нужно строить алгоритмы, которые находят решение определённой задачи не по фиксированным правилам вычисления, а методом проб и ошибок. Обычно процесс проб и ошибок разделяется на отдельные подзадачи. Часто эти подзадачи наиболее естественно описываются с помощью рекурсии. Процесс проб и ошибок можно рассматривать в общем виде как процесс поиска, который постепенно строит и просматривает (а также обрезает) дерево подзадач. Во многих случаях такие деревья поиска растут очень быстро, обычно экспоненциально, в зависимости от заданного параметра. Соответственно увеличивается стоимость поиска. Часто дерево поиска можно обрезать, используя только эвристические соображения, и тем самым сводить количество вычислений к разумным пределам.

Далее на примере задачи о ходе коня рассматривается общий принцип разбиения таких задач на подзадачи и использование в них рекурсии.

Задача “Обход конем шахматной доски nxn”. Конь помещается на поле с начальными координатами Х0, У0. Нужно покрыть ходами коня всю доску (осуществить обход доски) за n2-1 ход, при том, что каждое поле посещается ровно один раз.

Эта задача покрытия n2 полей сводится к более простой: или выполнить очередной ход, или установить, что никакой ход невозможен.

Характерная черта этого алгоритма состоит в том, что он предпринимает какие-то шаги по направлению к общему решению, эти шаги фиксируются (записываются), но можно возвращаться обратно и стирать записи, если оказывается, что шаг не приводит к решению, а заводит в “тупик”. Такое действие называется возвратом.

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

procedure try (i)

begin k := 0; (*инициировать выборку возможных шагов*)

repeat k := k+1; выбрать k-й возможный путь;

if приемлемо then

begin записать его;

if i < n then (*решение неполно*)

begin try (I+1); (*попробовать очередной шаг*)

if неудачно then стереть запись

end

end

until удачно  (k=m)

end.

4.4. Построение и анализ алгоритма

4.4.1. Как разрабатывать алгоритм?

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

Однако всегда находились математики (и представители других наук), для которых вопрос: «Как сформировалась идея?» и более общий вопрос: «Как вообще формировать идеи решения или изобретения?» был важнее решения конкретной задачи (проблемы). Многие выдающиеся математики пытались сформулировать принципы и методы решения любой задачи. Среди них первым можно отметить знаменитого греческого математика Паппа, который жил предположительно около 300 г. н. э. В седьмом томе своего "Математического сборника" он говорит об отрасли науки, названной им эвристикой, так (в свободном изложении): "То, что называют эвристикой, можно кратко определить как особое собрание принципов, предназначенное для тех, кто после изучения «Начал» Евклида имеет желание научиться решать математические задачи…".

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

Наиболее известные попытки создать стройную систему эвристики принадлежат Р. Декарту (1596 – 1650) и Г. Лейбницу (1646 – 1716) - двум великим математикам и философам. Первый попытался разработать универсальный метод решения задач, однако его «Правила для направления ума» остались неоконченными. Второй намеревался написать «Искусство изобретения», но не осуществил своего намерения; однако многочисленные отрывки, разбросанные в его трудах, показывают, что у него были интересные мысли по этому вопросу. Он неоднократно подчеркивал значение этого вопроса; так, он писал: «Нет ничего важнее, чем умение найти источник изобретения, – на мой взгляд, это еще интереснее, чем само изобретение».

Б. Больцано (1781 – 1848), логик и математик, оставил интересное и подробное изложение эвристики; он предпослал изложению введение, в котором написал: «… я приложу усилия к тому, чтобы ясно изложить правила и способы исследования, которыми руководствуются все способные люди …».

Следующим в этом ряду назовём Д. Пойа, не столько великого математика, сколько очень талантливого Учителя. Он написал книгу «Как решать задачу?» [14], весьма полезную как учителю, так и ученику не только средней, но и студенту высшей школы (в последнем случае рекомендуем также познакомиться со второй его книгой [15]). По её мотивам написаны книги [2] и [16].

Задача построения алгоритма, как и любая задача, может быть решена в соответствии с методикой, разработанной Д. Пойа [14]. Она заключается в разбиении процесса решения на этапы:

  • постановка задачи (понимание постановки задачи);

  • составление плана решения (анализ);

  • реализация плана (синтез);

  • осмысление полученного решения («взгляд назад»)

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

Соседние файлы в папке Основаная часть