5.3. Euclides extendido.

El algoritmo de Euclides no sólo sirve para encontrar el máximo común divisor de dos números, sino que también nos indica que el mcd se puede expresar como combinación lineal de los mismos. Además, el mcd es el menor entero positivo en que estos dos números se pueden usar como combinación lineal. Lo que buscamos con el algoritmo extendido de Euclides, son los coeficientes de esta combinación lineal.

Esta propiedad resulta de gran utilidad, sobre todo al momento de resolver ecuaciones Diofantinas (ecuaciones de la forma ax + by = c, donde todos son enteros y a, b y c son constantes).

Otra aplicación útil es que cuando a y b son primos relativos (por lo que c = 1), entonces x es el inverso multiplicativo de a módulo b. Por ejemplo, para 5x + 3y = 1, una solución es 5(-1) + 3(2) = 1, y tenemos que 5(-1) ≡ 1 mod 3 y 3(2) ≡ 1 mod 5.

Para encontrar los valores de x e y, consideremos lo siguiente. Expresando el mcd como combinación lineal de las entradas, implica que c = mcd:
mcd(a,b) = ax + by
También sabemos que:
mcd(a,b) = mcd(b, a mod b)
Si hacemos que a1 = a, b1 = b, a2 = b y b2 = (a mod b) = a -bk, donde k es entero, entonces:
mcd(a1, b1) = mcd(a2, b2)
Reemplazando en la primera ecuación tenemos:
mcd(a1, b1) = a1x1 + b1y1
mcd(a2, b2) = a2x2 + b2y2

mcd(an, bn) = anxn + bnyn

Si hacemos mcd(a,b) = d, y suponiendo que tenemos dos iteraciones además de los valores de x e y para la segunda (x2, y2):
mcd(a1, b1) = a1x1 + b1y1 = d
mcd(a2, b2) = a2x2 + b2y2 = d

Sabemos que a2 = b1, b2 = a1 -b1k y k = , por lo que:
d = a1x1 + b1y1
d = a2x2 + b2y2 = b1x2 + (a1 -b1k)y2

Uniendo las dos ecuaciones:
a1x1 + b1y1 = b1x2 + (a1 -b1k)y2
= a1y2 + b1(x2 -ky2)

Lo anterior se cumple si:
x1 = y2
y y1 = x2 -ky2 = x2 - y2

Con esto, podemos calcular los valores de x e y en base a lo anteriores. Ahora sólo necesitamos obtener cuales son los valores iniciales.

Sabemos que en la última iteración an = d y bn = 0, entonces nos queda que:
mcd(an, bn) = anxn + bnyn
d = dxn + 0yn
xn = 1, yn = 0


Problema ejemplo


El Problema de Euclides

Problema
Gracias a Euclides es conocido que para cualquier par de enteros positivos a y b, existen dos enteros x e y tales que ax + by = d, donde d es el máximo común divisor de a y b. El problema es encontrar para una pareja a y b dada, los x, y y d correspondientes.

Entrada
La entrada consistirá en un conjunto de líneas, cada una con un par a y b, separados por un espacio (a, b < 1 000 000 001).

Salida
Para cada línea de entrada, la salida consistirá en los tres enteros x, y y d, separados por un espacio. Si existen varios x e y que cumplan, deberás obtener la pareja para la cual |x| + |y| es mínimo (criterio principal) y xy (criterio secundario).

Solución: Aplicando el algoritmo extendido de Euclides podemos encontrar una solución. Tomando a los valores que arroja el algoritmo de Euclides como x0 e y0, y a t como una variable entera, las demás soluciones las podemos calcular a partir de la anterior, utilizando la siguiente fórmula:
d = a(x0 + t) + b(y0 - t)
Por lo que los valores de x e y son de la forma:
x = x0 + t
y = y0 - t

Además sí sabemos que la gráfica de la ecuación f(t) = |x = x0 + t| + |y = y0 - t| está compuesta por tres rectas, las cuales forman algo semejante a una V. Por lo que en caso de que existan valores enteros más pequeños que f(0), los podemos obtener ya sea incrementando o decrementado t.


Código


En las primeras dos líneas declaramos las variables que vamos a utilizar: leemos la entrada en a y b, y guardamos el resultado en x, y y d, con lo que utilizamos la misma notación que la que maneja el problema.

Entre las líneas 4 y 15 tenemos la versión extendida del algoritmo de Euclides. Para poder hacer que la función devuelva tres valores, hacemos un procedimiento en el que tres de los parámetros puedan ser modificadas (esto es, pasamos las variables por referencia, en lugar de por valor; en Pascal escribimos var antes de declararlas). Las líneas 8 y 11 son similares a las del algoritmo convencional, sólo que añadimos los valores iniciales de x y y en la línea 8, y en la línea 11 incluimos x, y y d como parámetros. En las líneas 12 y 13 calculamos los nuevos valores de x y y, respaldando primero los valores en x1 y y1. Es importante notar que los valores de x y y los calculamos después de mandar llamar la función.

La parte principal del programa lo encontramos entre las líneas 17 y 34. Lo que hacemos en esta parte del código es leer a y b, mandar llamar el algoritmo extendido de Euclides, buscar hacia los dos lados de la gráfica por soluciones más pequeñas e imprimir los resultados, todo esto mientras no lleguemos al fin de archivo.


Casos ejemplo

Entrada: 25 58
Desarrollo: mcd(25,58) = mcd(58, 25 mod 58)
mcd(58,25) = mcd(25, 58 mod 25)
mcd(25, 8) = mcd( 8, 25 mod  8)
mcd( 8, 1) = mcd( 1,  8 mod  1)
mcd( 1, 0) = 1

       x=  1, y=  0
 8  1; x=  0, y=  1 –( 8/ 1)×0 = 1, d= 1
25  8; x=  1, y=  0 –(25/ 8)×1 =-3, d= 1
58 25; x= -3, y=  1 –(58/25)×-3= 7, d= 1
25 58; x=  7, y= -3 –(25/58)×7 =-3, d= 1
Salida: 7 –3 1

Entrada: 4 6
Desarrollo: mcd( 4, 6)= mcd( 6, 4 mod 6)
mcd( 6, 4)= mcd( 4, 6 mod 4)
mcd( 4, 2)= mcd( 2, 4 mod 2)
mcd( 2, 0)= 2

     x=  1, y=  0
2 4; x=  0, y=  1 -(2/4)×0 = 1, d= 1
2 4; x=  1, y=  0 -(6/4)×1 =-1, d= 1

4 6; x= -1, y=  1 –(4/6)×-1= 1, d= 1
Salida: -1 1 2

Entrada: 17 17
Desarrollo: mcd(17,17) = mcd(17, 17 mod 17)
mcd(17, 0) = 17

       x=  1, y=  0
17 17; x=  0, y=  1 –(17/17)×0 = 1, d= 1
Salida: 0 1 17

Nota: En las operaciones de división, sólo se toma la parte entera (y esto aplica para el resto del capítulo).


Código en C


Tiempo de ejecución

Lenguaje Fecha Tiempos [s] Memoria [Kb]
Ejecución Mejor Mediana Peor
Pascal 13-Ene-2006 1.529 0.316 1.041 9.871 324
C 17-Feb-2006 0.734 388





© Pier Paolo Guillen Hernandez
World of πer