
- •Теоретический раздел лекции Тема 1. Программирование с использованием рекурсии
- •1.1. Cтратегии решения задачи разбиением ее на подзадачи
- •1.2. Программирование рекуррентных соотношений
- •Var z:extended;
- •1.3. Условия окончания рекурсии
- •1.4. О целесообразности использования рекурсии
- •Var I,X,y,z:word;
- •1.5 Правила выбора программной реализации рекуррентных соотношений
- •Тема 2. Задачи перебора вариантов
- •2.1. Модель дерева решений
- •2.2. Задача оптимального выбора (задача о рюкзаке)
- •2.3. Метод полного перебора двоичного дерева
- •Var wt,ct:extended;
- •Var j,k:byte;
- •If k in s then begin
- •Var j:byte;
- •Var j:byte;
- •Var wt1,oct1:byte;
- •2.4. Метод ветвей и границ
- •Var n,I:byte;
- •Var wt1,oct1:Extended;
- •Include(s,I);
- •If I in Sopt then writeln(I,a[I].W,a[I].C);
- •2.5. Эвристические методы
- •Тема 3. Поиск и сортировка массивов записей
- •3.1. Применимость сортировки и поиска
- •3.2. Массив записей и поиск в нем
- •Var m:word;
- •3.3. Сортировки массивов
- •Var c: mas; I,j,k:word;
- •Var m:word;
- •Var I,j:Word;
- •Var I,j,l,r:Word; X:Tk; w:Tzp;
- •Тема 4. Связанные списки с использованием рекурсивных данных
- •4.1. Список, стек, очередь
- •4.2. Списки на основе динамических массивов
- •Inherited create;
- •Var turn:Tlist; с1,c2:Tinf;
- •4.3. Рекурсивные данные и однонаправленные списки
- •Inherited create;
- •Var stec,st1,turn,tr1:Tlist; inf:Tinf;
- •4.4. Начальное формирование, добавление и удаление элементов однонаправленного списка
- •4.5. Разновидности связанных списков
- •Inf:Tinf;
- •Тема 5. Поиск и сортировки на связанных линейных списках
- •5.1. Поиск в однонаправленных списках
- •5.2. Сортировка однонаправленных списков
- •1 3Var Inf:tInf;
- •Тема 6. Использование линейных связанных списков
- •6.1. Вычисления арифметических выражений
- •Var ch,ch1,ch2,chr:char;
- •I:byte;ch,ch1:char;
- •6.2. Сложение больших целых чисел
- •Var u,V,s,t:byte;
- •6.3. Работа с разреженными матрицами
- •Inf:Tinf;
- •Inf:tInf;
- •Var proot,p:Ptree;
- •Var bl:boolean;
- •7.2. Бинарное дерево поиска
- •7.3. Основные операции с бинарным деревом поиска
- •Inf:tInf;
- •Var d1:Tree; c:Tinf; k:Tkey;
- •Var bl:Boolean;
- •Var m:Word;
- •Var p:Ttree; m:Word;
- •Тема 8. Хеширование
- •8.1. Что такое хеширование
- •8.2. Схема хеширования
- •Interface
- •Inf:Tinf;
- •8.4. Другие способы хеширования
- •Практический раздел Указания по выбору варианта
- •Индивидуальные практические работы и контрольные работы
- •Индивидуальная практическая работа №1. Программирование с использованием рекурсии
- •1.1. Понятие рекурсии
- •1.2. Порядок выполнения работы
- •1.2.1. Пример решения задачи
- •Индивидуальная практическая работа №2. Организация однонаправленного списка на основе рекурсивных типов данных в виде стека
- •2.1. Основные понятия и определения
- •Inf:tInf; // информация
- •Контрольная работа №1. Программирование с использованием деревьев на основе рекурсивных типов данных
- •1.1. Понятие древовидной структуры
- •Inf:tInf;
- •1.2. Компонент tTreeView
- •1.3. Бинарное дерево поиска
- •Основные операции с двоичным деревом поиска
- •1.4. Порядок написания программы
- •Inf:tInf;
- •Inherited Free;
- •Var tr:Ttree;
- •1.5. Индивидуальные задания
- •Курсовая работа
- •Литература
2.2. Задача оптимального выбора (задача о рюкзаке)
Много важных прикладных задач (в частности задач искусственного интеллекта) можно свести к следующей:
Имеется
набор из n
элементов a1...an.
Каждый элемент ai
характеризуется определенными свойствами,
например вес wi
и цена ci
(это могут быть размер и время, объем
инвестиций и ожидаемый доход, и т.д.).
Требуется найти оптимальную выборку
kn
из этого набора, т.е. такую для которой,
например, при заданном ограничении на
суммарный вес
достигается максимальная стоимость
.
С такой проблемой сталкивается, например,
путешественник, упаковывающий чемодан,
суммарный вес которого ограниченWmax
кг., а ценность вещей должна быть побольше
или инвестор, которому надо выгодно
вложить Wmax
млн. руб. в какие-то из n
возможных проектов, каждый из которых
имеет свою стоимость и ожидаемый доход.
Дерево решений этой задачи для а1, а2 , а3 , а4 можно представить в виде:
Рис. 2.1. Двоичное дерево решений
Здесь знак + или – над ветвью, идущей от i узла соответствует включению или не включению ai в выборку. В качестве упражнения допишите все варианты этого дерева.
2.3. Метод полного перебора двоичного дерева
При решении этой задачи в соответствии со схемой, приведенной на листинге 2.1 на каждом ходу предлагается два кандидата aij={i,0}.
Для запоминания хода решения здесь более удобно использовать вместо массива S множество S. В этом случае если выбирается первый кандидат в множество включается номер хода i, если выбирается второй кандидат из множества исключается i.
Используя это, получим следующую рекурсивную процедуру реализующую полный перебор всех вариантов двоичного дерева:
Листинг 2.2
Type Telem=Record c,w:Extended end;
Var wt,ct:extended;
S,Sopt:set of byte;
a:array[1..100]of Telem;
n:byte;
Procedure vbrPP1(i:byte);
Var j,k:byte;
begin
for j:=0 to 1 do begin
if j=0 then Include(s,i)
else Exclude(S,i);
if i<n then VbrPP1(i+1)
else begin
wt:=0; ct:=0;
for k:=1 to n do
If k in s then begin
wt:=wt+a[k].w; ct:=ct+a[k].c;end;
if (wt<=Wmax) and (ct>Cmax) then
begin Cmax:=ct;Sopt:=S; end;
end;
end;//j
End;
В этой процедуре вся обработка при нахождении максимального варианта суммирование текущего веса wt и стоимости ct производится после получения листа дерева.
Листинг 2.3
Procedure VbrPP2(i:byte);
Var j:byte;
begin
for j:=0 to 1 do
begin
if j=0 then begin Include(S,i);
wt:=wt+a[i].w; ct:=ct+a[i].c end
else begin Exclude(S,i);
wt:=wt-a[i].w; ct:=ct-a[i].c end;
if i<n then VbrPP2(i+1)
else if (wt<=wmax) and (ct>cmax) then
begin cmax:=ct; Sopt:=S end;
end;//j
end;//VbrPP2
В такой модификации процедуры суммирование вынесено из листа и делается за счет повторения рекурсии.
За счет этого, появляется возможность уменьшить количество вычислений, поставив проверку переполнения рюкзака:
Листинг 2.4
Procedure VbrPP3(i:byte);
Var j:byte;
begin
for j:=0 to 1 do
begin
if j=0 then begin Include(S,i);
wt:=wt+a[i].w; ct:=ct+a[i].c end
else begin Exclude(S,i);
wt:=wt-a[i].w; ct:=ct-a[i].c end;
if (wt<=wmax) then
if i<n then VbrPP2(i+1)
else if (ct>cmax) then
begin cmax:=ct; Sopt:=S end;
end;//j
end;//VbrPP3
В качестве упражнения, оцените на сколько уменьшится при этом количество перебираемых вариантов.
Обращение: wt:=0;ct:=0;cmax:=0; S:=[]; Sopt:=[];
ввод n; wmax; a[i], i=1..n; VbrPP(1);
Печать cmax, Sopt.
Здесь введен массив элементов a[1..n], имеющих тип записи с полями w и c. При генерации текущей и оптимальной выборок используются множества S и Sopt из индексов, входящих в выборку элементов.
Процедуру полного перебора можно немного усовершенствовать, если вместо текущей стоимости, ввести так называемую общую стоимость oct, которая вначале равна полной стоимости всей выборки, а по мере исключения i-того элемента, из нее вычитается его стоимость. Запишем цикл по J явно, и введем два дополнительных формальных параметра, получим:
Листинг 2.5
Procedure vbrPP4(i,wt,oct:byte);