Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль / okulov / okulov / chapter2.DOC
Скачиваний:
104
Добавлен:
10.12.2013
Размер:
7.1 Mб
Скачать

2.2.5. Алгоритм Нудельмана-Вунша

Пример из молекулярной биологии. Молекулы ДНК, содержащие генетическую информацию - это длинные слова из четырех букв (А, Г, Ц, Т). В процессе эволюции, в результате мутаций, последовательности меняются, одна буква может замениться на другую, выпасть, а может добавиться новая. Насколько похожи два фрагмента, каким наименьшим числом превращений можно один из них получить из другого? Формулировка задачи. Даны два слова (длины M и N), состоящие из букв А, Г, Ц, Т. Найти подпоследовательность наибольшей длины, входящую в то и другое слово.

Пример. Слова ГЦАТАГГТЦ и АГЦААТГГТ. Схема решения иллюстрируется следующим рисунком.

На рисунке закрашены клетки, в строке и в столбце которых находятся одинаковые буквы. Принцип заполнения таблицы W следующий: элемент W[i,j] равен наибольшему из чисел W[i-1,j], W[i,j-1], а если клетка <i,j> закрашена, то и W[i-1,j-1]+1. Формирование первой строки и первого столбца выполняется до заполнения таблицы и осуществляется так: единицей отмечается первое совпадение, затем эта единица автоматически заносится во все оставшиеся клетки. Например, W[3,1] - первое совпадение в столбце, затем эта единица идет по первому столбцу. Подпоследовательность формируется при обратном просмотре заполненной таблицы от клетки, помеченной максимальным значением. Путь - это клетки с метками, отличающимися на единицу, буквы из закрашенных клеток выписываются. Последовательность этих букв - ответ задачи. Для нашего примера две подпоследовательности: ГЦААГГТ и ГЦАТГГТ.

Фрагмент основной логики.

...

for i:=1 to Length(S1) do

for j:=1 to Length(S2) do begin

A[i,j]:=Max(A[i-1,j],A[i,j-1]);

if S1[i]=S2[j] then A[i,j]:=Max(A[i,j],A[i-1,j-1]+1);

end;

Writeln(‘Ответ:’,A[Length(S1),Length(S2)]);

....

2.2.6. Разбиение выпуклого n-угольника

Дан выпуклый N-угольник, заданный координатами своих вершин в порядке обхода. Он разрезается N-2 диагоналями на треугольники. Стоимость разрезания определяется суммой длин всех использованных диагоналей. Найти разрез минимальной стоимости.

Идея решения разбирается с использованием следующего рисунка.

Обозначим через S[k,l] стоимость разрезания многоугольника A[k,l] диагоналями на треугольники. При l=k+1 или k+2 S[k,l]=0, следовательно, l>k+2. Вершина с номером i, i изменяется от k+1 до l-1, определяет какое-то разрезание многоугольника A[k,l]. Cтоимость разрезания определим как:

S[k,l]=min{длина диагонали <k,i>+длина диагонали <i,l>+S[k,i]+S[i,l]}. При этом следует учитывать, что при i=k+1 диагональ <k,i> является стороной многоугольника и ее длина считается равной нулю.

Пример(N=6).

2.2.7. Задача о рюкзаке (динамическая схема)

Рассмотрим задачу из пункта 1.1.6. Напомним ее формулировку. В рюкзак загружаются предметыnразличных типов (количество предметов каждого типа не ограничено). Максимальный вес рюкзака не превышаетW. Каждый предмет типаiимеет весwi и стоимостьvi (i=1,2, ..., n).Требуется определить максимальную стоимость груза, вес которого не превышаетW.Обозначим количество предметов типаiчерезki,тогда требуется максимизироватьv1*k1+v2*k2+...+vn*kn при ограниченияхw1*k1+w2*k2+...+wn*kn£W, где ki - целые(0£ki£[W/wi]), квадратные скобки означают целую часть числа.

Пусть вес рюкзака должен быть равен W.Формализуем задачу следующим образом.

  • Шаг i ставится в соответствие типу предметаi=1,2,...,n.

  • Состояние yi на шагеiвыражает суммарный вес предметов, решение о загрузке которых принято на шагах 0,1,...,i. При этомyn=W, yi=0,1,...,Wприi=1,2,...,n-1.

  • Варианты решения ki на шагеi описываются количеством предметов типаi, 0£ki£ëW/wiû.

    Рассмотрим пример.W=6, и дано четыре предмета

i

wi

vi

1

2

50

2

3

90

3

1

30

4

4

140

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

Текст решения.

Const MaxN=???;

MaxK=???;

Type Thing=Record W,V:Word; end;

Var A:array[1..MaxN,0..MaxK] of word;

P:array[1..MaxN] of Thing;

Old,NewA:array[0..MaxK] of longint;

N,W:integer;

...

procedure Solve;

var k,i,j:integer;

begin

fillchar(Old,sizeof(Old),0);

for k:=1 to N do begin{цикл по шагам}

fillchar(NewA,sizeof(NewA),0);

for i:=0 to W do{цикл по состояниям шага}

for j:=0 to i div P[k].W do{цикл по вариантам решения - количеству предметов каждого вида}

if j*P[k].V+Old[i-j*P[k].W]>=NewA[i] then begin

NewA[i]:=j*P[k].V+Old[i-j*P[k].W];

A[k,i]:=j;{здесь j количество предметов?}

end;

Old:=NewA;

end;

end;

Вывод наилучшего решения.

procedure OutWay(k,l:integer);

begin

if k=0 then exit

else begin

OutWay(k-1,l-A[k,l]*P[k].V);{а здесь вес}

Write(A[k,l],’ ‘);

end;

end;

Первый вызов -OutWay(N,W).Эту схему реализации принято называть «прямой прогонкой». Ее можно изменить. Пусть пункт два формализации задачи звучит следующим образом. Состояниеyi на шагеi выражает суммарный вес предметов, решение о загрузке которых принято на шагахi, i+1, ..., N при этомy1=W yi=0,1,...,W приi=2,3, ...,N. В этой формулировке схему реализации называют «обратной прогонкой».

Соседние файлы в папке okulov