Псевдокод расширенного алгоритма Евклида:

НА ВХОДЕ: два неотрицательных числа $%a$% и $%b$%: $%a\geq b$%
НА ВЫХОДЕ: $%d=НОД(a,b)$% и целые $%x$%, $%y$%: $%ax + by = d$%.

  1. Если $%b=0$% положить $%d:=a$%, $%x:=1$%, $%y:=0$% и возвратить ($%d,x,y$%).
  2. Положить $%x_2:=1$%, $%x_1:=0$%, $%y_2:=0$%, $%y_1:=1$%.
  3. Пока $%b>0$%:
    3.1. $%q:=[a/b]$%, $%r:=a-qb$%, $%x:=x_2-qx_1$%, $%y:=y_2-qy_1$%;
    3.2. $%a:=b$%, $%b:=r$%, $%x_2:=x_1$%, $%x_1:=x$%, $%y_2:=y_1$%, $%y_1:=y$%.
  4. Положить $%d:=a$%, $%x:=x_2$%, $%y:=y_2$% и возвратить ($%d,x,y$%).

А что такое "с усеченными остатками" какой алгоритм? Никак не пойму. Спасибо.

------------------------Правка---------------------- На C# набросал программу которая реализовывает "Расширенный алгоритм Евклида с усеченными остатками"

 static void ras_o(BigInteger a, BigInteger b)
        {
            if (b == 0)
            {
                Console.WriteLine("d = " + a + " x = " + 1 + " y = " + 0);
                return;
            }
            BigInteger r = 0, x2 = 1, x1 = 0, y2 = 0, y1 = 1, x = 0, y = 0, count = 0;
            while (b > 0)
            {
                BigInteger q = BigInteger.Abs(a / b);
                if(q>b/2) q = b - q;
                r = a - q * b;
                x = x2 - q * x1; y = y2 - q * y1;
                a = b; b = r; x2 = x1; x1 = x; y2 = y1; y1 = y;
                count++;
            }
            Console.WriteLine("d = " + a + " x = " + x2 + " y = " + y2 + " s = " + count );
        }

Но проблема в том что у него количество итераций равно количеству итераций с обычным "Расширенный алгоритм Евклида", может я опять что то не понял? вроди все ок добавил if(q>b/2) q = b - q;

задан 5 Ноя '14 13:10

изменен 9 Ноя '14 23:55

@asddsa: это просто кто-то неудачный термин использовал. Здесь везде речь идёт о самых обычных остатках, что видно из алгоритма. Когда мы делим, скажем, 100 на 7, то мы несколько раз "усекаем" 100 на 7, получая остаток. Но вот кто и зачем придумал такой новый термин для остатка, назвав его "усечённым", этого я не могу "усечь" :)

Кстати, откуда сам этот текст и терминология?

(5 Ноя '14 19:28) falcao

@asddsa: к сожалению, я не понимаю этой терминологии. Давайте говорить в стандартных терминах. У нас есть два натуральных числа $%a$%, $%b$%. Есть теорема о делении с остатком согласно которой существуют и единственны целые $%q$%, $%r$%, для которых $%a=bq+r$% и $%0\le r < b$%. Они называются соответственно (неполным) частным и остатком от деления $%a$% на $%b$%. Легко видеть, что $%q=[a/b]$%, то есть целой части обычного (полного) частного. Обычно мы его находим, деля числа "в столбик", но можно делать это при помощи команд типа div. Зная $%q$%, выражаем $%r=a-bq$%. Этого достаточно.

(5 Ноя '14 20:54) falcao

@falcao http://oi58.tinypic.com/2d29aaw.jpg вот, в разделе другие алгоритмы, описан данный способ, но, к сожалению, так и не понял.

(9 Ноя '14 10:59) asddsa

@asddsa: в том отрывке, на который Вы ссылаетесь, есть несколько замечаний чисто обзорного характера, и их можно не анализировать. А одна из модификаций алгоритма там описана достаточно чётко. А именно, если у меня при делении $%a$% на $%b$% получилось в остатке $%r$%, где $%r > b/2$%, то удобно заменить $%r$% на $%r'=b-r$% по той причине, что $%b-r < b/2$%, и алгоритм станет работать быстрее. Это довольно простая идея; в программе её можно реализовать добавлением одного условного оператора.

(9 Ноя '14 13:23) falcao

@asddsa: у Вас там делается не то, что нужно. Вы заменяете частное, которое в дальнейшем вообще не участвует, а остаток у Вас остаётся прежним. Понятно, что число шагов не меняется. По смыслу надо делать другое. Например, если я считаю НОД для 21 и 13, то в обычном случае будет (13,8), (8,5), (5,3), (3,2), (2,1). А при ускоренном алгоритме будет (13,5), (5,2), (2,1).

Условие там r>b/2, и полагать надо r:=b-r в этом случае.

(10 Ноя '14 0:31) falcao
10|600 символов нужно символов осталось
0

Если можно, добавьте в ответы:

    if (b == 0)
            {
Console.WriteLine("a = " + a + " x = " + 1 + " y = " + 0);
return;
}
BigInteger r = 0, x2 = 1, x1 = 0, y2 = 0, y1 = 1, x = 0, y = 0, count = 0;
while (b > 0)
{
   BigInteger q = BigInteger.Abs(a / b);
   r = a - q * b;
   if (r > b / 2) r = b - r;
   x = x2 - q * x1; y = y2 - q * y1;
   a = b; b = r; x2 = x1; x1 = x; y2 = y1; y1 = y;
   count++;
            }
  Console.WriteLine("a = " + a + "\nb = " + b + "\nx = " + x2 + "\ny = " + y2 + "\ns = " + count); вдруг кому пригодится, код на C#
ссылка

отвечен 19 Ноя '14 0:39

изменен 21 Ноя '14 23:11

%D0%92%D0%B8%D1%82%D0%B0%D0%BB%D0%B8%D0%BD%D0%B0's gravatar image


9917

@falcao есть одна помарка, у нас тут НОД это число "а", но при расчете коэффициентов X и Y тоже надо как то учитывать их при условии r > b/2.? Иначе у меня при умножении ax + by <> НОД.

(22 Ноя '14 12:54) asddsa

@asddsa: нахождение множителей -- это отдельная задача. Вообще, это довольно естественно делается в обратном порядке. По идее, надо запоминать промежуточные числа, и тогда это просто. Если не запоминать, то формулы перехода там тоже можно выписать, но они более "хитрые". Мне вникать в текст программы не хочется, но я могу всё как бы "с нуля" объяснить -- это проще.

(22 Ноя '14 17:06) falcao

@falcao понял, спасибо, хочу еще помучится. :) Отпишусь, если получится. :)

(23 Ноя '14 14:24) asddsa

@falcao, извиняюсь, но я не смог рассчитать множители. (

(23 Ноя '14 17:45) asddsa
10|600 символов нужно символов осталось
Ваш ответ

Если вы не нашли ответ, задайте вопрос.

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

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

Присоединяйтесь!

отмечен:

×105
×15

задан
5 Ноя '14 13:10

показан
3850 раз

обновлен
23 Ноя '14 17:45

Отслеживать вопрос

по почте:

Зарегистрировавшись, вы сможете подписаться на любые обновления

по RSS:

Ответы

Ответы и Комментарии

Дизайн сайта/логотип © «Сеть Знаний». Контент распространяется под лицензией cc by-sa 3.0 с обязательным указанием авторства.
Рейтинг@Mail.ru