Вы находитесь на странице: 1из 38

О.Н. Паулин.

Основы теории алгоритмов

Глава 1
ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

В данной главе рассмотрим примеры простейших численных и логи-


ческих алгоритмов и опишем особенности организации вычислительных
процессов с использованием основных структур управления: альтерна-
тивы (разветвления) и итерации (цикла).

1.1. Разветвления в алгоритмах

1.1.1. Примеры алгоритмов, линейных и с разветвлением

Рассмотрим сначала линейные алгоритмы.


Линейным называется алгоритм, в схеме которого блоки (вершины)
связаны в одну линию.
Пример 1.1. Составить СА для вычисления следующей функции:
y = sin()cos() + e-x cos() (1.1)
при заданных значениях   x.
Вычислительный процесс для данной функции может быть организован
в виде последовательности шагов, на каждом из которых выполняются
следующие вычисления:
1) А1 = sin(); 2) A2 = cos(); 3) A3 = exp(-х); 4) A4 = cos();
5) B1 = A1 A2; 6) B2 = A3 A4; 7) у = B1 + B2.
СА, представляющая данный вычислительный процесс с учётом ввода
исходных данных и вывода вычисленного значения y, является линейной
(рис. 1.1; начальный и конечный блоки не нумеруются). Её особенность – то,

15
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

что операторные блоки 2-5 можно располагать в произвольном порядке; то же


относится и к блокам 6 и 7.
Независимость СА от расположения отдельных блоков означает, что
реализуемые ими фрагменты вычислительного процесса можно выпол-
нить одновременно (параллельно) при наличии соответствующих аппарат-
ных средств. Одновременность выполнения фрагментов обозначается на
СА параллельными линиями (рис. 1.2); при этом допускается возможность
расхождения связей на выходах всех блоков (кроме, разумеется, конечного).

Рис. 1.1. Пример линейной СА (последовательная реализация)

Для вычисления функций SIN, COS и EXP используются стандартные


подпрограммы (СП), основанные, как правило, на представлении этих
функций в виде полиномов (например, разложение в ряд Тейлора [4]).
Однако эти СП реализуют нелинейные СА, содержащие циклы – см. п. 1.2.

16
О.Н. Паулин. Основы теории алгоритмов

Рис. 1.2. Параллельная реализация СА для примера 1.1

Таким образом, линейность СА - понятие относительное; при более


подробном рассмотрении СА может оказаться нелинейной. В сколько-нибудь
сложной СА линейными могут быть только её отдельные фрагменты.
Рассмотрим далее схемы алгоритмов с разветвлением.
Разветвлением будем называть фрагмент СА, содержащий блок
выбора альтернативного направления с одним входом и с двумя или
более выходами; по этим выходам организуются связи с другими
фрагментами СА. Выбор альтернатив осуществляется по определённому

17
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

условию, возможно, сложному, реализуемому совокупностью условных


операторов.
Пример 1.2. Составить СА нахождения корней квадратного
уравнения
au2 + bu + c = 0. (1.2)
Предварительно запишем приведённое квадратное уравнение с целью
уменьшения числа параметров, определяющих решения исходного уравнения:
u2 + pu + q = 0; (1.3)
здесь
p = b/a, q = c/a (a  0 !). (1.4)
Корни приведённого квадратного уравнения определяются по формуле
u1,2 = -p/2  d, (1.5)
где
d = p2/4 – q. (1.6)
В зависимости от значений d возможны 3 случая :
 d>0. Решение содержит два вещественных корня
u1 = -p/2 + d, u2 = -p/2 - d; (1.7)
 d<0. Решение содержит два мнимых корня (u = x + iy, i = -1)
u1= -p/2 + id, u2= -p/2 - id; (1.8)
 d=0. Решение содержит два слившихся вещественных корня
u1=u2= -p/2. (1.9)

Проанализируем поведение корней при


изменении величины и знака дискриминанта
d (рис.1.3):
1) d<0 - корни перемещаются симмет-
рично по вертикали (мнимая ось);

18
О.Н. Паулин. Основы теории алгоритмов

2) d>0 - корни перемещаются симметрично по горизонтали (реальная ось);


3) d=0 - граничная точка x = -p/2 при переходе с вертикали на
горизонталь.

Анализ такого рода необходим при построении контрольного


примера для отладки программы или при ее тестировании. Конечно, для
такого анализа рассмотренный пример слишком простой. Но в более
сложных случаях (нахождение корней уравнения высокого порядка, корней
системы уравнений и т.д.) без такого анализа не обойтись, особенно если
интересны не только совокупность конкретных значений решения задачи,
но и зависимость этих значений от параметров задачи.
Составляем СА (рис. 1.4), исходя из такой последовательности шагов:
вводим исходные данные и вычисляем параметры приведённого квадратного
уравнения; вычисляем значения корней в соответствии с тремя возможными
альтернативами, определяемыми условными блоками; выводим результаты
на экран (принтер).

19
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

На рис. 1.4,а пунктиром выделен блок выбора трёх альтернативных


направлений в зависимости от значения дискриминанта d; он легко преоб-
разуется в эквивалентный ему блок выбора (рис. 1.4,б). Анализ этого
блока показывает, что проверку условия d=0 можно исключить из
алгоритма, так как в случае d=0 равные значения корней получаются
автоматически.

1.1.2. Общие вопросы организации разветвлений в алгоритмах

Рассмотрим вопрос организации выбора направления в СА подробнее.


Ситуации, в которых необходимо сделать выбор из нескольких аль-
тернатив, описываются составными логическими операторами, получен-
ными композицией простых условий (простых предикатов). Сложность
выбора определяется как множеством условий, так и множеством альтер-
натив. Каждому альтеpнативному напpавлению в СА выбора пpисваи-
вается свой десятичный номеp, начиная с 1.
На СА выбоp pеализуется двоичным деpевом (см. подразд. 3.5),
полным либо неполным, в каждом узле (условном блоке) котоpого
пpостейший выбоp кодиpуется логическим 0, если условие не выполняется
(false), и логической 1, если условие выполняется (true).
Если составить позиционный код на выходе из блока выбоpа по каж-
дому напpавлению в соответствии с кодами на выходах условных блоков
СА при последовательном пpохождении чеpез них свеpху вниз, то получим
двоичный код десятичного номера альтернативы, уменьшенного на 1.
Пpоpанжиpуем свеpху вниз условные блоки (ранг СА выбора – это глубина
узла дерева выбора, увеличенная на 1); тогда количество альтеpнатив m,
пpедоставляемых полным двоичным деревом, опpеделяется его pангом r,

20
О.Н. Паулин. Основы теории алгоритмов

m=2r. Возвpащаясь к pис.1.4, отметим, что в данном случае имеется двух-


pанговое неполное деpево выбоpа (r = ] log2 3 [ = 2).
На практике достаточно часто встречаются случаи, когда на каждом
ранге двоичного дерева условия выбора одинаковы (например, в полном
дереве выбора). Для описания такого рода ситуации достаточно, чтобы
количество булевых переменных логической функции выбора альтер-
натив равнялось рангу дерева выбора.
Рассмотрим построение СА выбора для полного дерева выбора.
Пример 1.3. Пусть необходимо оpганизовать выбоp из четырёх
альтернатив, используя полное дерево и таблицу альтернатив.
В этом случае достаточно двух условий В1 и В2 (В1 и В2 - булевы
переменные), пpичём на втором ранге условия одинаковы; каждой паре из
значений 0 (false) и 1 (true) этих условий можно сопоставить свою
альтернативу Ni - см. табл. 1.1, колонка А. Этой таблице соответствует
фpагмент СА, показанный на pис.1.5; здесь рядом с номеpами альтеp-
натив указаны их коды (двоичные представления).

Таблица 1.1
B1 B2 A
0 0 N1
0 1 N2
1 0 N3
1 1 N4

Рассмотрим построение СА выбора при неполном дереве выбора.


Пример 1.4. Пусть задана логическая функция выбора вида С=В1В2,
где В1 и В2 - логические условия (В1, В2 – булевы переменные) и  -

21
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

опеpация логического сложения по mod2. Заполним таблицу истинности для


функции С (табл. 1.2); здесь в колонке для С проставлены её логические
значения F (false) и T (true), определяющие выбоp из двух путей (альтеpнатив),
по котоpым pазветвляется СА для заданной функции. Таким образом, табл. 1.2
представляет собой таблицу альтернатив. На pис.1.6 пpиведён фрагмент схемы
алгоритма, построенный в соответствии с табл. 1.2, пpичём все пути, имеющие
одинаковое логическое значение, объединены.

Таблица 1.2

B1 B2 C
0 0 F
0 1 T
1 0 T
1 1 F

Если в построенной схеме име-


ется изображённый на pис. 1.7,а
фpагмент, то булева пеpеменная Вi в
нём склеивается, т. е. BiVBi =1; это
означает, что условный блок на уча-
стке a-b не нужен, и его можно заме-
нить отpезком пpямой (рис 1.7,б).

Аналогично заполняется таблица истинности (если она не задана) и


по ней стpоится схема алгоритма выбора, если задан составной опеpатоp
как логическая функция n аpгументов; на каждом pанге, начиная со
второго, пpоводится объединение путей, выбоp котоpых имеет одина-
ковые логические значения.

22
О.Н. Паулин. Основы теории алгоритмов

Пример 1.5. Пусть выбор из трёх альтернатив N1, N2, N3 опреде-


ляется тремя простыми условиями (булевыми переменными) В1, B2, В3 в
соответствии с табл. 1.3. Требуется синтезировать СА для блока выбора.
Перестроим табл. 1.3, введя для каждой альтернативы свою колонку,
~ ~ ~ отмечается единицей тот факт,
в которой для выбранного набора B1B2B3
что альтернатива реализуется, а прочерком - что не реализуется (табл. 1.4).

B1 B2 B3 C B1 B2 B3 N1 N2 N3
0 0 0 N1 0 0 0 1 -- --
0 0 1 N2 0 0 1 -- 1 --
0 1 0 N1 0 1 0 1 -- --
0 1 1 N3 0 1 1 -- -- 1
1 0 0 N3 1 0 0 -- -- 1
1 0 1 N3 1 0 1 -- -- 1
1 1 0 N3 1 1 0 -- -- 1
1 1 1 N3 1 1 1 -- -- 1

На рис. 1.8,а приведена начальная схема алгоритма выбора, а на


рис. 1.8,б показана минимизированная СА выбора; рядом с каждым
альтернативным выходом в скобках записаны соответствующие им коды
~ ~ ~ ; X - безразличное значение).
(значения двоичных наборов B1B2B3

23
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

В данном примере упрощения фрагментов СА выбора могут быть


получены чисто схемным путём. Действительно, участок a-b может быть
заменен прямой (см. рис. 1.7), а участки c-d, c-e, c-в можно преобра-
зовать с учётом законов дистрибутивности и коммутативности как для
переменных, так и для соответствующих им условных блоков. Имеем
__ __ __ __
участок c-d – B2 & B3 B2 & B3  B3& (B2  B2)  B3 ;

участок c-e – B2 & B3  B3 & B2 ;

участок c-в – В2&B3 = B3&B2.

Рассмотрим общие вопросы ор-


ганизации разветвлений в СА. Под
термином организация разветвле-
ний понимается такое построение
схемы (блока) выбора альтернатив,
которое адекватно отображает исход-
ное задание, и при этом имеет мини-
мальное булево выражение в смысле
цены по Квайну. Исходная инфор-

24
О.Н. Паулин. Основы теории алгоритмов

мация о сложном выборе в некоторой задаче должна быть представлена таблицей


альтернатив (ТА).

В общем случае построения СА выбора заданы m альтернатив N1...Nm


~ ~
и n булевых переменных B1...Bn. Каждому набору B1...B n соответствует
своя альтернатива, что может быть представлено в виде ТА. Перестроим ТА
таким образом, чтобы каждой альтернативе соответствовала своя колонка, в
~ ~
кото-рой для выбранного набора B1...B n отмечается 1 - альтернатива
реали-зуется, а прочерком - не реализуется. Тогда Ni (i=1, m ) можно считать
выходными переменными схемы выбора, а саму таблицу можно рассматри-
вать как таблицу истинности для системы m функций от n булевых перемен-
ных; минимизировав такую систему [5], можно построить СА выбора.
В ТА в столбце альтернатив могут быть одинаковые альтернативы (одна
~ ~
и та же альтернатива реализуется при нескольких наборах B1...B n ) или
про-черки (не все альтернативы используются). В первом случае можно
объеди-нить конечные узлы дерева. Второй случай соответствует неполному
дереву выбора (m<2r); ТА в этом случае может быть доопределена исходя
из дополнительных соображений. В обоих случаях надо минимизировать
логи-ческие выражения и реализующие их схемы алгоритмов.

На рис. 1.9 приведены фрагменты СА для условных операторов вида


а) if <условие> then S (на схеме условие сокращённо обозначено I);
б) if <условие> then S1 else S2 (на схеме - I);
в) case N of 1: S1; 2: S2; ... k: Sk end (на схеме - C).
Здесь Si – произвольный оператор; он может быть пустым либо
составным, т. е. включать в себя последовательность операторов, в том
числе условный оператор.

25
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Для простых случаев выбора достаточно использовать условные операторы


if (рис. 1.9,а и б). В более сложных случаях Pascal предоставляет мощное средство
– оператор-переключатель case .. of (рис. 1.9,в); аналогичное средство (switch)
имеется и в языке C.
В заключение запишем фрагмент программы для минимизированной
СА выбора (пример 1.5). Переход от схемы выбора (рис. 1.8,б) к условному
оператору case N of несложен: каждой альтернативе ставится в соответствие

свой десятичный номер (слева направо в СА выбора), затем по кодам


альтернатив записываются логические формулы, которые вписываются в
качестве условий в условные операторы, и формируются операторы присваи-
вания параметру N соответствующего десятичного номера; далее следует
(возможно, после операторов общего вида) оператор case N of.
Таким образом, фрагмент программы для примера 1.5 имеет вид
begin
if (NOT B1) AND (NOT B3) then N:=1 else
if (NOT B1) AND (NOT B2) AND B3 then N:=2 else N:=3;
case N of
1: S1;

26
О.Н. Паулин. Основы теории алгоритмов

2: S2;
3: S3
end
end.
Важно отметить, что к моменту вычисления N должны быть опре-
делены значения B1, B2, B3.

27
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

1.2. Циклы в алгоритмах

Цикл - многократное повторение некоторого фрагмента алгоритма;


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

1.2.1. Примеры циклических алгоритмов


Рассмотрим несколько примеров циклических алгоритмов.
Пример 1.6. Дано множество чисел A={a1, a2, … , an}. Требуется
найти минимальный элемент этого множества.
Такого pода сложная опеpация может быть оформлена в виде
процедуры. Она часто встpечается как составная часть некотоpого
алгоpитма (программы), например, при сортировке чисел по убыванию.
Назовём её MIN_A (минимальный элемент множества А). Пpоцедуpа
MIN_A основана на операции определения минимального элемента для
пары чисел, ai и aj, что реализуется при их сравнении: ai<aj  с=min(ai, aj).
При сравнении возможны 2 исхода:

ai при ai  aj
c  
 .
a j при
 ai aj

(1.10)
Процедура MIN_A может быть наглядно представлена как упорядо-
чивание предметов по убыванию их тяжести с помощью рычажных весов
(рис. 1.10,а) методом сравнения тяжести предмета с минимальным весом (с),
полученным на предыдущем взвешивании, и очередного предмета (аi +1).
Вычислительный процесс для процедуры MIN_A состоит в следу-
ющем. Пpосматpиваем элементы множества А слева напpаво, выделяем
пару элементов, начиная с первых двух, и сpавниваем их. Каждый pаз по-
сле сpавнения на пpавую позицию ставится минимальный элемент паpы;

28
О.Н. Паулин. Основы теории алгоритмов

при этом, возможно, возникнет необходимость перестановки (инверсии)


элементов. Новая паpа обpазуется из минимального и следующего эле-
ментов множества (pис 1.10,б). Пpоцесс продолжается до тех поp, пока
минимальный элемент не окажется на последнем месте справа в обра-
ботанном множестве А.

Приведем словесное описание алгоpитма, представленное по шагам


вычислительного пpоцесса.
1. Начало.
2. Ввод множества А.
3. В качестве минимального элемента принимаем первый элемент
множества A.
4. Обpазуем новую паpу: к минимальному элементу пpедыдущей
паpы пpиписываем следующий элемент множества.
5. Сpавниваем элементы. Если левый элемент паpы (lel) меньше
пpавого (rel), то меняем их местами (это - операция инверсии элементов,
invel) с помощью вспомогательной переменной t (рис. 1.10,в), иначе
оставляем их на месте.
6. В качестве минимального элемента принимаем правый элемент пары.
7. Если не все элементы множества обpаботаны, то пеpеходим к п. 4.

29
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

8. Последний элемент обpаботанного множества будет его мини-


мальным элементом (minel; эта переменная введена для удобства при
использовании данной процедуры в другой программе).
9. Конец.
По словесному описанию процедуры MIN_A составим её схему
алгоритма (рис. 1.11,а). Здесь пунктиром выделены блоки нахождения
минимального элемента MINEL (тело цикла) и организации цикла.
Запишем для процедуры MIN_A программу на Pascal в упрощённом
варианте (не объявлены типы данных; не расписан ввод множества А и
вывод переменной minel).
Процедура MIN_A.
1. Начало.
2. Ввод массива А.
3. i:=1; (* начальное значение паpаметpа цикла *)
4. c:=A[1];
5. М: lel:=с; rel:=A[i+1]; (* образование паpы *)
6. if lel<rel then (t:=lel; lel:=rel; rel:=t); (*инверсия элементов - invel*)
7. c:=rel; (* выделение минимального элемента в паpе*)
8. i:=i+1; (* новое значение паpаметpа цикла *)
9. if i<n then goto M; (* пpодолжить pаботу ?*)
10. minel:=с; (* минимальный элемент множества А*)
11. Вывод minel.
12. Конец.
Отметим, что при практическом программировании нет необходи-
мости в столь подробных комментариях.
Другой способ оpганизации цикла показан на pис.1.11,б. Здесь MINEL
- предопределённый вычислительный процесс, оформленный в виде про-

30
О.Н. Паулин. Основы теории алгоритмов

цедуры - см. рис. 1.11,а. В блоке MINEL выполняется макрооперация,


состоящая из следующих операций: образование пары элементов; сравне-
ние элементов; выбор варианта продолжения вычислительного процесса
(производить либо нет инверсию элементов); выделение минимального
элемента.

31
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Пpимеp 1.7. Даны две матpицы А и В pазмеpностью d(A)=d(B)=[mn].


Найти их сумму С=А+В.
Известно [5], что пpи суммиpовании матpиц элементы pезультиpу-
ющей матрицы вычисляются по правилу: элемент матрицы С, имеющий
пару индексов (i, j), pавен сумме элементов матpиц А и В, имеющих те же
пары индексов, т. е.

cij  aij  bij , (i  1, m; j  1, n). (1.11)

Пpи этом матpица С имеет также pазмеpность d(C)= [mn]:


c11 c12 ... c1n a 11 a 12 ... a 1n b11 b12 ... b1n
c 21 c 22 ... c 2n a a 22 ... a 2n b b 22 ... b 2n
 21  21 (1.12)
: : c ij : : : a ij : : : b ij :
c m1 c m2 , , , c mn a m1 a m2 ... a mn b m1 b m2 ... b mn

Суммиpование элементов можно провести двумя способами: по


стpокам или столбцам. Рассмотpим первый ваpиант. Идея вычислительного
процесса пpоста: выбиpаем некотоpую стpоку матpицы (фиксиpуем её номеp
i), и, пеpебиpая все её позиции с первой до последней включительно
(изменяем номер j столбца от 1 до n), пpоводим суммирование элементов aij и
bij . Затем увеличиваем номеp стpоки на 1 и повтоpяем пpоцедуpу
суммиpования элементов стpоки; эти действия повтоpяются до тех поp, пока
не будут пеpебpаны все m стpок.
Таким обpазом, процесс суммирования матриц содержит 2 цикла:
а) пеpебоp стpок (i  1, m );

б) пеpебоp элементов строки ( j  1, n ).

Поскольку цикл (а) включает в себя цикл (б), то говоpят, что цикл (б)
вложен в цикл (а); цикл (а) называют внешним, а цикл (б) - внутpенним.
Переменные i и j являются паpаметpами цикла (в данном случае i -
паpаметp внешнего, а j - внутpеннего цикла).

32
О.Н. Паулин. Основы теории алгоритмов

В соответствии с идеей работы алгоpитма суммирования двух мат-


pиц составим его схему (pис. 1.12,а; пунктиром выделен внутренний цикл).

На рис. 1.12,б представлен сжатый вариант СА; здесь пунктиром


выделен внешний цикл, причём телом этого цикла является оператор j:=0,
и внутрений цикл, который в данном представлении можно рассматривать
как предопределённый процесс.

Пpимеp 1.8. Постpоить СА умножения двух матpиц А и В.

33
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Пpавило, по котоpому опpеделяются элементы pезультиpующей


матpицы С, С=АxВ, описывается фоpмулой [ 5 ]
m
c ij   a il b lj , i  1, n, j  1, k . (1.13)
l 1

Пpи этом pазмеpности d матpиц должны быть согласованы (# -


операция согласования размерностей):
d(A) # d(B) = d(C) (1.14)
[n x m]#[m x k]=[n x k],
т.е. количество столбцов матрицы А должно быть равно количеству строк
матрицы В; в результате перемножения матриц количество строк матрицы
С равно количеству строк матрицы А, а количество столбцов матрицы С
равно количеству столбцов матрицы В.
Отметим, что из рассмотрения правила (1.13) следует, что в общем
случае операция перемножения матриц некоммутативна, т.е. АВ  ВА.
Реализация формулы (1.13) для умножения матриц показана на рис. 1.13.
В алгоритме перемножения матриц А и В можно выделить два
ключевых момента:
 вычисление отдельного элемента результирующей
матрицы С;
 упорядоченный перебор всех элементов матрицы С.
Вычисление отдельного элемента сij, по (1.13) осуществляют в соот-
ветствии со схемой рис. 1.13,а:
 фиксируются i-я строка матрицы А и j-й столбец матрицы
В;
 перебираются пары элементов (один из строки матрицы А, другой из
столбца матрицы В), и элементы каждой пары с одинаковыми индексами l
( l  1, m ) перемножаются;
 результаты перемножения суммируются.

34
О.Н. Паулин. Основы теории алгоритмов

Для организации процедуры вычисления всех элементов матрицы С её


сканируют (рис. 1.13,б):
 фиксируется i-я строка матрицы А, перебираются все столбцы
( j  1, k ) матрицы В, и вычисляются все элементы i-й строки матрицы С по
схеме, описанной выше;
 переходят к (i+1)-й строке матрицы А и повторяют
предыдущий пункт;
 так поступают до тех пор, пока не будут перебраны все строки
(i  1, n ) матрицы А.

СА перемножения двух матриц, построенная на основе приведенного


выше описания организации вычислительного процесса, представлена на
рис. 1.14. Здесь используются изображения по ЕСПД [17] блоков, обозна-
чающих начало и конец цикла с соответствующими именами.

35
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Отметим, что в цикле по l сумму целесообразно вычислять с помощью


оператора d:=d+A[i,l]*B[l,j], и лишь после выхода из цикла осуществить
переобозначение С[i,j]:=d. Это даёт
возможность экономить время обра-
щения к памяти, поскольку в самом
цикле работают с переменной d, а
не с элементом матрицы С, адрес
которого каждый раз надо было бы
снова вычислять.

СА содержит три цикла (по


параметрам i, j, l), причём
вложенность циклов такова: по l –
внутренний цикл, по j - внутренний
относительно цикла по i, но
внешний относительно цикла по l,
по i - внешний цикл; циклы по i и j
обеспечивают сканирование матрицы С, а в цикле по l происходит
вычисление элементов матрицы С по (1.13).
Как и в предыдущем примере, СА перемножения можно представить
с разной степенью подробности; так, циклы по l и j можно представить
предопределённым процессом (телом цикла по i).

36
О.Н. Паулин. Основы теории алгоритмов

1.2.2. Общие вопросы организации циклов

Выше были рассмотрены примеры циклических алгоритмов, которые


часто встречаются в практике. Прежде чем перейти к особенностям орга-
низации циклических процессов, рассмотрим ещё один типичный пример.
Пример 1.9. Пусть СП вычисления EXP в нашем распоряжении нет,
и нам самим требуется составить соответствующий алгоритм. Запишем
разложение exp(-x) в ряд Тейлора, ограничившись n-м членом:
x 2 x3 x n xi
exp( x)  1  x    ...  (1) n  1   (1) i  (1.15)
2! 3! n! i 1 i!

Обозначим hi общий член ряда:


xi
hi  (1) i  (1.16)
i!

Тогда ряд (1.15) может быть представлен выражением


n
exp( x )  S  1   hi  (1.17)
i 1

Вычисления hi можно проводить двояко:


 непосредственно по (1.16);
 используя рекуррентную связь между значениями h, индексы которых
отличаются на единицу.
В первом случае необходимо для каждого следующего члена ряда
проводить все вычисления как для степени, так и для факториала; во
втором случае вычисления проводятся с использованием предыдущих
результатов по формуле
x
hi   hi 1 . (1.18)
i

Ясно, что второй способ более рациональный.


При вычислении суммы ряда (1.17) также более рационально
использовать предыдущие результаты:
S i  S i 1  hi , (1.19)

37
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

где Si - значение частичной суммы членов ряда с 1-го по i-й включительно.


Нетрудно видеть, что при определении значения y=exp(-x) для
конкретного значения x=x0 достаточно организовать один цикл, в котором
объединить вычисления значений hi и Si.
В общем случае представления функции рядом она может быть
записана как
n
yn =  q i x ,
i
(1.20)
i 0

где qi - коэффициенты разложения функции в ряд.


При вычислении значений рядов возможны два варианта организации
вычислительного процесса (точнее, определения момента его окончания):
 n задано или известно в результате анализа погрешности ряда
(константа n – исходное данное). Чаще всего это бывает, если опреде-
ляется значение функции для одного конкретного значения x=x0 или
небольшого числа мало отличающихся (в том смысле, что для них n не
изменяется) значений x. Тогда организуются циклические вычисления,
которые заканчиваются при достижении параметром i цикла значения n;
 n заранее неизвестно, однако задана допустимая погрешность , и
циклический процесс заканчивается по условию выполнения неравенства
yn+1-yn  , (1.21)
или
Rn(x)  , (1.22)
где Rn(x) - остаточный член ряда (константа Rn вычисляется заранее).
В примере 1.9 ряд является знакопеременным, поэтому [4] погрешность
ряда не превышает значения первого отброшенного его члена, равного
n x n 1
Rn(x)  (1) . (1.23)
( n  1)!

Вычислительный процесс организуется по-разному в случае вычис-


ления у=f(x) для конкретного значения x=x0 и для некоторого множества

38
О.Н. Паулин. Основы теории алгоритмов

значений xi (например, необходимо построить график у=f(x), ахв). В пер-


вом случае вычисление выполняется однократно и потому нет необходи-
мости в дополнительной организации вычислительного процесса; во
втором случае необходимо организовать циклический перебор всех
значений xi, используя номера i-x точек на оси ОХ при неравномерном
разбиении отрезка [a, b] либо приращение по х,
ba
x  , (1.24)
k
при равномерном разбиении на к интервалов (к - известно), и тогда
xi = a + i*x. (1.25)
Отметим, что полином Qn(x) может быть записан аналогично (1.20).
Однако ряд и полином существенно отличаются: ряд имеет общий член,
так как коэффициенты ряда вычисляются по определённому закону, а у
полинома коэффициенты могут быть произвольными, поэтому у него
может отсутствовать общий член. Вопрос определения n для полинома
должен решаться отдельно в каждом конкретном случае.
Итак, видно, что циклический процесс заканчивается по-разному, в
зависимости от того, известно либо нет число повторений в цикле: в
первом случае цикл заканчивается, если вычисления в теле цикла прове-
дены для всех значений параметра цикла, а во втором - если выполнено
условие завершения цикла.
Стандартные способы построения циклов в программировании –
использование конструкций for, while <условие> do <оператор>, repeat
<оператор> until <условие> (рис. 1.15).
Оператор for имеет внутренний счётчик в обоих вариантах реали-
зации (Iнач, Iкон - целые константы):
for I:= Iнач to Iкон do <оператор> - счёт в прямом направлении;
for I:= Iкон downto Iнач do <оператор> - счёт в обратном направлении.

39
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Здесь изменение параметра цикла происходит на 1 по умолчанию; в


некоторых языках программирования используется явное указание на шаг
(step) приращения I.
Применять оператор for целесообразно при известном числе
повторений в цикле.
На рис. 1.15,а и б приведены фрагменты СА для оператора for;
здесь S1, S2 - тело цикла.
Запишем фрагмент программы примера 1.6 (строки 3-9) с использо-
ванием оператора for (здесь invel(lel, rel) - процедура инверсии элементов):
с:=А[1];
for i:=1 to n-1 do
begin
lel:=c; rel:=A[i+1];
if lel<rel then invel(lel,rel);
c:=rel
end;
minel:=c;
Этот же фрагмент можно упростить, исключив процедуру invel и
соответственно переменные lel и rel (на каждом шаге запоминается мини-
мальное значение с пары элементов):
c:=A[1];
for i:=2 to n do
begin
if ca[i] then c:=a[i]; (*текущий минимальный элемент*)
end;
minel:=c;
Реализация операторов while...do и repeat...until в виде СА
приведена на рис. 1.15,в и г. Смысл этих операторов заключается в

40
О.Н. Паулин. Основы теории алгоритмов

следующем: для первого - пока выполняется условие W, делать S1, S2,...,


а для второго - повторять S1, S2,..., пока не выполнится условие U. Раз-
личие этих условных операторов заключается в том, что при организации
одного и того же вычислительного процесса (S1; S2;..., Sn) условия W и U
____
должны быть противоположны, U= W ; кроме того, во втором случае
после-
довательность операторов выполняется по меньшей мере один раз. Дос-
тоинством этих операторов является то, что можно строить циклические
алгоритмы с заранее неизвестным числом итераций (повторений) в цикле.

Эти операторы можно использовать и при известном числе повторе-


ний; при этом в теле цикла должен быть предусмотрен счётчик, а усло-
вием выхода из цикла будет его конечное значение.
Операторы while...do и repeat...until так же, как и оператор if, соз-
дают простое разветвление, но в отличие от операторов if они предназ-

41
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

начены для многократного выполнения одного и того же вычислительного


процесса (S1;S2;...Sn).
Отметим, что организация цикла на рис. 1.11 соответствует опера-
тору repeat..until для первого варианта СА и оператору while..do - для
второго (в обоих вариантах со встроенным счётчиком).
Под термином организация цикла понимается правильное выпол-
нение начала цикла, его завершения и собственно тела цикла.
При организации начала цикла надо обеспечить точное определе-
ние начальных значений локальных переменных и параметра цикла,
согласование данного цикла с предыдущим фрагментом алгоритма по
глобальным переменным и т. д.
При продумывании реализации тела цикла необходимо понять, ка-
кие операторы не зависят от параметра цикла, и вынести их из цикла либо
обозначить простой переменной, что сократит время выполнения алго-
ритма. Если переменная X[I], зависящая от параметра цикла I, встре-
чается в теле цикла более двух раз, то имеет смысл переобозначить её
(например, Y:=X[I]), с тем чтобы не тратить время (кроме первого раза!) на
вычисление адреса этой переменной в оперативной памяти; при выходе
из итерации (цикла) следует вернуться к старому обозначению. Важно
обнаружить и использовать рекуррентные связи между переменными.
При организации завершения цикла необходимо решить вопрос о
том, каким должен быть выход из цикла (когда и как: с использованием
предусловия или постусловия)? При этом должно быть гарантировано, что
для встроенного счётчика все итерации имеют место. Установить, что
выход из цикла осуществляется с нужными значениями параметра цикла.
Разобраться, с какими значениями переменных циклический алгоритм
заканчивает работу, точнее, надо так организовать цикл, чтобы это были
нужные для следующего фрагмента СА значения.

42
О.Н. Паулин. Основы теории алгоритмов

Стыковка вложенных циклов предполагает передачу переменных и


параметров, их переобозначение, вспомогательные вычисления (напри-
мер, начальных значений параметров внутреннего цикла) и т. д.
Ошибки в организации цикла связаны обычно с неправильным
выполнением начала цикла или его конца; именно этим моментам и
следует уделить особое внимание.
Обычно для проверки правильности организации цикла рассмат-
ривают вычислительный процесс по шагам, каждому из которых соответ-
ствует своё значение параметра цикла; это можно сделать как на бумаге,
так и на компьютере. Операторы тела цикла выполняют пошагово, причём
в случае использования бумаги принимаются следующие упрощения:
малое число повторов, данные только целого типа, количество варьиру-
емых данных уменьшается до предела, после которого задача теряет
смысл, и т.п. Эти упрощения можно сделать при глубоком понимании сути
задачи. На рис. 1.11,в приведен образец анализа правильности организа-
ции цикла (верификация алгоритма).

43
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

1.3. Логические алгоритмы

Логическими принято называть алгоритмы, которые содержат пред-


писания (операции) относительно объектов нечисловой природы. Харак-
терной особенностью логических алгоритмов является выбор на каждом
шаге по определенным правилам альтернативной операции, осуществля-
емой при переходе к следующему шагу. К логическим задачам относят
многие игры. Однако выделение логических задач из множества математи-
ческих задач достаточно условно - в большинстве случаев задачи являются
смешанными: в них присутствуют и числовые, и логические операции. Так,
машинные алгоритмы игры в шахматы используют на каждом шаге вычис-
ление значения некоторой функции, учитывающей оценку позиции после
каждого следующего хода (точнее, полухода) и стоимость размена фигур.
Ниже рассматриваются две задачи, носящие выраженный логичес-
кий характер.

1.3.1. Задача “Поиск пути в лабиринте”

Эта задача восходит к греческой мифологии, в которой, в частности,


описывается подвиг Тезея, проникшего в лабиринт, где обитал чудовищный
Минотавр (полубык, получеловек), пожиравший местных красавиц. Тезей
разыскал в лабиринте Минотавра и убил его. Выбраться из лабиринта ему
помогла Ариадна (А), дав ему вначале клубок ниток, один конец которых
держала она сама. По мере углубления Тезея в лабиринт клубок разматы-
вался; наматывая потом нитки, Тезей благополучно вернулся к выходу.
Рассмотрим задачу поиска пути в лабиринте в общем случае (для
класса подобных задач) и приведём словесное описание алгоритма.

44
О.Н. Паулин. Основы теории алгоритмов

Представим лабиринт в виде конечной системы площадок, от кото-


рых расходятся коридоры, причём каждый коридор соединяет две площад-
ки (будем называть их смежными); возможно существование таких пло-
щадок, из которых можно пройти только в один коридор (такие площадки
будем называть тупиками). Геометрически лабиринт можно представить в
виде системы точек А, В, С, ..., изображающих площадки, и совокупности
отрезков АВ, ВС, ..., изображающих коридоры, которые соединяют опре-
делённые пары данных точек (рис. 1.16). Смежными являются, например,
площадки В и С, К и М и т. д., а тупиковыми - площадки А, D, I, J.

Рис. 1.16. Геометрическое представление лабиринта

Будем говорить, что площадка Y достижима из площадки X, если


существует путь от X к Y через промежуточные коридоры и площадки. Точ-
нее: либо X и Y - смежные площадки, либо существует последователь-
ность площадок X1, X2, ..., Xn таких, что X и X1, X1 и Х2 ... , и т.д., и, нако-
нец, Xn и Y являются смежными. Отметим, что если Y достижима из X, то
она достижима и посредством простого пути, т.е. такого пути, в котором
каждая площадка (а тем более и каждый коридор) проходится лишь один
раз. Например, путь ABCD является простым, а путь ABCFECD - нет.

45
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Тезей должен был решить задачу: узнать, достижима ли площадка М,


на которой находится Минотавр, из площадки А, на которой находится
Ариадна, или нет? Если да, то к М можно было добраться по любому пути,
но вернуться к площадке А нужно уже по простому пути. Поскольку
заранее устройство лабиринта неизвестно, решение задачи должно быть
представлено в виде общего метода поиска для любого лабиринта и при
любом расположении площадок А и М, т. е. требуется построить алгоритм
поиска пути в лабиринте.
Будем условно помечать коридоры следующими красками: непрой-
денные ни разу - зелёной, пройденные один раз - жёлтой, пройденные
дважды - красной.
Находясь на начальной площадке, Тезей может попасть на одну из
смежных площадок посредством одного из следующих двух ходов:
1. Разматывание нити. Прохождение от данной площадки по любому
зелёному коридору до смежной площадки. После прохождения этого
коридора он считается жёлтым.
2. Наматывание нити. Возвращение от данной площадки по послед-
нему пройденному жёлтому коридору до смежной площадки. При этом
нить наматывается обратно на клубок, а этот коридор становится красным.
Предполагается, что Тезей делает какие-то пометки, позволяющие
ему впоследствии отличать красные коридоры от зёленых; жёлтые разли-
чимы тем, что по ним протянута нить Ариадны .
Обстановка на данной площадке характеризуется такими призна-
ками.
1. Минотавр. Он обнаружен.
2. Петля. Через данную площадку уже протянута нить Ариадны (иначе:
от данной площадки расходятся по крайней мере два жёлтых коридора).

46
О.Н. Паулин. Основы теории алгоритмов

3. Зелёная улица. От данной площадки есть вход по крайней мере в


один зелёный коридор.
4. Ариадна. Она на данной площадке.
5. Особый случай. Отсутствие всех предыдущих признаков (например
тупик).
Поставим в соответствие каждой обстановке на площадке свой ход.
Признак Ход
1. Минотавр Остановка
2. Петля Наматывание нити
3. Зеленая улица Разматывание нити
4. Ариадна Остановка
5. Особый случай Наматыване нити

Находясь на некоторой площадке, Тезей делает очередной ход


следующим образом: он проверяет по порядку номеров в соответствии с
левым столбцом таблицы, какой из перечисленных признаков имеет
место; обнаружив первый такой признак, он (уже не проверяя остальные
признаки) делает соответствующий ход из правого столбца. Такие ходы
делаются до тех пор, пока не наступит остановка.
Приведём (без доказательства) утверждения, которые являются
обоснованием предложенного метода поиска пути в лабиринте.
1. При любом расположении А и М в лабиринте после конечного числа
ходов обязательно наступит остановка либо на площадке Минотавра, либо
на площадке Ариадны.
2. Если остановка наступила на М, то Минотавр достижим. Более
того, в этом случае нить Ариадны оказывается протянутой по простому
пути, ведущему от А к М. Наматывая нить, Тезей может теперь вернуться
по этому пути к Ариадне.

47
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

3. Если остановка наступила на площадке Ариадны, то Минотавр не


достижим.
Отметим, что в случае признака “зелёной улицы” ход не определён
однозначно - нарушается свойство детерминированности алгоритма. Этот
случай легко исправляется, если ввести дополнительное правило о том,
что при наличии нескольких зелёных коридоров Тезей обходит площадку
по часовой (против часовой) стрелке, выбирая очередной коридор. Ясно,
что в общем случае алгоритм основан на переборе вариантов обхода
площадок и коридоров.

1.3.2. Задача “Ханойские башни”

Эта задача формулируется следующим образом. Имеется три стерж-


ня, на одном из которых (назовём его занятым) находятся диски разных
диаметров, расположенные на стержне в порядке убывания диаметров
снизу вверх; второй стержень назовём свободным, а третий - вспомога-
тельным (рис 1.17). Требуется, производя одиночные перемещения
дисков, переместить всю “стопку” дисков с занятого стержня на свобод-
ный, используя вспомогательный стержень; при этом на любом шаге
диски должны быть расположены на каждом стержне в порядке убывания
их диаметров.

Рис. 1.17. Ханойские башни

48
О.Н. Паулин. Основы теории алгоритмов

В табл. 1.5 приведен результат решения задачи для случая четырех


дисков. Здесь А - занятый в начальный момент (нулевой шаг) стержень, В
- свободный, а С - вспомогательный стержень. Цифрами обозначен
“номер” диска, причём большему номеру соответствует больший диаметр.
Отметим, что в середине процесса решения в качестве вспомогательного
выступает то стержень А, то стержень С.
Видно, что процесс перемещения стопки дисков можно разбить на
фазы (1-я фаза - шаги 1-8; 2-я фаза - шаги 9-12; 3-я фаза - шаги 13 и 14;
4-я фаза - шаг 15). К началу каждой фазы на вспомогательном (занятом)
стержне собирается стопка дисков (в табл. 1.5 номера этих дисков
подчёркнуты), затем в течение данной фазы самый нижний диск стопки
перемещается на свободный стержень
Таблица 1.5.

Ша 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

г
А 4-1 4-2 4,3 4,3 4 4,1 4,1 4   2 2,1 2,1 2  
В   2 2,1 2,1 2   4 4,1 4,1 4 4,3 4,3 4-2 4-1
С  1 1  3 3 3,2 3-1 3-1 3,2 3 3  1 1 

Анализ перемещений дисков позволяет выявить определённые зако-


номерности, составить словесное описание алгоритма перемещений для
общего случая (количество дисков произвольно), а затем перейти к разра-
ботке схемы алгоритма.
Чтобы переместить самый нижний диск на стержень В, необходимо
2n-1 перемещений. Общее число перемещений равно 2n-1.
Эти утверждения можно доказать по индукции.

Заключение

49
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

Любой вычислительный процесс может быть представлен компо-


зицией следующих его фрагментов: линейный, ветвящийся, циклический.
Для организации разветвлений и циклов могут быть использованы
различные операторы; выбор того или иного оператора в конкретном
случае остаётся за программистом.
При организации разветвлений необходимо стремиться миними-
зировать логическое выражение, описывающее выбор альтернатив.
При организации циклов особенно важны два момента: правиль-ное
построение начала цикла и его конца. Важно также обеспечить стыковку
цикла с остальной частью алгоритма или циклов друг с другом при их
вложенности.
СА может быть представлена с разной степенью подробности. Так,
предопределённый процесс, например блок ввода/вывода, может вклю-
чать в себя несколько циклов; визуально фрагмент СА, включающий в
себя этот блок, будет выглядеть линейным. В действительности линей-
ными могут быть только очень простые алгоритмы или их некоторые
фрагменты.
СА допускают эквивалентные преобразования, что может быть
использовано для повышения эффективности алгоритмов. Например,
имеет смысл выносить, если это возможно, из тела цикла все операторы,
не связанные с параметром данного цикла.
Необходимо повышенное внимание уделять особым случаям,
которые встречаются в данных либо в формулах (например, в алгоритме
нахождения минимального числа множества - это случай, когда входное
множество содержит один элемент либо оно пустое; при некоторых
вычислениях возникает необходимость деления на 0 и т.п.).

Контрольные вопросы. Упражнения

50
О.Н. Паулин. Основы теории алгоритмов

1. Какие соединения вершин СА являются допустимыми?


Предло-жите несколько вариантов произвольных СА, содержащих 8...10
вершин разных типов.
2. Вы сможете доказать, что каждый из рассмотренных в данной
главе вычислительных процессов является алгоритмом?
3. Как надо скорректировать СА решения квадратного уравнения
(рис 1.4), чтобы при преобразовании уравнения общего вида (1.7) к
приведённому учесть случай а = 0 (при этом вычисление p и q связано с
делением на 0, что недопустимо)?
4. Как изменится СА для процедуры MIN_A (пример 1.7), которая
встроена в некий вычислительный процесс (модуль), если при обращении
к этой процедуре возможны случаи, когда сформированный в основном
процессе массив А содержит всего один элемент либо пуст?
5. Каким требованиям должны удовлетворять размерности матриц
A, B и C, чтобы корректно выполнить матричную операцию D = A + BхC?
Сколько циклов понадобится для вычисления матрицы D?
6. Почему некоммутативна в общем случае операция перемножения
двух квадратных матриц одинаковой размерности? В каком частном
случае коммутативность имеет место?
7. Составьте фрагменты СА для формул (1.16) ... (1.19) и сравните
попарно фрагменты для формул (1.16), (1.18) и (1.17), (1.19). В каком
случае вычисления рациональнее и почему?
8. В чём отличие вариантов с использованием от вариантов без
использования оператора case ... of? Рассмотрите эти варианты для
примера 1.5.
9. Чем отличаются операторы for, while…do, repeat…until?

51
Глава 1. ПРОСТЕЙШИЕ АЛГОРИТМЫ И ВЫЧИСЛИТЕЛЬНЫЕ ПРОЦЕССЫ

10. Постройте схему алгоритма выбора, реализующую логическую


__
функцию C  B1VB2 & B3 , где B1, B2, B3 - некотоpые условия (булевы
переменные).
__
Указание. Ввести промежуточную переменную Z  B2 & B3 .

11. Постройте СА, реализующую предикат p(x)ax<b.


Указание. Учесть, что предикат включает в себя 2 условия.
12. Составьте СА определения максимального элемента множества,
содержащего 12 чисел. Какое количество сравнений и перестановок эле-
ментов понадобится в случае, если массив отсортирован в порядке возра-
стания элементов? Выведите формулу для определения количества срав-
нений и перестановок в случае произвольного количества элементов.
13. Составьте словесное описание алгоритма перемножения двух
матриц.
14. Для функции y=F(x), представленной разложением в ряд (1.20),
постройте схему алгоритма, позволяющего вычислить значение y в точках

разбиения с погрешностью  при равномерном разбиении области опре-


деления функции [a,b] на m частей.
15. Составьте СА поиска пути в лабиринте.
16. Докажите, что в задаче “Ханойские башни” для перемещения n-го
(самого нижнего) диска на свободный стержень необходимо 2 n-1 одиночных
перемещений. Докажите также, что общее число перемещений на свобод-
ный диск определяется числом 2n-1.

52

Оценить