Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Иллюстрация

Реализация нерекурсивного алгоритма

program pohod;const nnn = 100; {максимально возможное количество различных весов}var f: text; d,razn,k,i,j,n: integer; sum: longint; ves,kol: array[1..nnn] of word; take, dif: array[0..nnn] of word; procedure vyvod(a: integer);begin writeln(a); halt; {принудительное завершение работы программы}end; begin{---- Ввод данных и их сортировка ---}...{---- Основная часть программы -----} d:= sum mod 2; {показатель четности общего веса} sum:=(sum div 2)+ d; {"большая половина" общего веса} dif[0]:= sum; razn:= sum; for i:= 1 to k do begin take[i]:= min(dif[i-1] div ves[i],kol[i]); dif[i]:= dif[i-1]- take[i]*ves[i]; if dif[i]< razn then razn:= dif[i]; if razn <= d then vyvod(d); {проверка того, что уже на первом шаге найдено решение} end; {---- Заполнение массива --------} i:= k; while i>0 do begin if take[i]= 0 then i:= i-1 {переход к следующей компоненте} else begin dec(take[i]); уменьшение текущей компоненты на 1} inc(dif[i],ves[i]); {увеличение остатка на соотв. величину} for j:= i+1 to k do {перезаполнение хвоста} begin take[j]:= min(dif[j-1] div ves[j],kol[j]); dif[j]:= dif[j-1]- take[j]*ves[j]; if dif[j]< razn then razn:= dif[j]; if razn <= d then vyvod(d); {проверка результата} end; i:= k; end; end; vyvod(2*razn-d);end.

Наиболее понятным образом принцип работы нашей программы можно продемонстрировать на примере.

Вес        
Количество        

Пусть имеется семь предметов (n = 7) с весами 9, 5, 25, 11, 9, 5, и 11 единиц (килограмм, фунтов, бушелей...). Тогда всего есть четыре разных вида предметов (k = 4).

Общая сумма весов равна 75; следовательно, "большая половина" sum = 38. Теперь нужно найти такой набор предметов, чей суммарный вес будет наиболее близким к этой "золотой середине". Кроме того, не стоит забывать и о сделанном ранее замечании: как только найдется набор, вес которого отличается от "золотого" лишь на единицу, поиск можно закончить.

Начнем теперь заполнять массивы take и dif (массив dif хранит остатки, в пределах которых можно проводить дальнейшие вычисления).

На начальном ("нулевом") шаге мы заполним массив take так, чтобы в создаваемый набор попали по возможности самые тяжелые предметы (см. раздел реализации "Основная часть программы"). Таким образом, получим следующие состояния массивов:

ves -        
take          
dif          

После этого шага переменная razn, которая хранит отклонение текущего набора весов от оптимального, будет содержать значение 2. Попытаемся уменьшить это значение (переход к разделу реализации "Заполнение массива").

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

Таким образом, наши массивы последовательно примут следующие значения (некоторые непринципиальные шаги опущены):

ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          
ves -        
take          
dif          

Итак, мы убедились в том, что найденное в самом начале значение переменной razn и было минимальным (найденные группы весов соответственно 25 + 11 = 36 и 11 + 9 + 9 + 5 + 5 = 39). Необходимо отметить, что из приведенных выше таблиц видно (см. шаг 5), что существует еще один способ разделить приведенный набор весов таким же оптимальным образом: (11 + 11 + 9 + 5 = 36 и 25 + 9 + 5 = 39). Найденная разница 39 - 36 = 3 и будет окончательным результатом, который программа сообщит пользователю.

<== предыдущая лекция | следующая лекция ==>
Нерекурсивный алгоритм | Алгоритм Быстр
Поделиться с друзьями:


Дата добавления: 2014-01-03; Просмотров: 223; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.009 сек.