Как было указано, успешное использование вычислительных машин в анализе тесно связано с созданием математической модели. Если для данной проблемы или хотя бы для ее части нельзя построить модель, то вычислительная машина бесполезна. Вычислительная машина при современном понимании того, как она может быть использована, не может помочь решению проблемы, которую теоретически нельзя решить без ее помощи.
Вычислительная машина не является универсальным средством. То, что в данном исследовании использовалась вычислительная машина, не является гарантией его качества. Достоверность результата не выше достоверности модели, с которой работала вычислительная машина. Часто, к сожалению, результаты исследований кажутся заслуживающими доверия только потому, что они получены на вычислительной машине.
Факт использования в анализе вычислительной машины может свидетельствовать о том, что проблема была изучена детально и были рассмотрены разнообразные возможности. Но он ничего не говорит о качестве этого исследования.
Модели, их преимущества и скрытые в них опасности не являются предметом обсуждения в настоящей главе, но они настолько тесно связаны с использованием вычислительных машин для осуществления их работы, что разделить эти два предмета полностью нельзя. Остановимся вкратце на опасностях моделей. Модель воздушной войны может быть справедлива, например, только при условии, что участвующие в ней самолеты имеют дозвуковую скорость. Другими словами, те уравнения модели, в которые входит скорость полета, могут давать бессмысленные результаты, если в воздушных операциях принимают участие сверхзвуковые самолеты. Создатель модели мог вполне быть осведомлен об этом в свое время и не обращать на это внимания, потому что его интересовал только случай с дозвуковой скоростью. Этот пример указывает на одну из опасностей при использовании модели не по первоначальному назначению; модель, ценная для одного исследователя, может оказаться ловушкой для другого.
Даже в тех случаях, когда математическая модель создана с расчетом охватить самый общий случай, отработка этой модели на вычислительной машине может повести к некоторой потере общности. Например, программист, составляя программу для решения задачи о воздушной войне, может для большей эффективности составить программу так, чтобы в ней учитывался только случай дозвуковых скоростей, зная, что именно этот случай представляет интерес для создателя модели. При повторном использовании этой программы исследователь может упустить из виду то, что она была составлена только для частного случая. Так случилось однажды в корпорации РЭНД, когда мы захотели применить программу статистических испытаний, разработанную другой организацией. Хотя модель статистических испытаний допускает действия с неограниченным количеством данных, эта программа была составлена так, что машина учитывала только первые двадцать единиц статистической информации, а все остальные данные исключались.
Дело в том, что в программу для вычислительной машины может быть включено больше допущений, чем в саму модель. По этому поводу следует сделать дополнительное замечание. Допущения имеют место во всех моделях, но вычислительные машины дают возможность использования более сложных моделей, чем при расчетах вручную. Однако не следует обольщаться: и сложные модели включают Допущения, но там они сделаны на ином уровне детализации проблемы. Детализация может быть полезной, но не следует забывать, что допущения и здесь имеют место. Однако на некоторых людей детальность расчетов оказывает почти гипнотическое действие.
К проблеме построения модели примыкает смежная проблема подготовки программы для вычислительной машины, которая автоматизирует расчет модели. Конечно, оба эти процесса обычно идут параллельно. Однако для того чтобы сосредоточить наше внимание на задаче составления программы, предположим пока, что модель построена и отлажена. После этого программисты должны безупречно записать команды, с помощью которых модель вводится в машину. Важно уметь оценить объем нужной для этого работы, ибо человек склонен к недооценке затрат времени, необходимого для полного цикла, состоящего из постановки проблемы, программирования, проведения расчетов на машине, анализа результатов, вывода заключений и принятия решений. Мы заговорили об этой склонности потому, что даже опытные программисты зачастую излишне оптимистично оценивают время, требуемое для программирования той или иной задачи.
Вычислительную машину часто сравнивают с гигантским мозгом, приписывая ей многосторонний ум. В действительности вычислительная машина способна производить лишь ограниченное количество основных операций она может складывать, вычитать, умножать, делить и сравнивать числа, принимать входные данные и выдавать результаты. Некоторые вычислительные машины могут производить и другие операции, являющиеся вариациями перечисленных, но их возможности строго ограничены. Чтобы воспользоваться вычислительной машиной, нужно написать набор команд, называемый программой, что является задачей программиста. Типичная короткая программа приведена на рис. 14.1. В этом случае в вычислительной машине хранится некоторое число, и мы хотим извлечь из него квадратный корень. Мы не будем разбирать этот пример; он только показывает, что должен написать программист, чтобы заставить машину сделать что-то относительно простое.
На практике программы, подобные программе извлечения квадратного корня, которые, очевидно, необходимы программистам для решения многих задач, пишутся только один раз и затем включаются в библиотеку стандартных программ, откуда они могут быть извлечены программистом при необходимости. Это, в общем-то, тривиальное положение иллюстрирует тот факт, что большая часть программ составляется из подпрограмм.
При составлении набора команд программист должен сделать нечто большее, чем только дать машине команду на выполнение необходимых вычислений. Чтобы согласовать подпрограммы и добиться их совместной работы, необходимо произвести дополнительные действия; следует также каким-то образом ввести в машину исходные данные и вывести из нее результаты работы. Необходимо предусмотреть возобновление счета при сбое в работе машины, чтобы сбой не вел к потере всех полученных до того результатов. Необходимо также обеспечить контроль над результатами вычислений. Допустим, например, что программистом была допущена ошибка в постановке задачи для расчета траектории ракеты на настольной счетной машине. Через некоторое время он приходит и спрашивает: «В момент времени, равный 27 секундам, тяга становится отрицательной - может ли это быть?» Сама вычислительная машина дать ответа на такой вопрос не может, и результаты всей работы будут поставлены под сомнение, поскольку известно, что что-то неправильно, но что именно, не известно. Кроме того, наличие ошибки в постановке задачи может и не быть столь очевидным, если ошибка в окончательном результате не превысит, например, 20%. Поэтому программист, составляя программу, должен располагать определенными средствами контроля результатов вычислений.
Он должен составить свою программу таким образом, чтобы машина подавала сигнал, если результат расчета указывает на невозможное событие, например, если тяга становится меньше нуля. В программе извлечения квадратного корня аварийный сигнал подается, если число, из которого мы хотим извлечь квадратный корень, отрицательно. На практике над вычислениями, производимыми машиной, невозможно осуществить такой же строгий контроль, как над вычислениями, производимыми вручную. Однако в программу для вычислительной машины иногда можно ввести сложную систему проверок, которая потребовала бы слишком много труда, если ее выполнять вручную.
Занимаясь проблемой контроля результатов вычислений, программист вынужден ставить вопросы по существу проблемы. Они часто вскрывают упущения в разработке модели и еще раз подчеркивают тесную связь между построением модели и ее программированием. Программист, завершив работы над моделью, потребует внесения в нее многочисленных изменений, и он затратит значительное время на попытку облегчить введение этих изменений. Как показывает опыт, неудачи в подобных попытках объясняются, как правило, не тем, что программист плохо выполняет свои обязанности, а тем, что предугадать заранее существо этих изменений и их воздействие на модель очень трудно. Изменения в программе почти всегда требуют от программиста труда, непропорционального размерам этих изменений.
Составляя программу, программист старается предвидеть вопросы типа «А что, если...?», которые могут быть заданы модели, и предусмотреть возможность ответа на большинство подобных вопросов. Однако жизнь сложна, и могут возникнуть вопросы, ответить на которые удастся только путем коренной переделки программы.
После того как программист напишет набор команд, и они будут перфорированы для ввода в машину, начинается длительный процесс отладки программы. Обычно он делает это, проверяя работу каждой подпрограммы отдельно. Для этого часто приходится писать другие, отладочные программы, позволяющие произвести проверку различных подпрограмм. Затем он проверяет их совместную работу и, в конце концов, доводит программу до работоспособного состояния. Мы говорили о программисте в единственном числе, но на самом деле имели в виду целый коллектив программистов, так как в программировании сложной задачи занят целый коллектив людей, каждый из которых составляет свои подпрограммы, объединяемые впоследствии в окончательную программу.
Мы не упомянули еще об одном из более ранних этапов программирования - составлении блок-схемы программы. Она дает общий ход решения задачи и указывает последовательность действий при программировании. Типичная блок-схема приведена на рис. 14.2. Интересно заметить, что программисты редко пользуются такими аккуратными схемами.
Размеры полных программ для вычислительных машин могут изменяться от нескольких сотен команд до нескольких сотен тысяч. Производительность труда при программировании изменяется в широких пределах - от одной или двух команд, написанных и проверенных за один день, до нескольких сотен команд в день. Стоимость одной написанной и проверенной команды изменяется в соответствии с этим примерно от 0,5 долл. до 20 долл. Однако обычно стоимость одной команды лежит в пределах от 1 до 5 долл. Поэтому стоимость больших программ может быть очень велика. Это не противоречит высказанному ранее утверждению о том, что одним из основных положительных свойств вычислительных машин является способность выдавать результаты за недорогую цену. Напомним, что, сравнивая возможности вычислительных машин и человека, мы утверждали, что машины дают результаты за меньшую цену, чем люди, лишь после того, как составлена программа для машины. Следует также различать стоимость программирования и стоимость работы машины, производящей расчеты по составленной программе. Попутно целесообразно заметить, что относительная дешевизна единичного расчета вводит исследователя в соблазн производить все новые и новые расчеты, и в этом случае полная стоимость может быть очень велика. Он может также переоценить свои возможности при обработке результатов и окажется неспособным справиться с полученным ворохом бумаги.
Постановка задачи
Я попытался показать затраты труда на программирование, неотделимое от использования вычислительных машин, но мало сказал о затратах труда на разработку модели или вообще на постановку задачи. Хотя разработка моделей не является предметом обсуждения в этой главе, мы хотели бы рассмотреть проблему постановки задачи при таком использовании вычислительных машин, при котором не предусматривается применение модели в обычном значении этого понятия.
Постановка задачи обычно настолько переплетена с программированием, что их часто рассматривают как единое целое. Объем необходимой для этого работы постоянно недооценивают, и недооценивают очень существенно даже тогда, когда задача, в сущности, проста. Для того есть много причин. С одной стороны, если программированием занимаются люди, знакомые с задачей, то они должны уметь программировать. Но обучение требует много времени, и возможно, что они так никогда и не станут квалифицированными программистами. Если же, с другой стороны, программисты займутся постановкой задачи в целом, то им придется изучить задачу, что опять-таки требует времени, и вполне возможно, что они никогда не изучат ее как следует. Если над задачей работает смешанная группа, то возникает проблема общения между ее членами; каждый из специалистов в своей области должен научиться понимать язык другого, а на это требуется еще больше времени.
Метод, при котором программирование выполняют люди, знакомые с задачей, успешно применялся при проведении коммерческих расчетов. Метод, при котором постановка задачи выполняется программистом, совершенно не изучен. Использование смешанных групп весьма широко распространено, и, по-видимому, это наилучший метод. Однако в связи с таким подходом следует сделать одно важное замечание. Если речь идет о больших системах, то очень важно, чтобы человек, знакомый с задачей, научился понимать язык программиста и получил представление о программировании и ограничениях, присущих машинам. Если в руках такого человека находится большая и сложная задача, то он не может просто передать ее программисту для решения.
Другая причина недооценки размеров работы, необходимой для использования вычислительной машины в решении новой задачи, заключается в том, что решение задач на вычислительных машинах происходит совершенно иначе, чем при применении старого привычного метода. Консерватизм отдельных лиц и инертность организаций часто затрудняют введение перемен, а иногда делают их невозможными .
Мы считаем, что из всех элементов, из которых слагается эта работа, больше всего трудностей доставляет детальное решение вопроса, какую именно проблему мы собираемся решать. Например, один директор банка, в котором все операции были недавно автоматизированы, сообщил, что 65% труда группы, занимавшейся вопросами обработки данных, ушло на детальное уяснение проблемы, решением которой им предстояло заниматься.
Для уяснения причин большой длительности подготовительного периода приведем несколько примеров.
Самым ярким примером трудностей при использовании машин для бухгалтерского учета, по-видимому, является пример с промышленной фирмой, решившей автоматизировать составление платежных ведомостей. Заработная плата в этой фирме рассчитывалась по прогрессивной системе, с учетом работы, как отдельных работников, так и целых групп, так что платежные ведомости были исключительно сложными. У фирмы были свои собственные специалисты, ряд опытных специалистов был предоставлен в ее распоряжение фирмой-поставщиком вычислительных машин. Для большей надежности прибегли к консультациям специалистов по коммерческим расчетам. Состояние проблемы опасения не вызывало. Однако примерно через два года, после того как было написано несколько сот тысяч команд, все участники работ признали, что она им не под силу. Следует учесть, правда, что данная группа решала эту проблему одной из первых и ей пришлось многому учиться. В наши дни машины хорошо справляются с проверкой инвентарных списков и составлением платежных ведомостей. К сожалению, организации и отдельные лица, работающие в этой области, не особенно склонны учиться на ошибках других, и подобные случаи неоднократно повторяются.
Второй пример относится к компании городского энергоснабжения. Она избрала более разумный и намеренно медленный подход к проблеме, но масштабы работы были также недооценены. Изучение проблемы началось в 1953 г. Через год компания решила, что приобретение вычислительной машины было бы экономически оправдано, и заказала машину определенного типа. Специалисты немедленно принялись за постановку задачи и программирование. Еще через два с половиной года компания получила машину и начала передавать на машину работу, производившуюся до того людьми. Длительность переходного периода вместо запланированных девяти месяцев составила четырнадцать месяцев. Первоначально предполагалось, что потребуется программа из 30 000 команд. Когда работа была завершена, объем программы составил 42 000 команд, так как были недооценены размеры работы, необходимой для учета в программе отдельных, не часто встречающихся операций; в ходе этого была также установлена необходимость включения в программу различных проверок (упомянутые выше аварийные сигналы). Помимо того, для обеспечения нужд переходного периода пришлось написать еще 20 000 команд. В течение переходного периода были наняты дополнительно новые сотрудники, так как в это время действовали три системы: старая, новая и промежуточная. Чтобы установить вычислительную машину, которая обычно способствует сокращению рабочей силы на предприятии, компании пришлось временно увеличить число сотрудников на 60 человек. В ходе установки машины были произведены изменения в структуре бухгалтерских групп и в характере деятельности компании во многих областях. Таким образом, этот переход привел к существенной реорганизации.
Вывод отсюда следующий: для больших систем затраты труда на подготовку программы для вычислительной машины являются основным фактором, определяющим длительность ввода вычислительных систем в эксплуатацию.