Технические требования для решения задачи или постановка задачи
Прежде чем мы сможем понять задачу, мы должны ее точно сформулировать. Это условие само по себе не является достаточным для понимания задачи, но оно абсолютно необходимо.
Обычно процесс точной формулировки задачи сводится к постановке правильных вопросов. Перечислим некоторые полезные вопросы для плохо сформулированных задач:
Понятна ли терминология, используемая в предварительной формулировке? Что дано?
Что нужно найти? Как определить решение?
Каких данных не хватает и все ли они нужны? Являются ли какие-то имеющиеся данные бесполезными? Какие сделаны допущения?
Возможны и другие вопросы в зависимости от конкретной задачи. Часто после получения полных пли частичных ответов на некоторые из вопросов их приходится ставить повторно.
Другими словами задание на программу включает возможно полное и точное описание действия программы, т.е. что она должна делать, какие у нее исходные данные и результаты, ограничения на область ее применения, ограничения на эффективность (если они есть).
При этом одним из важных условия является однозначность задания, т.е. задача должна быть поставлена таким образом, чтобы ее понимание было возможно только однозначно. В противном случае, если формулировка задачи допускает ее неправильное толкование, то обязательно найдется человек, который именно так и сделает.
При этом необходимо использовать следующие практические советы
1. Прежде чем приступать к решению задачи необходимо убедиться в правильности ее понимания.
2. Если такая задача ставится Вами, то важно сформулировать ее как можно яснее еще до начала разработки программы. Для этого на бумаге нужно записать техническое задание (ТЗ) того, что должно быть сделано: исходные данные, результаты, средства для достижения этого и ограничения (например оперативную память, время или деньги), которые необходимо соблюсти. Это уже само по себе помогает собраться с мыслями, однако целесообразно показать спецификацию соответствующим образом подготовленному коллеге, и спросить его может ли он все это понять, либо указать на недостатки, неопределенности или упущения.
3. Если задача ставится не Вами, то необходимо внимательно ознакомиться с ТЗ на нее и убедиться, что Вам понятна каждая ее часть. И, если что-то непонятно, потребовать разъяснений, при этом не надо бояться «потерять лицо» или показаться глупым, нельзя надеяться на то, что все прояснится позже. Если в работе заняты несколько человек то необходимо, не только иметь правильное представление о задаче, но и правильно распределить работу между ними.
4. Необходимо составить законченное представление о всем проекте, а не только о проектировании конкретной программы. В самом начале главы мы поставили последовательность этапов разработки программного обеспечения; этот порядок в некоторой степени отражает последовательность создания проекта. Однако он не соответствует порядку в котором программист должен рассматривать различные факторы. В качестве примера можно указать, что документирование - это такой процесс, который должен начинаться с самого начала работы над проектом (с написания ТЗ) и продолжаться на протяжении всей работы. Однако все этапы разработки непрерывно связаны и примерно соответствуют той последовательности в какой они записаны, т.е. реализация каждого нового этапа невозможна без соответствующей проработки предыдущего.
В заключении приведем пример карикатуры, показанной на рис.3.1, когда впервые она появилась она нашла отклик в сердцах программистов, постигших эти уроки нелегким путем.
Для еще лучшего понимания как правильно сформулировать ТЗ рассмотрим пример о так называемой транспортной задачи.
Пример. Виктор — агент по продаже компьютеров (коммивояжер); на его территории 20 городов, разбросанных по всей Воронежской области. Компания возмещает ему только 50% стоимости деловых автомобильных поездок. Виктор вычислил, сколько ему будет стоить переезд на машине между каждыми двумя городами на его территории. Ему, естественно, хотелось бы снизить свои дорожные расходы.
Что дано? Исходная информация задана в виде перечня городов на территории Виктора и соответствующей матрицы стоимостей, т. е. двумерного массива с элементами Cij, равными стоимости переезда из города i в город j. В данном случае матрица стоимостей имеет 20 строк и 20 столбцов.
Что мы хотим найти? Мы хотим помочь Виктору снизить его дорожные расходы. Это звучит несколько туманно. Действительно, вопрос о том, каким будет решение, выглядит неуместным. Обдумав ситуацию, мы придем к выводу, что ничего не можем сделать без дополнительной информации от Виктора. Имеет ли Виктор в одних городах больше покупателей, чем в других? Если да или если есть какие-то особые покупатели, то Виктор, возможно, захочет посещать какие-то города чаще. Могут быть и такие города, в которые Виктор специально не поедет, а заедет туда, когда окажется в соседнем городе. Другими словами, нам надо знать больше о приоритетах Виктора и учитывать предпочтения при составлении графика поездок.
Поэтому мы возвращаемся к Виктору и требуем у него дополнительную информацию. Он сообщает, что хотел бы иметь маршрут, начинающийся и оканчивающийся в его базовом городе и проходящий по одному разу через все остальные города на его территории. Следовательно, нам требуется список городов, содержащий каждый город только один раз, за исключением базового города, который стоит в списке первым и последним. Порядок городов в этом списке представляет собой маршрут, по которому Виктор должен объезжать города на своей территории. Сумма стоимостей проезда между каждыми двумя последовательными городами списка - это общая стоимость маршрута, представленного списком. Мы решим задачу Виктора, если представим ему список с наименьшей возможной общей стоимостью.
Это хорошая исходная постановка задачи. Мы знаем, что мы имеем и что хотим найти.
![]() |
Рис.3.1. Постановка и решение задачи при неправильном формулировании