Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Костюк - Основы программирования

.pdf
Скачиваний:
138
Добавлен:
30.05.2015
Размер:
1.3 Mб
Скачать

131

 

 

 

v:=i;

u:=i;

 

for j:=i+1 to m do

 

for

k:=i+1 to n do

if abs(A[j,k])>abs(A[v,u]) then

 

begin v:=j; u:=k end;

 

 

if v<>i then

{перестановка i–го уравнения с v–м}

for

j:=i to n+1 do begin

z:=A[i,j]; A[i,j]:=A[v,j]; A[v,j]:=z

end;

 

{перестановка i–го столбца с u–м}

if u<>i then begin

for k:=1 to m do begin

z:=A[k,i]; A[k,i]:=A[k,u]; A[k,u]:=z end;

p:=L[i]; L[i]:=L[u]; L[u]:=p end;

(7.12)

(7.13)

c:=A[i,i];

for j:=i to n+1 do (7.14)

A[i,j]:=A[i,j]/c;

for k:=1 to m do

if k<>i then begin

c:=A[k,i]; (7.15) for j:=i to n+1 do A[k,j]:=A[k,j]-c*A[i,j]

end;

Алгоритм (7.11) преобразует систему уравнений (7.1) к виду (7.3), из которого получается общее решение. Далее должны быть выполнены проверки, выделяющие три выше перечисленных варианта решений. После этого можно получить значения неизвестных (в первом варианте по формуле (7.4), а в третьем варианте по формуле (7.5)). При этом следует учитывать запомненные в массиве L перестановки номеров неизвестных, в результате неизвестные будут перечислены в следующем порядке:

xL[1], xL[2], …, xL[n].

(7.6)

Конец примера.

7.3 Алгоритмы с квадратными матрицами

Рассмотрим две важнейшие операции над квадратными матрицами – вычисление определителя и обращение матрицы.

132

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

Пример 7.10. Алгоритм вычисляет определитель квадратной матрицы методом Гаусса с частичным выбором ведущего элемента. Массив A размерностью n×n со­ держит коэффициенты матрицы. Результат – X.

i:=1; r:=n; p:=1; while i<=r do

begin {Выбор ведущего элемента A[v,i] (7.17)} if abs(A[v,i])<eps then r:=i-1

else begin {Перестановка строк (7.18)} (7.16) {Вычитание строк матрицы (7.19)}

i:=i+1 end

end;

{ Вычисление определителя (7.20)}

Запишем отдельные этапы алгоритма (7.16). Выбор ведущего элемента – в алго­ ритме (7.17), перестановка строк – в алгоритме (7.18), вычитание строк матрицы – в алгоритме (7.19), вычисление определителя – в алгоритме (7.20).

 

 

v:=i;

 

for j:=i+1 to n do

(7.17)

if abs(A[j,i])>abs(A[v,i]) then v:=j;

 

 

 

if v<>i then begin p:=-p;

 

for j:=i to n do begin

 

z:=A[i,j]; A[i,j]:=A[v,j]; A[v,j]:=z

(7.18)

end

 

end;

 

 

 

for k:=i+1 to n do

 

begin

 

c:=A[k,i]/A[i,i];

(7.19)

for j:=i to n do A[k,j]:=A[k,j]-c*A[i,j]

 

end;

 

133

if r<n then X:=0 else begin

X:=p*A[1,1]; (7.20) for i:=2 to n do X:=X*A[i,i]

end;

Нетрудно видеть, что общее количество исполнений внутреннего цикла на этапе вычитания уравнений (самом трудоемком этапе) приближенно равно n3/3, как в алго­ ритме (7.8). Перед выполнением алгоритма (7.16) необходимо также задать eps.

Конец примера.

Вычисление обратной матрицы. Согласно определению, обратная матрица

должна удовлетворять равенству:

 

AD = I ,

(7.7)

где A – исходная квадратная матрица, D – обратная матрица,

I – единичная мат­

рица. Все матрицы имеют размер n×n. Равенство (7.6) можно представить в виде:

AЧD j = I j , j = 1,..., n ,

(7.8)

где Dj j–й столбец обратной матрицы, I j j–й столбец единичной матрицы.

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

Пример 7.11. Алгоритм вычисляет обратную матрицу методом Гаусса с частич­ ным выбором ведущего элемента. Массив A размерностью n×n содержит ко­ эффициенты матрицы. Массив D размерностью n×n первоначально содержит эле­ менты единичной матрицы. Результат (обратная матрица) – в массиве D.

i:=1; r:=n; while i<=r do

begin {Выбор ведущего элемента A[v,i] (7.17)} if abs(A[v,i])<eps then r:=i-1;

else begin {Перестановка строк (7.22)} (7.21) {Деление i–й строки на A[i,i] (7.23)}

{Вычитание уравнений (7.24)} i:=i+1

end

134

end;

Перестановка строк:

if v<>i then begin

for j:=i to n do begin

z:=A[i,j]; A[i,j]:=A[v,j]; A[v,j]:=z end;

for j:=1 to n do begin

z:=D[i,j]; D[i,j]:=D[v,j]; D[v,j]:=z end

end;

Деление i–й строки на A[i,i]:

aii:= A[i,i];

for j:=i to n do A[i,j]:=A[i,j]/aii; for j:=1 to n do D[i,j]:=D[i,j]/aii;

(7.22)

(7.23)

Вычитание уравнений:

for k:=1 to n do

if k<>i then begin c:=A[k,i];

for j:=i to n do A[k,j]:=A[k,j]-c*A[i,j]; (7.24) for j:=1 to n do D[k,j]:=D[k,j]-c*D[i,j]

end;

Если после исполнения алгоритма (7.21) величина r оказалась меньше, чем n, то это означает, что обратная матрица не существует.

Нетрудно видеть, что общее количество исполнений внутреннего цикла на этапе вычитания уравнений (самом трудоемком этапе) приблизительно равно n3/2 + n3 = 1,5∙n3 . Перед выполнением алгоритма (7.21) необходимо задать eps.

Конец примера.

Вопросы и задания

1.Оформить в виде процедур следующие алгоритмы над векторами и матрицами:

1)вычисление суммы векторов;

2)вычисление суммы матриц;

3)вычисление скалярного произведения векторов;

4)вычисление произведения вектора на скаляр;

5)вычисление произведения прямоугольной матрицы на скаляр;

6)вычисление произведения вектора на прямоугольную матрицу;

7)вычисление произведения прямоугольной матрицы на вектор;

8)вычисление произведения двух прямоугольных матриц;

135

9) возведение квадратной матрицы в положительную целочисленную степень. Взять за основу алгоритмы (7.1) – (7.7).

2.Написать программу, которая вводит из файла прямоугольную матрицу, вычисляет произ­ ведение этой матрицы на нее же транспонированную и записывает вычисленное произве­ дение в файл. При этом запрещается использовать дополнительные массивы.

3.Оформить в виде процедуры алгоритм решения системы n линейных уравнений с n неизвестными методом Гаусса с частичным выбором ведущего элемента. Взять за осно­ ву алгоритмы (7.8) – (7.10).

4.Взяв за основу алгоритмы (7.11) – (7.15), написать программу, вычисляющую общее ре­

шение системы n линейных уравнений с m неизвестными методом Гаусса.

5.Оформить в виде процедуры алгоритм вычисления определителя квадратной матрицы ме­ тодом Гаусса с частичным выбором ведущего элемента. Взять за основу алгоритмы (7.16) – (7.20).

6.Оформить в виде процедуры алгоритм обращения квадратной матрицы методом Гаусса с частичным выбором ведущего элемента. Взять за основу алгоритмы (7.21) – (7.24).

7.Написать программу, которая вводит из файла прямоугольную матрицу и вычисляет ее

ранг методом Гаусса с выбором ведущего элемента. Взять за основу алгоритмы (7.8) – (7.10).

Глава 8 Технология программирования

8.1 Программы, комплексы программ и программные продукты

Программы создают для различных целей. Многие программы создаются про­ граммистами только для собственных нужд, для таких программ, как правило, не пи­ шутся какие-либо инструкции или описания. Если же программа разрабатывается с целью ее тиражирования и последующего применения многими пользователями, то она должна обладать более удобным интерфейсом, выдавать диагностические сооб­ щения в случае возникновения каких-либо некорректных ситуаций в процессе вычис­ лений, и, кроме того, обязательно снабжаться описанием или инструкцией (про­ граммной документацией). Такая программа вместе с документацией называется программным продуктом. Создание программного продукта требует гораздо большего труда, чем написание аналогичной по объему простой программы для соб­ ственных нужд программиста. Многочисленные исследования показывают, что тру­ дозатраты при этом возрастают примерно в 3 раза.

Обычная программа, как правило, реализует некоторый алгоритм с одним вхо­ дом и выходом. Программная система или комплекс программ состоит из сово­ купности функционально связанных программ, предназначенных для решения цело­ го класса задач. Их создание требует гораздо большего труда, чем написание анало­ гичной по объему простой программы; согласно исследованиям, объем работы при этом возрастает в 3–4 раза.

Если комплекс программ предназначен для тиражирования и применения многи­ ми пользователями, то он создается в виде комплексного программного продукта, при этом трудозатраты (по сравнению с аналогичной по объему простой програм­ мой) возрастают приблизительно в 10 раз. Поэтому разработка большого по объему комплексного программного продукта может потребовать труда многих программи­ стов на протяжении нескольких месяцев и даже лет.

Научная дисциплина технология программирования начала создаваться в 60–е годы, когда в практическом программировании стали разрабатываться программные продукты большого объема, вследствие чего появилась потребность в планировании труда программистов для сокращения сроков разработки и улучшения качества со­ здаваемых программных продуктов. В дальнейшем рекомендации этой научной дис­ циплины вошли в различные промышленные и государственные стандарты. Далее,

137

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

Весь процесс разработки системы можно разделить на следующие последова­ тельно выполняемые этапы:

1)этап технического задания (ТЗ);

2)проектирование архитектуры системы;

3)проектирование и разработка системы;

4)этап опытной эксплуатации.

Целью первого этапа является создание документа (ТЗ), в котором описаны тех­ нические требования, условия и ожидаемые характеристики создаваемой системы. ТЗ является основополагающим документом для последующей разработки. Если си­ стема создается для конкретного заказчика, то подготовленное ТЗ утверждается за­ казчиком, а после окончания разработки производится приемка-сдача системы, когда разработчик должен убедить заказчика, что система удовлетворяет требованиям ТЗ. Иногда, с целью обоснования технических требований в ТЗ, проводятся специальные научные исследования.

На этапе проектирования архитектуры прорабатываются основные концепции системы, уточняются и конкретизируются технические требования. Создается основ­ ная архитектура системы, т.е. прорабатываются принципы взаимодействия пользова­ теля с системой, проектируются в целом основные структуры данных и общая про­ граммная структура системы, ее разбиение на основные компоненты или модули. За­ тем проводится анализ архитектуры, при необходимости корректируется ТЗ и весь этап повторяется.

На этапе проектирования и разработки выполняется основная работа по созда­ нию системы: детальное проектирование структур данных и уточнение архитектуры компонентов системы, программирование всех компонентов системы, тестирование и отладка не только отдельных компонентов, но и системы в целом. Кроме того, на этом этапе создается программная документация.

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

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

138

процесс называется сопровождением программного продукта. Жизненный цикл системы продолжается, пока разработчик (или тот, кому переданы эти обязанности) осуществляет сопровождение системы. Очередной вариант системы, полученный в процессе ее сопровождения, называют версией или релизом. Версии обычно нуме­ руют двумя числами, записываемыми через точку, причем начинают нумерацию с версии 1.0. После небольшой модификации системы, когда в основном исправляют лишь обнаруженные ошибки, в номере версии увеличивают на единицу второе чис­ ло. Если же система была подвергнута существенной доработке, то увеличивают на единицу первое число, а второе число делают нулем. Так, после версии 1.5 может идти версия 2.0, затем 2.1, 2.2 и т.д.

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

8.2 Программная документация

Комплект программных документов обычно делится на две части, в одну часть входит эксплуатационная документация, в другую – документация сопровождения. При поставке системы пользователям передается сама система (в виде файлов, содер­ жащих готовые к выполнению программы) и эксплуатационная документация. Доку­ ментация сопровождения остается у разработчика системы или передается заказчику (если система сделана на заказ).

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

В руководстве по установке системы (или в соответствующем разделе описа­ ния применения) должны быть описаны минимальные технические характеристики

139

компьютера (компьютерной сети) и операционной системы, где может функциониро­ вать система. Должен быть приведен список файлов системы, описаны действия пользователя для развертывания системы на компьютере. Как правило, файлы с про­ граммами поставляются для пользователей в готовом (откомпилированном) виде. Для сложных систем разработчики обычно создают специальную программу по уста­ новке (по-английски “set up”), которая автоматически создает необходимые разделы на диске, копирует файлы, запрашивает пользователя о параметрах установки (если они предусмотрены в системе).

В описании применения должны быть указаны технические характеристики компьютера и операционной системы, а также технические характеристики самой си­ стемы (ее производительность и др.). Должны быть приведены сведения по непосред­ ственному использованию системы (как задавать входные данные, как общаться с си­ стемой в диалоге, в каком виде система выдает результаты, и т.п.). Кроме того, долж­ ны быть приведены примеры выполнения программы (контрольные примеры) с по­ дробными пояснениями. Так как описание применения рассчитано не на программи­ ста, то в нем не следует использовать без особой необходимости специальные компьютерные термины.

Хорошая система должна содержать и программные средства, помогающие поль­ зователю быстрее освоиться с системой, помочь ему, если пользователь что-то забыл в описании применения. Обычно эти средства реализуются в виде справок (помощи, по-английски – help), которые можно вызвать в любой момент диалога с системой, и содержание которой автоматически определяется тем, с какой функцией системы взаимодействует пользователь.

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

Текст программы (системы) представляется на исходном языке программиро­ вания. Он должен быть хорошо структурированным и содержать комментарии, об­ легчающие его понимание.

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

140

Вописании программы должно быть также написано, как генерировать (трансли­ ровать, собирать готовые к выполнению компоненты системы). Должны быть описа­ ны методы тестирования и приведены сами тесты.

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

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

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

8.3Проектирование и программирование программ и комплексов программ

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

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