Читаем Грокаем алгоритмы полностью

        if cost < lowest_cost and node not in processed:   Если это узел с наименьшей стоимостью из уже виденных и он еще не был обработан…

            lowest_cost = cost  …он назначается новым узлом с наименьшей стоимостью

            lowest_cost_node = node

    return lowest_cost_node


Упражнения

7.1 Каков вес кратчайшего пути от начала до конца в каждом из следующих графов?


Шпаргалка

• Поиск в ширину вычисляет кратчайший путь в невзвешенном графе.

• Алгоритм Дейкстры вычисляет кратчайший путь во взвешенном графе.

• Алгоритм Дейкстры работает только в том случае, если все веса положительны.

• При наличии отрицательных весов используйте алгоритм Беллмана—Форда.

8. Жадные алгоритмы

В этой главе

• Вы узнаете, как браться за невозможные задачи, не имеющие быстрого алгоритмического решения (NP-пол­ные задачи).

• Вы научитесь узнавать такие задачи и не терять время на поиски быстрого алгоритма (которого все равно нет).

• Вы познакомитесь с приближенными алгоритмами, которые могут использоваться для быстрого нахождения приближенного решения NP-полных задач.

• Вы узнаете о жадной стратегии — очень простой стратегии решения задач

Задача составления расписания

Допустим, имеется учебный класс, в котором нужно провести как можно больше уроков. Вы получаете список уроков.

Провести в классе все уроки не получится, потому что некоторые из них перекрываются по времени.

Требуется провести в классе как можно больше уроков. Как отобрать уроки, чтобы полученный набор оказался самым большим из возможных?

Вроде бы сложная задача, верно? На самом деле алгоритм оказывается на удивление простым. Вот как он работает:

1. Выбрать урок, завершающийся раньше всех. Это первый урок, который будет проведен в классе.

2. Затем выбирается урок, начинающийся после завершения первого урока. И снова следует выбрать урок, который завершается раньше всех остальных. Он становится вторым уроком в расписании.

Продолжайте действовать по тому же принципу — и вы получите ответ! Давайте попробуем. Рисование заканчивается раньше всех уроков (в 10:00), поэтому мы выбираем именно его.

Теперь нужно найти следующий урок, который начинается после 10:00 и завершается раньше остальных.

Английский язык отпадает — он перекрывается с рисованием, но математика подходит. Наконец, информатика перекрывается с математикой, но музыка подходит.

Итак, эти три урока должны проводиться в классе.

Я очень часто слышу, что этот алгоритм подозрительно прост. Он слишком очевиден, а значит, должен быть неправильным. Но в этом и заключается красота жадных алгоритмов: они просты! Жадный алгоритм прост: на каждом шаге он выбирает оптимальный вариант. В нашем примере при выборе урока выбирается тот урок, который завершается раньше других. В технической терминологии: на каждом шаге выбирается локально-оптимальное решение, а в итоге вы получаете глобально-оптимальное решение. Хотите верьте, хотите нет, но этот простой алгоритм успешно находит оптимальное решение задачи составления расписания!

Конечно, жадные алгоритмы работают не всегда. Но они так просто реализуются! Рассмотрим другой пример.


Задача о рюкзаке

Представьте, что вы жадный воришка. Вы забрались в магазин с рюкзаком, и перед вами множество товаров, которые вы можете украсть. Однако емкость рюкзака не бесконечна: он выдержит не более 35 фунтов.

Требуется подобрать набор товаров максимальной стоимости, которые можно сложить в рюкзак. Какой алгоритм вы будете использовать?

И снова жадная стратегия выглядит очень просто:

1. Выбрать самый дорогой предмет, который поместится в рюкзаке.

2. Выбрать следующий по стоимости предмет, который поместится в рюкзаке… И так далее.

Вот только на этот раз она не работает! Предположим, есть три предмета.

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

Вы набрали товаров на $3000. Погодите-ка! Если бы вместо магнитофона вы выбрали ноутбук и гитару, то стоимость добычи составила бы $3500!

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

Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

Язык программирования C++. Пятое издание
Язык программирования C++. Пятое издание

Лучшее руководство по программированию и справочник по языку, полностью пересмотренное и обновленное под стандарт С++11!Р'С‹ держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под стандарт С++11. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. Р' соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать РёС… наилучшие СЃРїРѕСЃРѕР±С‹ применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.Стенли Р'. Липпман работал старшим консультантом в Jet Propulsion Laboratory, архитектором РіСЂСѓРїРїС‹ Visual С++ корпорации Microsoft, техническим сотрудником Bell Laboratories и главным инженером- программистом по анимации в кинокомпаниях Disney, DreamWorks, Pixar и PDI.Р–РѕР·и Лажойе, работающий ныне в кинокомпании Pixar, был членом канадской РіСЂСѓРїРїС‹ разработчиков компилятора C/C++ корпорации IBM, а также возглавлял рабочую группу базового языка С++ в составе международной организации по стандартизации ANSI/ISO.Барбара Э. Му имеет почти тридцатилетний опыт программирования. На протяжении пятнадцати лет она работала в компании AT&T, сотрудничая с Бьярне Страуструпом, автором языка С++, и несколько лет руководила РіСЂСѓРїРїРѕР№ разработчиков С++.• Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования• Р

Барбара Э. Му , Жози Лажойе , Стенли Б. Липпман

Программирование, программы, базы данных