7.1. Метод частных целей
Этот метод имеет общую формулировку "Необходимо свести трудную задачу к последовательности более простых задач". С одной стороны, это естественно и разумно, а, с другой стороны, в конкретной задаче часто трудно указать способ ее разбиения на набор более простых задач. Все зависит от опыта и искусства программиста. Несмотря на общность метода и отсутствие рецептов его применения, важно освоить этот метод, поскольку он лежит в основе решения многих задач и по сути является основой алгоритмизации и программирования. Разработка любого алгоритма должна начинаться с ответа на вопрос "Можно ли задачу разбить на последовательность более простых задач?". Рассмотрим метод на задаче сетевого планирования.
Задача. Имеется комплекс взаимосвязанных работ. Для каждой из N работ задана ее трудоемкость в человеко-часах. Необходимо расставить K имеющихся работников так, чтобы длительность выполнения всего комплекса работ была минимальной. При этом запрещено перемещать работников с одной работы на другую в ходе выполнения работ.
Взаимосвязь работ задается сетевым графиком, представляющим собой ориентированный граф без петель и контуров и состоящий из конечного множества вершин и попарно соединяющих их дуг (i, j). Вершины графа – события, а дуги – работы. Работа – трудовой процесс, требующий затрат времени и ресурсов, характеризуется трудоемкостью. Событие – факт окончания всех предшествующих ему работ и возможность начать следующие за ним работы. Работа сетевого графика определяется i-ым событием, предшествующим началу работы, и j-ым событием, указывающим на окончание работы. Работа обозначается (i, j), продолжительность ее выполнения - tij, а трудоемкость - rij. К числу особых событий относятся исходное 0-ое событие, соответствующее началу выполнения работ, и M-ое завершающее событие, отражающее завершение всех работ. Остальные события нумеруются исходя из требования, чтобы не существовало некоторой работы (i, j), для которой i > j. Путь сетевого графика – любая непрерывная последовательность событий и работ по направлению стрелок. Множество путей, соединяющих два события i и k, обозначим, как L(i, k). Наибольший интерес представляют полные пути, т.е. пути из 0 в M – (0, M). Полный путь с наибольшей продолжительностью Iкр называется критическим.
Iкр = I (0, M), max T(I),
г де T(I) –продолжительность I -го пути. Рассмотрим конкретный комплекс работ, заданных сетевым графиком, в котором N = 7, K = 10, а множество работ задано графом (рис. справа) A = {(0, 1), (0, 2), (1, 3), (1, 4), (2, 4), (3, 5), (4, 5)}. Числа над дугами графа - трудоемкости работ. Множество полных путей - L(0, 5) = {I1, I2, I3}, где I1 = {(0, 1), (1, 3), (3, 5)}, I2 = {(0, 1), (1, 4), (4, 5)}, I3 = {(0,2), (2,4), (4,5)}.
Для K = 7 задача имеет тривиальное решение, так как на каждую работу приходится по одному работнику. При K = 8 появилась бы возможность поставить "лишнего" работника на одну из работ комплекса. Тогда вариантов такой расстановки было бы 7 по количеству работ. При K = 9 вариантов расстановки было бы уже 72, а в нашем случае – 73. Количество вариантов с ростом размерности задачи быстро растет и решение ее путем полного перебора неэффективно.
Один из простых путей решения задачи состоит в том, чтобы разбить задачу на три шага. На первом шаге решить задачу, куда поставить 8-го работника. Зафиксировав рабочего, на втором шаге решать задачу, куда поставить 9-го работника и т.д. Таким образом, сложная задача свелась к трем последовательным более простым задачам. В общем случае число таких простых задач равно (K - N). Каждая из этих однотипных задач формулируется так.
Необходимо принять решение о добавлении одного работника на одну из работ комплекса так, чтобы время выполнения всего комплекса по полученной расстановке было минимальным.
При конкретной расстановке работников по каждой работе время выполнения отдельной (i, j)-ой работы составит tij = rij / kij, где kij - количество работников на (i, j)-ой работе. В нашей задаче при исходной расстановке семи работников по одному на каждую работу времена их выполнения численно равны трудоемкостям, а длительности полных путей составят
T(I1) = t01 + t13 + t35 = 1 + 2 + 4 = 7,
T(I2) = t01 + t14 + t45 = 1 + 2 + 1 = 4,
T(I3) = t02 + t24 + t45 = 2 + 3 + 1 = 6.
Продолжительность выполнения комплекса работ определяется продолжительностью самого длинного из полных путей (критического пути) I1 и равна 7 часам. Очевидно, чтобы уменьшить эту длительность, следует поместить "лишнего" 8-го работника на одну из работ критического пути. Ставя работника на каждую работу этого пути (0,1), (1,3), (3,5) и сравнивая получающиеся варианты, выбираем из них вариант с наименьшей продолжительностью выполнения комплекса работ. В нашем случае это вариант с размещением работника на работу (3,5). Таким образом, задача размещения одного работника решена и переходим к следующей задаче последовательности. В общем случае, при поиске решения по данному алгоритму придется проанализировать не более (K-N)N вариантов.
- Введение в программирование и основы алгоритмизации
- 1.2. Понятие "правильной" программы
- 1.3. Надежность программного средства
- 1.4. Технология программирования как разработка надежных пс
- 1.5. Информатизация общества
- Тема 2 источники ошибок в программных средствах
- 2.1. Интеллектуальные возможности человека
- 2.2. Неправильный перевод как причина ошибок в пс
- 2.3. Модель перевода
- На каждом из этих шагов человек может совершить ошибку разной природы.
- 2.4. Основные пути борьбы с ошибками
- Тема 3 общие принципы разработки программных средств
- 3.1. Специфика разработки пс
- 3.2. Жизненный цикл пс
- 3.3. Понятие качества пс
- 3.4. Внешнего описания и его роль в обеспечении качества пс
- 3.5. Обеспечение надежности – основной мотив разработки пс
- 3.5. Борьба со сложностью систем и обеспечение точности перевода
- Тема 4 разработка структуры программы. Модульное и объектно-ориентированное программирование
- 4.1. Цель модульного программирования
- 4.2. Основные характеристики программного модуля
- 4.3. Методы разработки структуры программы
- 4.4. Объектно-ориентированное программирование
- 4.5. События и событийная модель
- Тема 5 Алгоритмизация и разработка программного модуля
- 5.1. Определение алгоритма
- Алгоритмизация - техника составления алгоритмов и программ для решения задач на эвм.
- 5.2. Изобразительные средства описания алгоритмов
- 5.3. Блок-схемы алгоритмов. Графические символы
- 5.4. Порядок разработки программного модуля
- 5.5. Структурное программирование
- 5.6. Пошаговая детализация и понятие о псевдокоде
- Тема 6 тестирование и отладка программного средства
- 6.1. Основные понятия
- 6.2. Принципы и виды отладки пс
- 6.3. Заповеди отладки пс
- 6.4. Автономная отладка пс
- Тема 7 Методы разработки алгоритмов
- 7.1. Метод частных целей
- 7.2. Метод подъема
- 7.3. Программирование с отходом назад
- Тема 8 Алгоритмы сортировки
- 8.1. Сортировка. Основные понятия
- 8.2. Пузырьковая сортировка
- 8.3. Сортировка с помощью дерева
- 8.4. Пирамидальная сортировка
- 8.5. Быстрая сортировка
- Тема 9 Алгоритмы поиска и перебора
- 9.1. Поиск. Основные понятия
- 9.2. Бинарный поиск
- 9.3. Поиск в сети
- Тема 10 Событийно-управляемое программирование на языке Visual Basic
- 10.1. Историческая справка
- 10.2. Основы Visual Basic
- Среда Windows: окна, события, сообщения
- Интерактивная разработка
- Интегрированная среда разработки
- 10.3. Формы и элементы управления
- Разработка и установка свойств формы
- События и методы формы
- Кнопки управления как основа выполнения действий
- 10.4. Элементы управления пользователя
- Флажки и переключатели
- Другие стандартные элементы управления
- 10.5. Фокус. Последовательность переходов. Меню Фокус
- Основы меню
- Контекстные меню
- Редактор меню
- Подсказки пользователю с помощью диалога
- Тема 11 Управление проектами
- 11.1. Работа с проектом и его структура
- 11.2. Работа с несколькими проектами
- 11.4. Установка параметров проекта
- 11.5. Дополнения и мастера
- Тема 12 Управляющие конструкции
- 12.1. Конструкции принятия решения (ветвление)
- 12.2. Циклы
- 12.3. Работа со структурами управления и досрочный выход из них
- Тема 13 Структура приложения. Техника написания кода
- 13.1. Структура приложения
- 13.2. Как работает событийное приложение
- 13.3. До начала кодирования
- 13.4. Техника написания кода
- 13.5. Автоматизация написания программы