logo
АСУ ТП / ИДЗ №1 / Анализ сложных систем

14.3. Программирование модели

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

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

Факт использования в анализе вычислительной машины может свидетельствовать о том, что проблема была изучена детально и были рассмотрены разнообразные возможности. Но он ничего не говорит о качестве этого исследования.

Модели, их преимущества и скрытые в них опасности не являются предметом обсуждения в настоящей главе, но они настолько тесно связаны с использованием вычислительных машин для осуществления их работы, что разделить эти два предмета полностью нельзя. Остановимся вкратце на опасностях моделей. Модель воздушной войны может быть справедлива, например, только при условии, что участвующие в ней самолеты имеют дозвуковую скорость. Другими словами, те уравнения модели, в которые входит скорость полета, могут давать бессмысленные результаты, если в воздушных операциях принимают участие сверхзвуковые самолеты. Создатель модели мог вполне быть осведомлен об этом в свое время и не обращать на это внимания, потому что его интересовал только случай с дозвуковой скоростью. Этот пример указывает на одну из опасностей при использовании модели не по первоначальному назначению; модель, ценная для одного исследователя, может оказаться ловушкой для другого.

Даже в тех случаях, когда математическая модель создана с расчетом охватить самый общий случай, отработка этой модели на вычислительной машине может повести к некоторой потере общности. Например, программист, составляя программу для решения задачи о воздушной войне, может для большей эффективности составить программу так, чтобы в ней учитывался только случай дозвуковых скоростей, зная, что именно этот случай представляет интерес для создателя модели. При повторном использовании этой программы исследователь может упустить из виду то, что она была составлена только для частного случая. Так случилось однажды в корпорации РЭНД, когда мы захотели применить программу статистических испытаний, разработанную другой организацией. Хотя модель статистических испытаний допускает действия с неограниченным количеством данных, эта программа была составлена так, что машина учитывала только первые двадцать единиц статистической информации, а все остальные данные исключались.

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

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

Вычислительную машину часто сравнивают с гигантским мозгом, приписывая ей многосторонний ум. В действительности вычислительная машина способна производить лишь ограниченное количество основных операций она может складывать, вычитать, умножать, делить и сравнивать числа, принимать входные данные и выдавать результаты. Некоторые вычислительные машины могут производить и другие операции, являющиеся вариациями перечисленных, но их возможности строго ограничены. Чтобы воспользоваться вычислительной машиной, нужно написать набор команд, называемый программой, что является задачей программиста. Типичная короткая программа приведена на рис. 14.1. В этом случае в вычислительной машине хранится некоторое число, и мы хотим извлечь из него квадратный корень. Мы не будем разби­рать этот пример; он только показывает, что должен написать программист, чтобы заставить машину сделать что-то относительно простое.

На практике программы, подобные программе извлечения квадратного корня, которые, очевидно, необходимы программистам для решения многих задач, пишутся только один раз и затем включаются в библиотеку стандартных программ, откуда они могут быть извлечены программистом при необходимости. Это, в общем-то, тривиальное положение иллюстрирует тот факт, что большая часть программ составляется из подпрограмм.

При составлении набора команд программист должен сделать нечто большее, чем только дать машине команду на выполнение необходимых вычислений. Чтобы согласовать подпрограммы и добиться их совместной работы, необходимо произвести дополнительные действия; следует также каким-то образом ввести в машину исходные данные и вывести из нее результаты работы. Необходимо предусмотреть возобновление счета при сбое в работе машины, чтобы сбой не вел к потере всех полученных до того результатов. Необходимо также обеспечить контроль над результатами вычислений. Допустим, например, что программистом была допущена ошибка в постановке задачи для расчета траектории ракеты на настольной счетной машине. Через некоторое время он приходит и спрашивает: «В момент времени, равный 27 секундам, тяга становится отрицательной - может ли это быть?» Сама вычислительная машина дать ответа на такой вопрос не может, и результаты всей работы будут поставлены под сомнение, поскольку известно, что что-то неправильно, но что именно, не известно. Кроме того, наличие ошибки в постановке задачи может и не быть столь очевидным, если ошибка в окончательном результате не превысит, например, 20%. Поэтому программист, составляя программу, должен располагать определенными средствами контроля результатов вычислений.

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

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

Составляя программу, программист старается предвидеть вопросы типа «А что, если...?», которые могут быть заданы модели, и предусмотреть возможность ответа на большинство подобных вопросов. Однако жизнь сложна, и могут возникнуть вопросы, ответить на которые удастся только путем коренной переделки программы.

После того как программист напишет набор команд, и они будут перфорированы для ввода в машину, начинается длительный процесс отладки программы. Обычно он делает это, проверяя работу каждой подпрограммы отдельно. Для этого часто приходится писать другие, отладочные программы, позволяющие произвести проверку различных подпрограмм. Затем он проверяет их совместную работу и, в конце концов, доводит программу до работоспособного состояния. Мы говорили о программисте в единственном числе, но на самом деле имели в виду целый коллектив программистов, так как в программировании сложной задачи занят целый коллектив людей, каждый из которых составляет свои подпрограммы, объединяемые впоследствии в окончательную программу.

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

Размеры полных программ для вычислительных машин могут изменяться от нескольких сотен команд до нескольких сотен тысяч. Производительность труда при программировании изменяется в широких пределах - от одной или двух команд, написанных и проверенных за один день, до нескольких сотен команд в день. Стоимость одной напи­санной и проверенной команды изменяется в соответствии с этим примерно от 0,5 долл. до 20 долл. Однако обычно стоимость одной команды лежит в пределах от 1 до 5 долл. Поэтому стоимость больших программ может быть очень велика. Это не противоречит высказанному ранее утверждению о том, что одним из основных положительных свойств вычислительных машин является способность выдавать результаты за недорогую цену. Напомним, что, сравнивая возможности вычислительных машин и человека, мы утверждали, что машины дают результаты за меньшую цену, чем люди, лишь после того, как составлена программа для машины. Следует также различать стоимость программирования и стоимость работы машины, производящей расчеты по составленной программе. Попутно целесообразно заметить, что относительная дешевизна единичного расчета вводит исследователя в соблазн производить все новые и новые расчеты, и в этом случае полная стоимость может быть очень велика. Он может также переоценить свои возможности при обработке результатов и окажется неспособным справиться с полученным ворохом бумаги.