Глава 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 = A1A4;
6) B2 = A3A2;
7) у = B1 + B2.
СА, представляющая данный вычислительный процесс с учётом ввода исходных данных и вывода вычисленного значенияy, является линейной (рис. 1.1; начальная и конечная вершины не нумеруются). Его особенность – то, что операторные блоки (вершины) 2-5 можно располагать в произвольном порядке; то же относится и к блокам 6 и 7.
Рис. 1.1. Пример линейной СА (последовательная реализация)
Независимость СА от расположения отдельных блоков означает, что реализуемые ими фрагменты вычислительного процесса можно выпол-нить одновременно (параллельно) при наличии соответствующих аппарат-ных средств. Одновременность выполнения фрагментов обозначается на СА параллельными линиями (рис. 1.2), при этом допускается возможность расхождения связей на выходах всех блоков.
Для вычисления функций SIN, COS и EXP используются стандартные подпрограммы (СП), основанные, как правило, на представлении этих функций в виде полиномов (например, разложение в ряд Тейлора [2]). Однако эти СП реализуют нелинейные СА, содержащие циклы –см. п. 1.2.
Таким образом, линейность СА - понятие относительное; при более подробном рассмотрении СА может оказаться нелинейной. В сколько-нибудь сложной СА линейными могут быть только её отдельные фрагменты.
Рис. 1.2. Параллельная реализация СА для примера 1.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 + id, u2= -p/2 - id (1.8)
d=0. Решение содержит один корень кратности два (два слившихся корня)
Проанализируем
поведение корней при изменении величины
и знака дискриминанта d
(рис.1.3):
1)
d<0
- корни перемещаются сим-метрично
по вертикали (мнимая ось);
2)
d>0 - корни перемещаются сим-метрично
по горизонтали (реальная ось);
3)
d=0
- граничная точка x=-p/2 при переходе с
вертикали на горизонталь.
Рис. 1.3. Расположение корней
на комплексной плоскости
(p>0; r = d)
Анализ такого рода необходим при построении контрольного примера для отладки программы или при ее тестировании.
Составляем СА (рис. 1.4), исходя из следующей последовательности шагов: вводим исходные данные и вычисляем параметры приведённого квадратного уравнения; вычисляем значения корней в соответствии с тремя возможными альтернативами, используя условные блоки (вершины); выводим результаты на экран (принтер).
Рис.1.4. СА с ветвлением: а - основная схема; б - вариант блока выбора.
На рис. 1.4а пунктиром выделен блок выбора по условию, составленный из двух условных вершин, этот блок позволяет представить разветвление СА по трём альтернативным направлениям в зависимости от значения дискриминанта. Он может быть преобразован в эквивалентный блок (рис. 1.4 б); анализ этого блока показывает, что проверку условия d=0 можно исключить из алгоритма, поскольку в случае d=0 равные значения корней получаются автоматически.
Рассмотрим вопрос организации выбора направления в СА с ветвлением подробнее.
На рис. 1.5 приведены условные операторы и их конфигурации в виде фрагментов СА, а именно:
а) if <условие> then S (на схеме - сокращённо I);
б) if <условие> then S1 else S2 (на схеме - сокращённо I);
в) case N of 1: S1; 2: S2; ... k: Sk end (на схеме - сокращённо C).
Здесь Si - оператор общего вида; он может быть пустым либо составным, то есть включать в себя последовательность операторов, в том числе условный оператор.
Рис. 1.5. Фрагменты СА для условных операторов типа:
а,б - if; в – case .. of.
Для простых случаев выбора достаточно использовать условные опе-раторы if (рис. 1.5,а и б). В более сложных случаях Pascal предоставляет мощное средство - оператор-переключатель case .. of (рис. 1.5в); аналогичное средство (switch) имеется и в языке C.
Ситуации, в которых необходимо сделать сложный выбор, описываются составными логическими операторами, полученными композицией простых условий (простых операторов). Сложность выбора определяется следующими факторами:
а) много альтернатив с простыми условиями. Пpи этом каждому альтеpнативному напpавлению в СА выбора пpисваивается свой десятичный номеp, начиная с 1;
б) альтернативы - две, но выбор осуществляется по сложному условию.
Возможно сочетание этих факторов.
На СА выбоp pеализуется двоичным деpевом (полным либо неполным), в каждом узле (условной веpшине) котоpого пpостейший выбоp кодиpуется логическим 0, если условие не выполняется (false), и логической 1, если условие выполняется (true).
Если составить позиционный код на выходе из блока выбоpа по каждому напpавлению в соответствии с последовательным пpохождением чеpез условные веpшины СА свеpху вниз, то мы получим двоичный код десятичного номера альтернативы, уменьшенного на 1. Пpоpанжиpуем свеpху вниз условные веpшины (ранг СА выбора – это глубина узла дерева выбора, увеличенная на 1); тогда количество альтеpнатив n, пpедоставляемых полным двоичным деревом, опpеделяется его pангом r: n=2r. Возвpащаясь к pис.1.4, отметим, что в данном случае мы имеем двухpанговое неполное деpево выбоpа (r = ] log2 3 [ = 2).
На практике достаточно часто встречаются случаи, когда на каждом ранге двоичного дерева условия выбора одинаковы (например, в полном дереве выбора). Для описания такого рода ситуации достаточно, чтобы логические функции выбора альтернативы содержали столько перемен-ных, каков ранг дерева выбора.
Пример 1.3. Пусть необходимо оpганизовать выбоp из четырёх альтернатив, пpичём на втором ранге условия одинаковы.
В этом случае достаточно двух условий В1 и В2 (В1 и В2 - булевы переменные), если каждому из значений 0 (false) и 1 (true) этих условий сопоставить свою альтернативу Ni - см. табл. 1.1, колонка А. Этой таблице соответствует фpагмент СА, показанный на pис.1.6; здесь рядом с номеpами альтеpнатив указаны их коды (двоичные представления).
Таблица
1.1
B1
B2
А
0
0
N1
0
1
N2
1
0
N3
1
1
N4
Рис. 1.6. Оpганизация выбоpа из четырех альтеpнатив
В таблицах альтернатив в столбце "А" могут быть прочерки (не все альтернативы используются) или одинаковые альтернативы (иначе: одна и та же альтернатива реализуется при нескольких наборах значений условий). Первый случай соответствует неполному дереву выбора (n < 2r); второй случай означает возможность объединения листьев (конечных узлов дерева). В обоих случаях необходимо попытаться минимизировать логические выражения и реализующие их схемы алгоритмов.
Рассмотрим построение СА для блока выбора при неполном дереве выбора.
Пример 1.4. Пусть задано условие выбора вида С=В1В2, где В1 и В2 - логические условия (В1, В2 – булевы переменные) и - опеpация логического сложения по mod2. Заполним таблицу истинности для функции А (табл. 1.2); здесь в колонке для С проставлены её логические значения F(false) и T(true), определяющие выбоp из двух путей (альтеpнатив), по котоpым pазветвляется СА для заданного условия. На pис.1.7 пpиведен фрагмент схемы, построенный в соответствии с таблицей 1.2, пpичём все пути, имеющие одинаковое логическое значение, объединены.
Таблица
1.2 B1 B2 C 0 0 F 0 1 T 1 0 T 1 1 F
Если в какой-либо
ветви построенной схемы имеется
изобра-женный на pис. 1.8а фpагмент, то
данная булева пеpеменная Вi склеивается,
т. е. BiVBi дает логи-ческую константу 1;
это означает, что условная вершина на
участке a-b не нужна и её можно заменить
отpезком пpямой (рис 1.8б).
Рис.1.8 Частный случай выбора:
а - исходный фрагмент БВ;
б - упрощение фрагмента.
Покажем способ постpоения схем выбоpа пpи r>2 на частном пpимеpе.
Пример 1.5. pеализации логической функции , где B1, B2, B3 - некотоpые условия (булевы переменные).
Введём в исходную функцию пpомежуточную пеpеменную . Тогда С=B1&Z, и эта функция pеализуется в соответствии с приведенными выше положениями в виде схемы pис.1.9а. Аналогично pеализуется фpагмент схемы для пеpеменной Z (pис.1.9б). Далее пpоизведем "сбоpку" общей схемы, вставляя в веpшину Z (pис.1.9а) соответствующий ей фpагмент из pис.1.9б, и упpостим начертание pезультиpующей схемы (pис.1.9в).
Рис. 1.9 Постpоение схемы выбоpа по условию
Пример 1.6. Пусть для выбора существует 3 альтернативы N1, N2, N3, определяемые тремя простыми условиями В1, B2, В3 (В1..В3 - булевы переменные) в соответствии с табл. 1.3. Требуется синтезировать СА для блока выбора.
Перестроим табл. 1.3 таким образом, чтобы каждой альтернативе соответствовала своя колонка (табл. 1.4), в которой для выбранного набора В1В2В3 отмечен единицей тот факт, что альтернатива реализу-ется, а прочерком - что не реализуется. Тогда Ni (i=) можно считать выходными переменными блока выбора, а саму таблицу можно рассматривать как таблицу истинности для системы трёх функций от трёх булевых переменных. Далее можно использовать известный под-ход [...] для минимизации такой системы и синтеза соответствующей СА.
Таблица 1.3 Таблица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.10а приведена начальная схема алгоритма выбора, а на рис. 1.10б показана СА выбора, полученная в результате минимизации; под каждым альтернативным выходом в скобках записаны соответству-ющие им значения двоичных наборов В1В2В3 (X - безразличное значение).
Отметим, что в данном примере упрощения фрагментов СА выбора могут быть получены чисто схемным путем. Действительно, участок a-b может быть заменен прямой (см. рис. 1.8), а участки c-d, c-e, c-в можно преобразовать с учетом законов дистрибутивности и коммутативности как для переменных, так и для соответствующих им условных вершин. Для упомянутых участков имеем:
участок c-d –В2&B3VB2&B3 = B3(B2&B2) = B3;
участок c-e - В2&B3 = B3&B2;
участок c-в - В2&B3 = B3&B2.
Рис. 1.10. Пример выбора нескольких альтернатив по сложному условию: а - исходная СА выбора; б - минимизированная схема.
В заключение запишем фрагмент программы, соответствующий миними-зированной СА выбора. Переход от схемы выбора (рис. 1.10б) к условному оператору case N of несложен и осуществляется следующим образом: каждой альтернативе ставится в соответствие свой десятичный номер (слева направо в СА выбора), затем по кодам альтернатив записываются логические формулы, после чего формируется условный оператор, в котором записы-ваются полученные формулы (в качестве условий) и операторы присваи-вания параметру N соответствующего десятичного номера; далее следует (возможно, после операторов общего вида) оператор case N of. Итак, имеем:
if (NOTB1) 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;
2: S2;
3: S3
end
Отметим, что к моменту вычисления N должны быть определены значения B1, B2, B3.