
- •Министерство образования и науки Российской Федерации
- •Цель лекции
- •План лекции
- •1 Происхождение вычислительных машин
- •2 Изучение алгоритмов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Биты и их хранение
- •2 Оперативная память
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Устройства внешней памяти
- •3 Хранение и поиск файлов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Представление числовых значений
- •2 Хранение целых чисел
- •3 Хранение дробей
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Представление текста
- •2 Представление изображений
- •Достоинства пиксельной графики
- •Недостатки пиксельной графики
- •Достоинства векторной графики
- •Недостатки векторной графики
- •3 Представление звука
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Сжатие изображений
- •2 Ошибки передачи данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Архитектура эвм
- •2 Связь процессора с другими устройствами
- •3 Другие архитектуры
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Машинный язык
- •2 Пример машинного языка
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Выполнение программы
- •2 Пример выполнения программы
- •3 Программы и данные
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Логические операции
- •2 Операции сдвига
- •3 Арифметические операции
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эволюция операционных систем
- •2 Архитектура операционных систем
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Понятие процесса
- •2 Управление процессами
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Классификация сетей
- •2 Сетевые протоколы*
- •3 Безопасность сетей
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Понятие алгоритма
- •2 Представление алгоритма
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Теория решения задач
- •2 Общие методы решения задач
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Алгоритм последовательного поиска
- •2 Управление циклами
- •3 Алгоритм сортировки методом вставки
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Алгоритмы поиска и сортировки
- •2 Управление рекурсией
- •3 Разработка рекурсивных процедур
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эффективность алгоритмов
- •2 Верификация программ
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эволюция и классификация языков программирования
- •2 Концепции традиционного программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Процедурные единицы
- •2 Реализация языка программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Объектно-ориентированное программирование
- •2 Декларативное программирование
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Структуры данных
- •Integer Scores (2.9).
- •2 Статические и динамические структуры
- •3 Указатели
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Массивы
- •2 Списки
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Структура и функции стека
- •2 Реализация стека
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Очереди
- •2 Деревья
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Пользовательские типы данных
- •Int Age;
- •2 Классы
- •Int *StackEntries;
- •3 Стандартная библиотека шаблонов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Роль операционной системы
- •2 Последовательные файлы
- •3 Вопросы программирования
- •0000000010000110
- •001100010011001100110100
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Основные положения индексации
- •2 Вопросы программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Основные положения хеширования
- •2 Вопросы программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Общие вопросы
- •2 Система управления базой данных
- •3 Поддержка целостности баз данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Модели баз данных
- •2 Реляционная модель баз данных
- •3 Объектно-ориентированные базы данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Интеллект и машины
- •2 Распознавание образов
- •3 Мышление
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Искусственные нейронные сети
- •2 Генетические алгоритмы
- •Контрольные вопросы
- •Невычислимые функции Цель лекции
- •План лекции
- •1 Основы машины Тьюринга
- •2 Невычислимая функция
- •3 Сложность задач
- •Листинг 1. Процедура MergeLists для объединения двух упорядоченных списков
- •Листинг 2. Алгоритм сортировки слиянием, реализованный в процедуре MergeSort
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Шифрование с открытым ключом
- •2 Модульная арифметика
- •Контрольные вопросы
- •Литература
- •Internet-ресурсы
2 Общие методы решения задач
Мы обсудили решение проблем с философской точки зрения, пока не затрагивая вопрос, как следует действовать при попытке решить некоторую задачу. Безусловно, существует множество подходов к решению задач, каждый из которых приводит к успеху в определенных ситуациях. Ниже мы кратко обсудим некоторые из них. Сейчас же просто отметим, что существует нечто общее, присущее всем этим методам. Это можно охарактеризовать как выбор оптимальной позиции для дальнейших действий. В качестве примера рассмотрим следующую простую задачу.
Перед соревнованиями участники А, В, С и D сделали следующие прогнозы:
Участник А предсказал, что победит участник В.
Участник В предсказал, что участник D будет последним.
Участник С предсказал, что участник А будет третьим.
Участник D предсказал, что сбудется предсказание участника А.
Только один из этих прогнозов оказался верным, и это был прогноз победителя.
В каком порядке участники А, В, С и D закончили соревнования?
Ознакомившись с задачей и проанализировав приведенные в ее условии сведения, нетрудно заметить, что, поскольку прогнозы участников А и D эквивалентны, а верным оказался только один прогноз, прогнозы участников А и D неверны. Следовательно, ни участник А, ни участник D не являются победителями соревнования. Теперь можно считать, что первый шаг сделан. Для получения окончательного решения надо просто продолжить наши рассуждения. Поскольку прогноз участника А оказался неверным, значит, участник В также не стал победителем. Остается единственный возможный вариант, в котором победителем стал участник С. Итак, участник С выиграл соревнования, и его прогноз оказался верным. Отсюда можно сделать вывод, что участник А занял третье место. Это означает, что участники финишировали либо в порядке CBAD, либо в порядке CDAB. Но первый вариант нужно отбросить, так как прогноз участника В не оправдался. Следовательно, участники финишировали в порядке CDAB.
Конечно, сказать, что нужно сделать первый шаг и занять оптимальную позицию, — совсем не то же самое, что сказать, как это сделать. Первоначальный прорыв, а затем осознание того, как закрепить полученный успех, чтобы суметь найти окончательное решение задачи, потребуют значительных усилий от того, кто ее решает. Однако существует несколько общих подходов, предложенных математиком Полиа и другими исследователями, подсказывающими, как можно осуществить этот первоначальный прорыв. Один из подходов состоит в том, чтобы работать с задачей в обратном порядке. Например, если задача заключается в том, чтобы найти способ получения определенного конечного результата из заданного начального, можно начать поиск с конечного результата и попытаться пройти путь к заданному начальному. Этот подход будет полезен, если потребуется найти алгоритм складывания бумажной птички, упомянутый в предыдущем разделе. Логично начать с попытки развернуть сложенную птичку с целью понять, как она была сделана.
Другой общий подход к решению задачи состоит в поиске связанных с ней проблем, которые или легче решаются, или уже были решены раньше. Позже предпринимается попытка применить способ их решения к данной задаче. Этот метод особенно важен в контексте разработки программ. Часто при разработке программы основная трудность заключается в создании общего алгоритма для решения всех разновидностей данной задачи. Другими словами, если нам необходимо разработать программу для упорядочения списка имен в алфавитном порядке, наша задача не сводится к сортировке отдельного списка, а заключается в нахождении алгоритма, пригодного для сортировки любого списка имен. Рассмотрим следующий набор инструкций.
Поменять местами имена David и Alice.Поместить имя Carol между именами Alice и David.Поместить имя Bob между именами Alice и Carol.
Этот набор позволяет правильно выполнить сортировку списка, состоящего из имен David, Alice, Carol и Bob, но он не является тем общим алгоритмом, который мы ищем. Нам же нужен алгоритм, который в состоянии выполнить сортировку, как данного списка, так и любого другого, который может встретиться. Однако найденное решение сортировки конкретного списка не является совершенно бесполезным для разработки общего алгоритма. Мы можем, например, продвинуться в решении, рассматривая такие частные случаи, как попытки найти o6щий принцип, которые, в свою очередь, послужат основой для создания искомого общего алгоритма. В этом случае искомое решение, в конце концов, будет найдено с помощью метода решения набора взаимосвязанных частных задач.
Еще один подход к проблеме "с чего начинать" заключается в применении метода поэтапного уточнения, который предполагает, что задачу не следует пытаться решить сразу же и целиком во всех ее деталях. Согласно этому методу, исследователь должен разбить задачу на ряд подзадач. Идея заключается в том, что при разбиении исходной задачи на подзадачи появляется возможность найти общее решение как последовательность этапов, на каждом из которых решается задача, более простая по сравнению с исходной. Поэтапное уточнение подразумевает также, что каждый из этапов, в свою очередь, можно разбить на меньшие, а те — на еще меньшие, так что, в конце концов, вся задача сводится к набору легко разрешимых подзадач.
Поэтапное уточнение является нисходящим методом, так как его развитие происходит в направлении от общего к частному. В противоположность этому, восходящие методы предусматривают развитие от частного к общему. Хотя в теории эти подходы противоположны, на практике они просто дополняют друг друга. Например, разбиение задачи, предлагаемое нисходящим методом поэтапного уточнения, обычно осуществляется интуитивно с использованием восходящей модели.
Решениям, полученным с помощью метода поэтапного уточнения, свойственна естественная модульная структура. Именно в этом кроется основная причина популярности этого метода при разработке алгоритмов. Если алгоритм имеет естественную модульную структуру, то он легко реализуется в модульном представлении, способствующем созданию удобных в сопровождении программ. Более того, модульная структура, создаваемая в процессе поэтапного уточнения, легко совмещается с концепцией коллективного программирования, в соответствии с которой несколько человек объединяются в команду, имеющую своей задачей разработку определенного программного продукта. После того как исходная задача будет разбита на подзадачи (потенциальные модули), члены команды смогут работать над ними независимо, не мешая друг другу.
Метод поэтапного уточнения пользуется широкой популярностью при разработке программного обеспечения. Однако, несмотря на все его преимущества, этот метод отнюдь не является последним словом науки в отношении создания алгоритмов. В сущности, он представляет собой только средство организации работы, и все его возможности по решению задач являются лишь следствием этой организации. Вполне естественно использовать метод поэтапного уточнения при организации общенациональной политической кампании, написании курсовой работы или заключении торгового соглашения. Аналогичным образом для большинства проектов разработки программного обеспечения из области обработки данных характерна большая роль организационного компонента. Задача этих проектов состоит не столько в создании нового сенсационного алгоритма, сколько в представлении решаемых задач таким образом, чтобы их можно было реализовать в виде согласованно функционирующего пакета программ. Поэтому метод поэтапного уточнения по праву стал основой всей методологии проектирования в области обработки данных.
Однако поэтапное уточнение остается всего лишь одной из многих методологий проектирования, представляющих интерес для специалистов в области компьютерных наук. Поэтому не следует впадать в заблуждение, полагая, что все алгоритмы могут быть созданы с помощью этого метода. Фактически применение при решении задач предвзятых представлений и заранее выбранных схем в некоторых случаях может даже усложнить изначально простое задание. Рассмотрим следующую задачу.
Когда вы садились в лодку, ваша шляпа упала в воду, но вы этого не заметили. Скорость течения реки 2,5 мили в час, и ваша шляпа поплыла вниз по течению. Тем временем вы поплыли в лодке вверх против течения со скоростью 4,75 мили в час (относительно воды). Спустя 10 минут вы заметили пропажу шляпы, развернули лодку и поплыли вниз по реке догонять вашу шляпу. Через какое время вы поймаете свою шляпу?
Большинство студентов, изучающих алгебру в высшей школе, а также любителей карманных калькуляторов начнут решение этой задачи с определения, какое расстояние прошла лодка за 10 минут вверх по течению и какое расстояние за это время проплыла шляпа вниз по течению. Затем они попытаются вычислить, сколько времени понадобится лодке, чтобы пройти вниз по течению до той точки, где находится шляпа. Но ведь пока лодка будет идти к этой точке, шляпа будет уплывать дальше вниз по течению! Таким образом, они, весьма вероятно, попадут в цикл вычислений, где будет находиться шляпа в тот момент, когда лодка достигнет того места, где шляпа была на предыдущем этапе расчета.
На самом же деле задача гораздо проще. Весь фокус состоит в том, чтобы суметь противостоять стремлению писать формулы и делать вычисления. Необходимо просто отложить эти навыки в сторону и взглянуть на задачу в ее истинном свете. Суть всей проблемы в реке. В данном случае тот факт, что вода движется относительно берегов, не имеет никакого значения. Представьте себе ту же задачу на длинной конвейерной ленте. Сначала решим поставленную задачу, когда лента неподвижна. Если вы, стоя на ленте, положите шляпу у своих ног, а затем будете идти вдоль ленты в течение 10 минут, то вернуться к шляпе вы сможете за те же 10 минут. Теперь включим конвейер. Это будет означать, что сначала вы пойдете против движения ленты. Но поскольку вы, как и шляпа, находитесь на ленте, это не изменит ваших взаимоотношений с лентой и шляпой. Вам по-прежнему потребуется 10 минут, чтобы вернуться к оставленной шляпе.
В результате можно прийти к заключению, что создание алгоритмов является сложным искусством, которое необходимо постоянно совершенствовать, а не изучать как предмет, состоящий из хорошо определенных методологий. Учить решать задачи, следуя четко определенным методологиям, — значит "загубить" творческие способности учащихся, которые, напротив, нужно всемерно развивать.