Главная  Длительная эволюция 

[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]

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

Оказывается, „Математика" последовательно применяла основное правило, понижая значение аргумента до тех пор, пока не пришла к отдельно определенным начальным значениям fib[l] и /гЬ[2], а затем проводила вычисления для возрастающих значений аргумента. При таком порядке вычислений нахождение fib[5] или fib[7] выполняется совершенно аналогично, так как значения функции fib[n] не запоминаются. Можно исправить это положение вещей, прибегнув к так называемому „динамическому программированию". Это достигается следующим изменением данных ранее правил.

factdyn[n Integer?Positive] := factdyn[n] = nfactdyn[n - 1] factdyn[l] = 1;

Теперь все вычисляемые значения функции factdyn будут запоминаться.

factdyn[5] 120

Сравним время вычисления 100! обеими функциями.

{fact[lOO]; Timing,factdyn[100]; Timing}

{{0.22Second, Null}, {0.6l5econd, Null}}

Время, затраченное второй функцией, существенно больше. А теперь для числа 110! сравним вновь время его вычисления обеими функциями.

{fact[110]; Timing,factdyn[llO]; Timing} {{0.27 Second, Null}, {O.llSecond, Null}}



Результат достаточно убедителен. Экономия времени в случае применения функции factdyn достигнута за счет того, что значение factdyn[lOO] сохранено в программе.

С понятием опций, т.е. необязательно явно указываемых аргументов функций, мы познакомились в гл. 3 при изучении встроенных графических функций. Там опциональные аргументы указывали директивы, регулирующие представление графического объекта. В „Математике" имеются два способа определять функции с опциями. Первый основан на использовании именованных шаблонов х : v со значениями по умолчанию равными и; второй - на использовании функции Options и локальных правил преобразований.

Рассмотрим эти способы на примере. Допустим, что при работе со списками нам часто требуется разбивать элементы списков на пары с отступом 1, и мы пользуемся для этого функцией Partition, указывая в качестве ее второго аргумента число 2, а в качестве третьего - число 1. Чтобы сэкономить время, определим функцию pairs, позволяющую не указывать явно числа 2 и 1. Сделаем это упомянутыми двумя способами:

pairs[x List,n : 2,m : 1] := Partition[x,n,m] pairs[{a,b,c,d}]

{{a,b},{b,c},{c,d}}

Функцией pairs, учитывая ее определение, можно пользоваться так же, как и функцией Partition, указывая явно один или два ее необязательных аргумента. Следует помнить, что если будет указан один аргумент, то он будет воспринят как второй аргумент функции pairs. Пусть, например, требуется разбить список на тройки с отступом 1. Воспользуемся функцией pairs следующим образом:

pairs[{a,b,c,d},3] {{a,b,c},{6,c,d}}



Если же требуется разбить список на пары с отступом два, то следует вычислить выражение:

pairs[{a,b,c,d},2,2] {{a,6},{c,d}}

Второй способ реализуется следующим образом:

Clear [pairs]

Options[pairs] = {optl -> 2,opt2 -> 1}

{орЙ-2,ор«2-> 1}

pairs[x -List,opts ] := Partition[x,optl /.

{opts} /. Options[pairs],opt2 /. {opts} /. Options[pairs]]

pairs[{a,b,c,d}]

{{a,6},{b,c},{c,d}}

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

pairs[{a,b,c,d,},optl -¥ 3]

{{a,b,c},{b,c,d}}

6.4. Шаблоны в локальных правилах преобразований

Приемы программирования, рассматриваемые в этом параграфе, являются, на наш взгляд, одними из самых интересных, неожиданных и эффективных из используемых в „Математике". Можно надеяться, что с течением времени программы в стиле локальных преобразований займут ведущее место в приложениях. Локальные правила содержат подстановки вида exprl ехрг2 и exprl :> ехрг2, где exprl может содержать шаблоны. Подстановки осуществляются с помощью функций



[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]

0.0008