Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 [ 123 ] 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

обратном порядке обхода дерева; в то же время этот символ обозначает последователя узла Р при симметричном порядке обхода бинарного дерева.

В качестве примера .использования этих методов для решения практических задач рассмотрим некоторые операции с алгебраическими формулами. Такие формулы лучше всего представлять в виде древовидных структур, а не как одно- или двумерные конфигурации символов, и даже не как бинарные деревья. Например, формулу у = 31п{х -I-1) - а/х можно представить в виде дерева таким образом.


0<-...............

©-

в левой части рисунка показано обычное дерево, подобное представленному на рис. 21, в котором бинарные операторы -, х, / и t (последний символ обозначает возведение в степень) имеют по два поддерева, соответствующих их операндам. Унарный оператор In имеет одно поддерево, а переменные и константы являются концевыми узлами. В правой части рисунка показано эквивалентное правопрошитое бинарное дерево, включающее дополнительный узел у, который является заголовком списка этого дерева. Заголовок списка имеет вид, представленный условиями 2.3.Н8).

Важно отметить, что, хотя дерево, показанное в левой части (7), внешне очень похоже на бинарное дерево, здесь оно рассматривается как обычное дерево и представлено в виде совершенно иного бинарного дерева, чем то, которое показано в правой части (7). Программы для выполнения алгебраических операций можно было бы создать непосредственно на основе бинарных деревьев, т. е. на основе так называемого трехадресного кода (three-address code) представления алгебраических формул. Однако на практике при использовании древовидного представления алгебраических формул применяются некоторые упрощения, подобно представлениям (7), поскольку обход дерева в обратном порядке выполняется проще в обычном дереве.

При обходе узлов дерева в левой части (7) получим

-x3 1n-fxl/at2;2 для прямого порядка; (8)

3 3;l--lnxa3;2t/ - Для обратного порядка. (9)

Алгебраические выражения наподобие (8) и (9) имеют очень большое значение и называются польской системой обозначений, так как в виде (8) она впервые была



использована польским логиком Яном Лукасевичем (Jan Lukasiewicz). Выражение (8) является префиксным обозначением {prefix notation) формулы (7), а выражение (9) - ее постфиксным.бозначением {postfix notation). В следующих главах эта система обозначений будет рассмотрена подробнее, а здесь лишь отметим, что польская систе.ма обозначений непосредственно связана с основными способами обхода деревьев.

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

RTAG

RLINK

TYPE

LLINK

(10)

Здесь поля RLINK и LLINK имеют обычное значение, а значение поля RTAG является отрицательным для связей-нитей (что соответствует RTAG = 1 в выражениях алгоритма). Поле TYPE используется для того, чтобы можно было различать узлы разных типов. Например, TYPE = О означает, что узел представляет константу, а поле INFO содержит ее значение; TYPE = 1 означает, что узел представляет переменную, а поле INFO содержит ее пятибуквенное имя; TYPE > 2 означает, что узел представляет оператор, а поле INFO содержит символьное имя этого оператора, т. е. значения TYPE = 2, 3, 4, ... используются для обозначения операторов +, -, X, / и т. д. Здесь нас меньше всего будет интересовать вопрос, как древовидная структура представлена в памяти компьютера, поскольку эта тема очень подробно анализируется в главе 10. Предположим лишь, что дерево уже размещено в памяти компьютера, и отложим на потом все вопросы, связанные с операциями ввода и вьшода.

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

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

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

D{x)

(11)

D{a)

= 0, где a - константа или переменная ф х

(12)

D(lnu)

= D{u)/u, где и - любая формула

(13)

D{~u)

= -D{u)

(14)

D{u + v)

= D{u) + D{v)

(15)

D{u-v)

= D{u) - D{v)

(16)

D{u X v)

- D{u) X V + u X D{v)

(17)



D{u I v) = D{u)lv -{их D{v))/{v t 2) (18)

D{u t w) = D{u) X (u 5; (u t (г - 1))) + ((Ь и) x D{v)) x (u t г) (19)

Эти правила позволяют оцбнить производную D{y) для любой формулы у, состоящей из перечисленных выше операторов. Знак "-" в правиле (14) является унарным оператором, который отличается от бинарного оператора "-" в (16). Далее для обозначения унарного отрицания в узлах деревьев будет использоваться обозначение "neg".

К сожалению, правил (11)-(19) недостаточно, так как, применив их вслепую для очень простой формулы

у = 3\п{х +1) - а/х, получим правильный, но совершенно неудобный для дальнейшей работы результат:

D{y) = О • \п{х + 1) + 3((1 + 0)/{х + 1))

- (0/х2 - (а(1(2х2-) + ((1пх) • 0)х))/{хУ). (20)

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

D{y) = 3(1/(х + 1)) - {{-{а{2х)))/{х)). (21)

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

D{y) = 3{x + 1)- +2ах-\ (22)

Здесь мы ограничимся описанием программ, с помощью которых можно получить результат в виде формулы (21), а не (22).

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

Основная идея такого алгоритма заключается в обходе дерева в обратном порядке с вычислением производной каждого посещаемого узла до тех пор, пока не будет вычислена производная всего выражения. Использование обратного порядка обхода означает, что узел оператора (например, "-Ь") посещается после того, как буд>т продифференцированы его операнды. Правила (И)-(19) подразумевают, что



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 [ 123 ] 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225