Опубликован: 16.09.2005 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 5:

Построение цикла с помощью инварианта

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

Быстрое возведение в степень

Второй важнейший алгоритм элементарной теории чисел - это алгоритм быстрого возведения в степень. Наряду с алгоритмом Евклида, он встречается буквально на каждом шагу, когда речь идет о применении теории чисел в программировании, - например, в теории кодирования.

Пусть требуется возвести элемент a в целую неотрицательную степень n. В качестве a может фигурировать целое или вещественное число, квадратная матрица, элемент кольца вычетов по модулю m и т.п. - требуется только, чтобы элемент a принадлежал алгебраической структуре, в которой определена ассоциативная операция умножения (т.е. в общем случае, a - элемент полугруппы).

Идея алгоритма состоит в том, чтобы возвести a в произвольную степень, применяя элементарные операции возведения в квадрат и умножения.

В качестве фазового пространства X этой задачи рассмотрим множество троек

X = {(b,k,p)}.

Здесь b выступает в роли текущего основания степени, k - в роли текущего показателя степени, p - это уже вычисленная часть степени. Ключевым моментом всегда является формулировка инварианта цикла:

I(b,k,p): bk*p = an = const,

т.е. величина bk*p постоянна и равна an. Легко подобрать начальные значения так, чтобы инвариант выполнялся:

b0 = a;  k0 = n;  p0 = 1.
I(b0,k0,p0) = I(a,n,1): an*1 = an

Условие завершения совместно с выполнением инварианта должно обеспечить легкое решение требуемой задачи, т.е. вычисление an. Действительно, если k = 0, то из инварианта следует, что

b0*p = p = an,

т.е. искомая величина содержится в переменной p. Итак, условие завершения состоит в равенстве нулю числа k:

Q(b,k,p): k = 0

Осталось написать преобразование T точки x = (b,k,p), которое сохраняет инвариант и одновременно уменьшает k. Определим преобразование T следующим образом:

T(b,k,p) = (b*b, k/2, p),     если k четное
T(b,k,p) = (b, k-1, p*b),   если k нечетное

Легко видеть, что инвариант сохраняется и k монотонно убывает. Итак, выпишем алгоритм быстрого возведения в степень для случая вещественного основания:

вещ алг. быстрое возведение в степень(вх: вещ a, цел n)
| дано: основание a и показатель степени n >= 0
| надо: вычислить a в степени n
начало алгоритма
| вещ b, p; цел k;
|
| // инициализация
| b := a; p := 1.0; k := n;
| утверждение: b^k * p == a^n;
|
| цикл пока k > 0
| | инвариант: b^k * p == a^n;
| | если k четное
| | | то
| | |   k := k / 2;
| | |   b := b * b;
| | | иначе
| | |   k := k - 1;
| | |   p := p * b;
| | конец если
| конец цикла
|
| утверждение: k == 0 и b^k * p == a^n;
| ответ := p;
конец алгоритма
< Лекция 4 || Лекция 5: 123456 || Лекция 6 >
Кирилл Юлаев
Кирилл Юлаев
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Данила Некрасов
Данила Некрасов
Россия, Пермь, ПНИПУ
Сергей Федоров
Сергей Федоров
Россия