Descargar

Congruencias (página 2)

Enviado por Aladar Peter Santha


Partes: 1, 2

If rr(2) ="-0" then rr(2) = "0"

xx = rt(2)

Loop

ReDim s(mcd), rs(mcd)

s(1) = xx: i = "2"

If mcd <> "1" Then

Do

x(1) = i: x(2) = "1": j = Restar(x(), n)

x(1) = s(j): x(2) = mx: s(i) = Sumar(x(), n)

If i = mcd Then Exit Do

x(1) = i: x(2) = "1": i = Sumar(x(), n)

Loop

End If

i = "0": res = ""

Do

x(1) = i: x(2) = "1": j = Sumar(x(), n)

rs(i) = rs(j) + rc + "x(" + j + ") = " + s(j) + " + k*" + m

res = res + rs(i) + rc: i = j

If i = mcd Then Exit Do

Loop

Else

res = "¿No hay solución!"

End If

CongruenciasE = res

End Function

Ejemplo 7: Para hallar el elemento inverso edu.redhay que resolver la congruencia edu.redque tiene solución si y solamente edu.redson primos relativos. En este caso edu.redPor supuesto, primero hay que hallar el valor de edu.redcon la función de Euler. Por ejemplo, utilizando la función CongruenciasE, con los argumentos edu.reddonde edu.redson variables de tipo string, la solución de la congruencia edu.redes edu.redPor tanto, el elemento inverso de la clase edu.redes la claseedu.red

Ejemplo 8: Resolver la congruencia:

edu.red

Por los dos métodos anteriores se obtiene la solución: edu.red

Ejemplo 9: Resolver la congruencia:

edu.red

Los dos métodos anteriores dan el resultado siguiente:

edu.red; edu.red

edu.rededu.red

Cuando el módulo no tiene más que 8 dígitos, la longitud de los números a y b puede ser muy superior a la longitud del modulo y los dos programas siguientes seguirán funcionando con una velocidad aceptable.

Para resolver las congruencias de primer grado existe también el método de las fracciones continuas [9]. A continuación se considerarán las fracciones continuas finitas de la forma siguiente:

edu.red (6a)

, donde los números edu.redson números naturales. Las fracciones continuas edu.rededu.redse llaman reducidas de la fracción continua edu.redCada fracción continua y sus reducidas se pueden expresar en la forma de fracciones ordinarias. Si edu.red

, entonces edu.rededu.rededu.rededu.redy para calcular las reducidas siguientes se conocen las fórmulas de recurrencia siguientes:

edu.red (6b)

Se ha demostrado que:

edu.red (6c)

También se conoce que cada fracción ordinaria se puede desarrollar en una fracción continua finita, y que todas las reducidas son fracciones ordinarias irreducibles. Para resolver la congruencia Si se tiene que resolver la congruencia (2), se puede suponer que los números edu.redson primos relativos. Sea (6a) el desarrollo de la fracción ordinaria a/m en fración continua. Entonces, según la relación (6c) aplicada para edu.red, resulta que

edu.rededu.red

, es decir

edu.red

Así la congruencia (2) tiene las soluciones

edu.red (6d)

Ejemplo 10: En la congruencia edu.redel máximo común divisor de 6 y de 15 es 3, que divide al número 21. La congruencia equivalente es edu.redEl desarrollo en fracción continua de 2/5 es edu.redy así la solución es:

edu.red

En el caso cuando los coeficientes de la congruencia y los números que intervienen en el proceso de resolución pueden ser almacenados en variables de tipo Long se puede utilizar el el pgrama siguiente, basado en el método de las fracciones continuas.

Public Function MetodoFraC(ByVal a As Long, ByVal b As Long, ByVal m As Long) As String

Dim s() As Long, ax As Long, bx As Long, i As Long, k As Long, rr() As Long, d As Long

Dim x As Long, mcd As Long, mx As Long, rc As String, rs As String, t As Long

Dim p() As Long, q() As Long

If m < 1 Then

MetodoFraC = " El módulo tiene que ser un entero mayor que 1"

Exit Function

End If

rc = Chr$(13) + Chr$(10): mcd = MaxComDiv2(a, m)

x = b Mod mcd

If x = 0 Then

If mcd = 1 Then

ax = a: bx = b: mx = m

Else

ax = a / mcd: bx = b / mcd: mx = m / mcd

End If

If ax < 0 Then ax = -ax: bx = -bx

rr() = FraContFra(ax, mx)

d = UBound(rr())

ReDim p(d), q(d)

p(0) = rr(0): q(0) = 1

p(1) = rr(0) * rr(1) + 1: q(1) = rr(1)

For i = 2 To d

p(i) = rr(i) * p(i – 1) + p(i – 2)

q(i) = rr(i) * q(i – 1) + q(i – 2)

Next i

x = bx * q(d – 1)

t = (d + 1) Mod 2

If t = 1 Then x = -x

ReDim s(mcd)

x = x (mod mx)

s(1) = x

If s(1) < 0 Then

s(1) = s(1) + mx

End If

For i = 2 To mcd: s(i) = s(i – 1) + m: Next i

For i = 1 To mcd

rs = rs + rc + "x(" + Str$(i) + ") = " + Str$(s(i)) + " + k*" + Str$(m)

Next i

Else

rs = "No hay soluciones"

End If

MetodoFraC = rs

End Function

Public Function FraContFra(ByVal a0 As Long, ByVal b0 As Long) As Variant

"Desarrollo de una fracción ordinaria en fracción continua

Dim i As Long, j As Long, x As String, n As Long

Dim ax As Long, bx As Long, q0 As String, q() As Long

ax = Abs(a0): bx = Abs(b0)

Do

qx = Int(ax / bx): rx = ax – qx * bx

If rx <> 0 Then

i = i + 1

q0 = q0 + Str$(qx) + ","

ax = bx: bx = rx

Else

q0 = q0 + Str$(qx) + ","

i = i + 1

Exit Do

End If

Loop

d = i – 1: j = 0

ReDim q(d)

Do

For i = 1 To Len(q0)

x = Left$(q0, i)

If Right$(x, 1) = "," Then

q(j) = Val(Left$(x, Len(x) – 1))

q0 = Mid$(q0, i + 1)

Exit For

End If

Next i

If q0 = "" Then Exit Do

j = j + 1

Loop

FraContFra = q()

End Function

Esta función es utilizable si los coeficientes de la congruencia y los números que aparecen durante el cálculo pueden ser almacenados en variables de tipo Long.

Finalmente, si se utilizan las operaciones con números enteros largos el código anterior se puede transformar en un código "5 estrellas" para la resolución de las congruencias de primer grado, basado también en el método de las fracciones continuas. Esta vez, los números se almacenan en variables de tipo string y el tiempo necesario para la resolución es más que razonable. El programa siguiente (escrita en negrita) se puede utilizar siempre, incluso cuando las funciones "CongruenciasD" y "CongruenciasE" tardan demasiado tiempo en los cálculos.

Public Function MFrContCg(ByVal a As String, ByVal b As String, ByVal m As String) As String

Dim s() As String, ax As String, bx As String, i As Long, k As String

Dim xx As String, mcd As String, mx As String, rc As String, rs As String

Dim p() As String, q() As String, x(2) As String, fr() As String

Dim d As Long, t As Long, n As Integer, rr() As String, dif As String

n = 7: x(1) = m: x(2) = "1"

xx = Restar(x(), n)

If Left$(xx, 1) = "-" Or xx = "1" Then

MFrContCg = " El módulo tiene que ser un entero mayor que 1"

Exit Function

End If

rc = Chr$(13) + Chr$(10)

x(1) = a: x(2) = m

mcd = MaxComDiv(x(), n)

x(1) = b: x(2) = mcd

rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx = rr(2)

If xx = "0" Then

If mcd = "1" Then

ax = a: bx = b: mx = m

Else

x(2) = mcd

x(1) = a: rr() = DivisionEuclidea(x(), n): ax = rr(1)

x(1) = b: rr() = DivisionEuclidea(x(), n): bx = rr(1)

x(1) = m: rr() = DivisionEuclidea(x(), n): mx = rr(1)

End If

If Left$(ax, 1) = "-" Then

ax = Mid$(ax, 1)

If Left$(bx, 1) = "-" Then bx = Mid$(bx, 1) Else bx = "-" + bx

End If

fr() = FrContFrCg(ax, mx)

d = UBound(fr())

ReDim p(d), q(d)

p(0) = fr(0): q(0) = "1"

x(1) = fr(0): x(2) = fr(1)

x(1) = Multiplicar(x(), n): x(2) = "1"

p(1) = Sumar(x(), n): q(1) = fr(1)

For i = 2 To d

x(1) = fr(i): x(2) = p(i – 1)

x(1) = Multiplicar(x(), n): x(2) = p(i – 2)

p(i) = Sumar(x(), n)

x(1) = fr(i): x(2) = q(i – 1)

x(1) = Multiplicar(x(), n): x(2) = q(i – 2)

q(i) = Sumar(x(), n)

Next i

x(1) = bx: x(2) = q(d – 1)

xx = Multiplicar(x(), n)

t = (d + 1) Mod 2

If t = 1 Then

If Left$(xx, 1) = "-" Then xx = Mid$(xx, 1) Else xx = "-" + xx

End If

ReDim s(mcd)

s(1) = xx

x(1) = s(1): x(2) = mx: rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

s(1) = rr(2)

Do

If Left$(s(1), 1) = "-" Then

x(1) = s(1): x(2) = mx: s(1) = Sumar(x(), n)

Else

Exit Do

End If

Loop

If mcd <> "1" Then

k = "1"

Do

x(1) = k: x(2) = "1": k = Sumar(x(), n)

x(1) = s(k – 1): x(2) = mx: s(k) = Sumar(x(), n)

Loop Until k = mcd

End If

k = "0": rs = ""

Do

x(1) = k: x(2) = "1": k = Sumar(x(), n)

rs = rs + rc + "x(k) = " + s(k) + " + k*" + m

Loop Until k = mcd

Else

rs = "No hay soluciones"

End If

MFrContCg = rs

End Function

Public Function FrContFrCg(ByVal a0 As String, ByVal b0 As String) As Variant

" — Desarrollo de una fracción ordinaria en fracción continua, operando con enteros largos

Dim i As Long, j As Long, xx As String, n As Integer

Dim ax As String, bx As String, q0 As String, q() As String

Dim x(2) As String, rr() As String, d As Long

n = 7: i = 0

If Left$(a0, 1) = "-" Then ax = Mid$(a0, 1) Else ax = a0

If Left$(b0, 1) = "-" Then bx = Mid$(b0, 1) Else bx = b0

Do

x(1) = ax: x(2) = bx

rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

qx = rr(1): rx = rr(2)

i = i + 1

q0 = q0 + qx + ","

If rx <> "0" Then

ax = bx: bx = rx

Else

Exit Do

End If

Loop

d = i – 1: j = 0

ReDim q(d)

Do

For i = 1 To Len(q0)

xx = Left$(q0, i)

If Right$(xx, 1) = "," Then

q(j) = Left$(xx, Len(xx) – 1)

q0 = Mid$(q0, i + 1)

Exit For

End If

Next i

If q0 = "" Then Exit Do

j = j + 1

Loop

FrContFrCg = q()

End Function

Ejemplo 12: Utilizando el método anterior, resolver la congruencia siguiente:

edu.red

La solución es edu.redLa función "MetodoFrc" no podría resolver la congruencia puesto que su módulo no puede ser almacenado en variables de tipo Long. Los dos programas "CongruenciasD" o "CongruenciasE" probablemente tardarían mucho para dar este resultado.

Ejemplo 13: Resolver la congruencia siguiente:

edu.red

Según la función FrContFrCg, las soluciones son:

edu.red

§4. Resolución de congruencias de grado superior.

Las congruencias de grado superior tienen la forma siguiente:

edu.red (7)

, donde los coeficientes del polinomio son enteros y el modulo edu.redes un número natural mayor que 1. Las soluciones se buscan en el conjunto de los números enteros.

Hay que observar que si el máximo común divisor de los enteros edu.redno divide al coeficiente edu.redentonces la congruencia no tiene solución.

A continuación no se van a exponer los detalles de la teoría de este tipo de congruencias (se puede consultar la bibliografía). Se establecerán solamente programas en el lenguaje Visual-Basic, para hallar sus soluciones (cuando existen), utilizando el método directo, es decir seleccionando entre los números de 1 a edu.reda aquellos que son soluciones de la congruencia (7). Si edu.redes una solución de la congruencia (7), obviamente serán soluciones también todos los números naturales de la forma edu.red

Public Function CongrGrS(ByRef p() As Long, ByVal m As Long) As string

Dim i As Integer, j As Integer, k As Integer, gp As Integer, rs As String

Dim x As Long, y As Long, z As Long, r As Long, mcd As Long

Dim s0() As Long, p0() As Long

gp = UBound(p())

' Si el m.c.d. de los primeros gp-1 coeficientes y del módulo no divide al término libre, no hay solución

i = 0: x = Abs(p(0))

Do

i = i + 1

If i < gp Then y = Abs(p(i)) Else y = m

If y <> 0 Then

Do

If x < y Then z = x: x = y: y = z

r = x Mod y

If r = 0 Then Exit Do

x = y: y = r

Loop

x = y

End If

Loop While i <= gp – 1

mcd = y

y = p(gp) Mod mcd

If y = 0 Then

If mcd = 1 Then

m0 = m: p0() = p()

Else

m0 = m / mcd

ReDim p0(gp)

For i = 0 To gp

p0(i) = p(i) / mcd

Next i

End If

' ——— SOLUCIÓN ——————–

ReDim s0(m0)

For j = 0 To m0 – 1

x = 0

If j = 0 Then

x = p0(gp) Mod m0

Else

x = p0(0) Mod m0

For i = 1 To gp

x = x * j + p0(i)

x = x Mod m0

Next i

End If

If x = 0 Then

k = k + 1

s0(k) = j

End If

Next j

End If

If k <> 0 Then

For i = 1 To k

rs = rs + rc + "x(" + Str$(i) + ") = " + Str$(s0(i)) + " + k*" + Str$(k)

Next i

Else

rs = "No hay soluciones"

End If

CongrGrS = rs

End Function

Ejemplo 14: Según el programa anterior, las soluciones de la congruencia

edu.red

, son las siguientes: edu.redy edu.red

Sin embargo La función CongrGrS no sirve si los coeficientes del polinomio ó el modulo son enteros muy largos. Para estos casos hay que utilizar la función siguiente, que puede operar con enteros largos:

Public Function CongrGrSEG(ByRef p() As String, ByVal m As String) As String

Dim i As Integer, j As String, k As Integer, gp As Integer, rt As String, rr() As String, rs As string

Dim xx As String, yy As String, zz As String, r As String, mcd As String, dif As String, dif1 As String

Dim s0() As String, p0() As String, x(2) As String, m0 As String, n As Integer

n = 7: gp = UBound(p())

If Left$(p(0), 1) = "-" Then xx = Mid$(p(0), 2) Else xx = p(0)

' Si el m.c.d. de los primeros gp-1 coeficientes y del módulo no divide al término libre, no hay solución

i = 0

Do

i = i + 1

If i < gp Then

If Left$(p(i), 1) = "-" Then yy = Mid$(p(i), 2) Else yy = p(i)

Else

yy = m

End If

If yy <> "0" Then

Do

x(1) = xx: x(2) = yy: rt = Restar(x(), n)

If Left$(rt, 1) = "-" Then zz = xx: xx = yy: yy = zz

x(1) = xx: x(2) = yy: rr() = DivisionEuclidea(x(), n): r = rr(2)

If r ="-0" then r = "0"

If r = "0" Then Exit Do

xx = yy: yy = r

Loop

xx = yy

End If

Loop While i <= gp – 1

mcd = yy

x(1) = p(gp): x(2) = mcd: rr() = DivisionEuclidea(x(), n)

If rr(2) ="-0" then rr(2) = "0"

yy = rr(2)

If yy = "0" Then

If mcd = "1" Then

m0 = m: p0() = p()

Else

x(1) = m: x(2) = mcd: rr() = DivisionEuclidea(x(), n): m0 = rr(1)

ReDim p0(gp)

For i = 0 To gp

x(1) = p(i): x(2) = mcd: rr() = DivisionEuclidea(x(), n): p0(i) = rr(1)

Next i

End If

'' ——- SOLUCIÓN ————-'

ReDim s0(m0) " m0 no puede ser muy grande

j = "0": k=0: x(1) = m0: x(2) = "1": dif = Restar(x(), n)

Do

xx = "0"

If j = 0 Then

x(1) = p0(gp): x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) ="-0" then rr(2) = "0"

xx = rr(2)

Else

x(1) = p0(0): x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) ="-0" then rr(2) = "0"

xx = rr(2)

For i = 1 To gp

x(1) = xx: x(2) = j: rt = Multiplicar(x(), n)

x(1) = rt: x(2) = p0(i): xx = Sumar(x(), n)

x(1) = xx: x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) ="-0" then rr(2) = "0"

xx = rr(2)

Next i

End If

If xx = "0" Or xx = "-0" Then

k = k + 1

s0(k) = j

End If

x(1) = j: x(2) = "1": j = Sumar(x(), n)

x(1) = dif: x(2) = j: dif1 = Restar(x(), n)

Loop While Left$(dif1, 1) <> "-"

End If

If k <> 0 Then

For i = 1 To k

rs = rs + rc + "x(" + Str$(i) + ") = " + s0(i) + " + k*" + m0

Next i

Else

rs = "No hay soluciones"

End If

CongrGrSEG = rs

End Function

Ejemplo 15: Utilizando la función CongrGrSEG, las soluciones de la congruencia siguiente:

edu.red

, son edu.redy edu.red

Ejemplo 16: Utilizando el mismo código que en el ejemplo11, se obtiene que la congruencia

edu.red

, tiene las soluciones siguientes:

edu.red

Para que el último programa funcione, los coeficientes del polinomio pueden ser enteros bastante largos pero el módulo no. Según un teorema de Lagrange [8], si m es un número primo el número de las soluciones es inferior o igual al grado del polinomio. Si m no es primo pueden haber hasta m soluciones y, si m es grande, no se podría dimensionar una matriz s0() que contenga las soluciones [utilizando la instrucción: ReDim s0(m)]. En este último caso sería preferible presentar las soluciones en una variable de tipo String, separadas por comas, y no como elementos de una matriz. El programa anterior se puede modificar en este sentido:

Public Function CongrGrSEGB(ByRef p() As String, ByVal m As String) As String

Dim i As Integer, j As String, k As Integer, gp As Integer, rt As String, rr() As String, rs As String

Dim xx As String, yy As String, zz As String, r As String, mcd As String, dif As String, dif1 As String

Dim s0 As String, s() As String, p0() As String, x(2) As String, m0 As String, n As Integer

n = 7: gp = UBound(p())

If Left$(p(0), 1) = "-" Then xx = Mid$(p(0), 2) Else xx = p(0)

' ¿Pueden existir soluciones?

i = 0

Do

i = i + 1

If i < gp Then

If Left$(p(i), 1) = "-" Then yy = Mid$(p(i), 2) Else yy = p(i)

Else

yy = m

End If

If yy <> "0" Then

Do

x(1) = xx: x(2) = yy: rt = Restar(x(), n)

If Left$(rt, 1) = "-" Then zz = xx: xx = yy: yy = zz

x(1) = xx: x(2) = yy: rr() = DivisionEuclidea(x(), n)

r = rr(2)

If r = "0" Then Exit Do

xx = yy: yy = r

Loop

xx = yy

End If

Loop While i <= gp – 1

mcd = yy

x(1) = p(gp): x(2) = mcd: rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

yy = rr(2)

If yy = "0" Then

If mcd = "1" Then

m0 = m: p0() = p()

Else

x(1) = m: x(2) = mcd: rr() = DivisionEuclidea(x(), n): m0 = rr(1)

ReDim p0(gp)

For i = 0 To gp

x(1) = p(i): x(2) = mcd: rr() = DivisionEuclidea(x(), n): p0(i) = rr(1)

Next i

End If

' ———— SOLUCIÓN ——————-

j = "0": s0 = "": k = 0: x(1) = m0: x(2) = "1": dif = Restar(x(), n)

Do

xx = "0"

If j = 0 Then

x(1) = p0(gp): x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx = rr(2)

Else

x(1) = p0(0): x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx = rr(2)

For i = 1 To gp

x(1) = xx: x(2) = j: rt = Multiplicar(x(), n)

x(1) = rt: x(2) = p0(i): xx = Sumar(x(), n)

x(1) = xx: x(2) = m0: rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx = rr(2)

Next i

End If

If xx = "-0" Then xx = "0"

If xx = "0" Then

k = k + 1

s0 = s0 + j + " , "

End If

x(1) = j: x(2) = "1": j = Sumar(x(), n)

x(1) = dif: x(2) = j: dif1 = Restar(x(), n)

Loop While Left$(dif1, 1) <> "-"

End If

If k <> 0 Then

rs = "x = " + Left$(s0, Len(s0) – 5) + " mod (" + m0 + ")"

Else

rs = "No hay soluciones"

End If

CongrGrSEGB = rs

End Function

Ejemplo 17: En el caso de la congruencia

edu.red

El programa anterior da las soluciones:

edu.red

Es evidente que en este caso no era conveniente utilizar una matriz con 2374586 elementos para que al final contenga solo tres elementos. De todos modos, trabajando el ordenador a tres GHz, el resultado ha tardado en aparecer alrededor de 5-6 minutos. Si el módulo sería todavía mas grande, el tiempo de ejecución aumentaría mucho. Si en el ejemplo anterior se añadiría otra cifra más, el tiempo de ejecución podría alargarse fácilmente hasta una hora. En consecuencia, los coeficientes del polinomio pueden ser bastante grandes pero si el módulo tiene más de 6-7 cifras, la resolución de la congruencia tardaría demasiado.

§5. Sistemas de congruencias de primar grado.

Un sistema de congruencias de grado 1 tiene la forma siguiente:

edu.red (8)

El sistema (8) no siempre tiene soluciones. Las razones pueden ser distintas: o bien algunas congruencias no tienen solución o bien la solución de una no es solución de alguna de las otras.

Existe un teorema de un autor chino que afirma lo siguiente:

Teorema 7 (chino): Si los módulos edu.redson dos a dos primos relativos y, entonces el sistema edu.redtiene solución única respecto al módulo edu.red

El teorema 6 será consecuencia del teorema 7", en el caso edu.red

Teorema 7": Si los módulos edu.redson dos a dos primos relativos y edu.redson también primos relativos, entonces el sistema (8) tiene solución única respecto al módulo edu.red

En efecto, puesto que los números edu.redy el número edu.redson primos relativos, la congruencia edu.redtiene la solución edu.redsegún el teorema de Euler. Esto es la única solución de esta congruencia puesto que si tuviésemos también edu.redresultaría que edu.redLuego, teniendo en cuenta que edu.redson primos relativos, de aquí se obtiene que edu.redObviamente, edu.red, donde edu.redsi edu.rede edu.redsi edu.redAsí edu.redes solución del sistema (8) puesto que

edu.red

, cualquiera que sea edu.redes decir edu.redes solución de la congruencia (8). Si edu.redfuera otra solución entonces, según la propiedad 10, resultaría que edu.red

Teorema 8: Si en el sistema de congruencias (8) edu.redson primos relativos y edu.redson dos soluciones distintas del sistema, entonces edu.reddonde M es el mínimo común múltiplo de los módulos. En efecto si edu.redentonces

edu.redy edu.red

Así edu.redde donde resulta que edu.redes un divisor de la diferencia edu.redPuesto que edu.redprimos relativos resulta que edu.rededu.redPor consiguiente el teorema (8) se cumple para edu.redSuponiendo que se cumple para edu.redesto significa que edu.redLuego edu.redson soluciones también de la congruencia edu.redlo que implica que edu.redPuesto que el mínimo común múltiplo de edu.redy del módulo edu.redesedu.redresulta que edu.rededu.redes decir el teorema se cumple también en el caso edu.redPor consiguiente el teorema queda demostrado por inducción completa.

Para resolver el sistema (8) se puede proceder de la manera siguiente: En cada congruencia se calcula el máximo común divisor de edu.redde edu.redSi en alguna congruencia del sistema, edu.redno divide el número edu.redel sistema no tiene solución. En el caso contrario en cada congruencia se dividen los números edu.redentre edu.redobteniendo el sistema equivalente siguiente:

edu.red (8")

Luego, se resuelve la primera congruencia del sistema (8"). Si esta solución es edu.redluego entre los valores edu.redse busca una solución edu.redque verifique la segunda congruencia. Si no hay tal solución edu.redel sistema no tiene solución. En el caso contrario la solución del sistema formado de las primeras dos congruencias será edu.redLuego, entre edu.redse busca a aquella solución edu.reddel sistema, formado da las primeras dos congruencias de (8"), que verifique la tercera congruencia. Si edu.redno existe el sistema (8") no tiene solución En el caso contrario, según el teorema (8) la solución del sistema formado por las primera tres congruencias de (8") será edu.redContinuando este proceso o bien se obtiene que el sistema (8") no tiene solución, o bien se obtiene su solución respecto al módulo edu.red

Ejemplo 18: Resolver el sistema de congruencias por el método anterior:

edu.red (9)

La resolución del sistema (9) se reduce a la resolución del sistema (9"):

edu.red (9")

La solución de la primera congruencia es edu.redEntre los valores 0, 3, 6, el número 3 es solución del sistema formado de las primeras dos congruencias. Luego el valor 3 es el número que verifica el sistema (9"). Por tanto la solución del sistema es edu.red6. Respecto al módulo edu.redel sistema tiene las soluciones: edu.redy edu.rededu.red

Siguiendo el método expuesto en el ejemplo 14, para le resolución de los sistemas de congruencias en el ordenador se puede utilizar el código Visual-Basic siguiente:

Public Function RSC1(ByRef a0() As Long, ByRef b0() As Long, ByRef m0() As Long) As String

Dim i As Long, j As Integer, n As Long, u() As Long, x As Long, kk as integer

Dim mcd() As Long, mcm() As Long, k As Integer, ui As Long, xy As Long

Dim rc As String, y As Long, w As Long, m() As Long, a() As Long

Dim sw As Integer, res As String, xx() As Long, b() As Long

rc = Chr$(13) + Chr$(10): m() = m0(): a() = a0(): b() = b0(): n = UBound(a0())

ReDim mcd(n), mcm(n), u(n), resultado(2), xx(n)

' Cambios para que la primera congruencia tenga el menor módulo.

For i = 2 To n

If m(i) < m(1) Then

xy = m(1): m(1) = m(i): m(i) = xy

xy = a(1): a(1) = a(i): a(i) = xy

xy = b(1): b(1) = b(i): b(i) = xy

End If

Next i

' ¿Tienen soluciones las congruencias del sistema?

For i = 1 To n

mcd(i) = MaxComDivC(a(i), m(i))

x = b(i) Mod mcd(i)

If x <> 0 And mcd(i) <> 1 Then

RSC1 = "No hay solución"

Exit Function

End If

Next i

For i = 1 To n

If mcd(i) <> 1 Then

a(i) = a(i) / mcd(i): b(i) = b(i) / mcd(i): m(i) = m(i) / mcd(i)

End If

Next i

' Resolución de la primera congruencia (cuyo módulo es menor)

a(1) = a(1) Mod m(1): b(1) = b(1) Mod m(1)

For i = 1 To m(1) – 1

x = (a(1) * i – b(1)) Mod m(1)

If x = 0 Then k = i: Exit For

Next i

'Resolución del sistema

u(1) = k: mcm(1) = m(1)

For i = 2 To n

mcm(i) = MinComMultC(mcm(i – 1), m(i))

For j = u(i – 1) To mcm(i) Step m(i – 1)

sw = 0

For kk = 1 To i – 1: xx(kk) = 0: Next kk

For kk = 1 To i

xx(kk) = (a(kk) * j – b(kk)) Mod m(kk)

Next kk

For kk = 1 To i

If xx(kk) <> 0 Then sw = 1: Exit For

Next kk

If sw = 0 Then

u(i) = j: sw = 0: Exit For

End If

Next j

If sw = 1 Then

RSC1 = " No hay solución"

Exit Function

End If

If i = n Then Exit For

Next i

' Presentación del resultado

ui = u(i): res = "Solución: " + rc

res = res + "x = " + Str$(ui) + " + " + "k*" + Str$(mcm(n))

w = MinComMultC(m0(1), m0(2))

For i = 3 To n

w = MinComMultC(w, m0(i))

Next i

If ui + mcm(n) < w Then

res = res + rc

res = res + rc + "Soluciones respecto al módulo: " + Str$(w) + rc

i = 0: sw = 0

Do

y = ui + i * mcm(n): res = res + "x = " + Str$(y) + " + k*" + Str(w) + rc

i = i + 1

Loop While y + mcm(n) < w

End If

RSC1 = res

End Function

Public Function MaxComDiv3(ByVal a As Long, ByVal b As Long) As Long

Dim ax As Long, bx As Long, x As Long, qx As Long, rx As Long

ax = Abs(a): bx = Abs(b)

If ax < bx Then

x = ax: ax = bx: bx = x

End If

Do

rx = ax Mod bx

If rx = 0 Then Exit Do

ax = bx: bx = rx

Loop

MaxComDivC3 = bx

End Function

Public Function MinComMult3(ByVal a As Long, ByVal b As Long) As Long

MinComMult3 = Abs(a * b) / MaxComDiv3(a, b)

End Function

Ejemplo 19: Aplicando el código expuesto anteriormente al sistema:

edu.red (10)

, se obtiene la solución edu.redRespecto el módulo edu.redlas soluciones son: edu.red

La function RSC1 tiene suslimitaciones puesto que los coeficientes del sistema y los números que aparecen durante el cálculo se almacenan en variables de tipo Long. A continuación se presentan dos funciones que hacen los mismo que la Función RSC1 pero trabajan con variables de tipo String y son capaces de almacenar números enteros muy largos. La Función RSC2 se basa en el método directo y la segunda usa el me´todo de las fracciones continuas;

Public Function RSC2(ByRef a0() As String, ByRef b0() As String, ByRef m0() As String) As String

Dim i As String, ii As Integer, j As String, n As Integer, nc As Integer

Dim mcd() As String, x(2) As String, k As String, kk As Integer

Dim mcm() As String, ui As String, v1 As String, rr() As String

Dim a() As String, b() As String, m() As String, u() As String

rc = Chr$(13) + Chr$(10): a() = a0(): b() = b0(): m() = m0()

n = 7: nc = UBound(a0())

If nc = 1 Then

MsgBox "El sistema debe tener más de una congruencia"

End

End If

ReDim mcd(nc), u(nc), xx(nc), mcm(nc)

For kk = 1 To nc

x(1) = a(kk): x(2) = m(kk)

mcd(kk) = MaxComDiv(x(), n)

x(1) = b(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

If rr(2) <> "0" And mcd(kk) <> "1" Then

RSC2 = "No hay solución"

Exit Function

End If

Next kk

For kk = 1 To nc

If mcd(kk) <> "1" Then

x(1) = a(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): a(kk) = rr(1)

x(1) = b(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): b(kk) = rr(1)

x(1) = m(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): m(kk) = rr(1)

End If

Next kk

' Resolución de la primera congruencia por el método directo.

x(1) = a(1): x(2) = m(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

a(1) = rr(2)

x(1) = b(1): x(2) = m(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

b(1) = rr(2)

i = "0": x(1) = m(1): x(2) = "1": v = Restar(x(), n)

Do

x(1) = i: x(2) = "1": i = Sumar(x(), n)

x(1) = a(1): x(2) = i: y = Multiplicar(x(), n)

x(1) = y: x(2) = b(1): y = Restar(x(), n)

x(1) = y: x(2) = m(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

If rr(2) = "0" Then k = i: Exit Do

x(1) = i: x(2) = v: v1 = Restar(x(), n)

Loop While Left$(v1, 1) = "-" Or v1 = "0"

'Resolución del sistema

u(1) = k: mcm(1) = m(1)

For ii = 2 To nc

x(1) = mcm(ii – 1): x(2) = m(ii): mcm(ii) = MinComMult(x(), n)

Next ii

For ii = 2 To nc

j = u(ii – 1)

Do

For kk = 1 To ii: xx(kk) = "0": Next kk

sw = 0

For kk = 1 To ii

x(1) = a(kk): x(2) = j: xx(kk) = Multiplicar(x(), n)

x(1) = xx(kk): x(2) = b(kk): xx(kk) = Restar(x(), n)

x(1) = xx(kk): x(2) = m(kk): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx(kk) = rr(2)

Next kk

For kk = 1 To ii

If xx(kk) <> "0" Then sw = 1: Exit For

Next kk

If sw = 0 Then

u(ii) = j: sw = 0: Exit Do

End If

x(1) = j: x(2) = m(ii – 1): j = Sumar(x(), n)

x(1) = j: x(2) = mcm(ii): dif = Restar(x(), n)

Loop While Left$(dif, 1) = "-" Or dif = "0"

If sw = 1 Then

RSC2 = " No hay solución"

Exit Function

End If

If ii = nc Then Exit For

Next ii

' Presentación del resultado

ui = u(ii): res = "Solución: " + rc

es = res + "x = " + ui + " + " + "k*" + mcm(nc)

RSC2 = res

End Function

Ejemplo 20: El sistema de congruencias siguiente no puede ser resuelto utilizando la función "RSC1" puesto que sus coeficientes no pueden ser almacenados en variables de tipo Long.

edu.red (11)

Para esto se puede servir de la función "RSC2", que trabaja con números enteros almacenados en variables de tipo String. Con esta función se obtiene la siguiente solución del sistema (11): edu.red

Public Function RSCFRC(ByRef a0() As String, ByRef b0() As String, ByRef m0() As String) As String

Dim i As String, ii As Integer, j As String, n As Integer, nc As Integer, u() As String, y As String

Dim mcd() As String, mcm() As String, x(2) As String, k As String, kk As Integer, ui As String

Dim rc As String, w As String, m() As String, a() As String, dif As String, v1 As String

Dim sw As Integer, res As String, xx() As String, b() As String, rr() As String, fr() As String

rc = Chr$(13) + Chr$(10): a() = a0(): b() = b0(): m() = m0()

n = 7: nc = UBound(a0())

ReDim mcd(nc), mcm(nc), u(nc), resultado(2), xx(nc)

For kk = 1 To nc

x(1) = a(kk): x(2) = m(kk)

mcd(kk) = MaxComDiv(x(), n)

x(1) = b(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

If rr(2) <> "0" And mcd(kk) <> "1" Then

RSCFRC = "No hay solución"

Exit Function

End If

Next kk

For kk = 1 To nc

If mcd(kk) <> "1" Then

x(1) = a(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): a(kk) = rr(1)

x(1) = b(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): b(kk) = rr(1)

x(1) = m(kk): x(2) = mcd(kk): rr() = DivisionEuclidea(x(), n): m(kk) = rr(1)

End If

Next kk

' Resolución de la primera congruencia por el método de las fracciones continuas

fr() = FrContFrCg(a(1), m(1))

d = UBound(fr())

ReDim p(d), q(d)

p(0) = fr(0): q(0) = "1"

x(1) = fr(0): x(2) = fr(1)

x(1) = Multiplicar(x(), n): x(2) = "1"

p(1) = Sumar(x(), n): q(1) = fr(1)

For ii = 2 To d

x(1) = fr(ii): x(2) = p(ii – 1)

x(1) = Multiplicar(x(), n): x(2) = p(ii – 2)

p(ii) = Sumar(x(), n)

x(1) = fr(ii): x(2) = q(ii – 1)

x(1) = Multiplicar(x(), n): x(2) = q(ii – 2)

q(ii) = Sumar(x(), n)

Next ii

x(1) = b(1): x(2) = q(d – 1)

xy = Multiplicar(x(), n)

t = (d + 1) Mod 2

If t = 1 Then

If Left$(xy, 1) = "-" Then xy = Mid$(xy, 1) Else xy = "-" + xy

End If

x(1) = xy: x(2) = m(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

u(1) = rr(2): mcm(1) = m(1)

For ii = 2 To nc

x(1) = mcm(ii – 1): x(2) = m(ii)

mcm(ii) = MinComMult(x(), n)

j = u(ii – 1)

Do

For kk = 1 To ii – 1: xx(kk) = "0": Next kk

sw = 0

For kk = 1 To ii

x(1) = a(kk): x(2) = j: xx(kk) = Multiplicar(x(), n)

x(1) = xx(kk): x(2) = b(kk): xx(kk) = Restar(x(), n)

x(1) = xx(kk): x(2) = m(kk): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

xx(kk) = rr(2)

Next kk

For kk = 1 To ii

If xx(kk) <> "0" Then sw = 1: Exit For

Next kk

If sw = 0 Then

u(ii) = j: sw = 0: Exit Do

End If

x(1) = j: x(2) = m(ii – 1): j = Sumar(x(), n)

x(1) = j: x(2) = mcm(ii): dif = Restar(x(), n)

Loop While Left$(dif, 1) = "-" Or dif = "0"

If sw = 1 Then

RSCFRC = " No hay solución"

Exit Function

End If

If ii = nc Then Exit For

Next ii

' Presentación del resultado

ui = u(ii): res = "Solución: " + rc

res = res + "x = " + ui + " + " + "k*" + mcm(nc)

RSCFRC = res

End Function

Ejemplo 21: Resolver el sistema de congruencias:

edu.red

Utilizando las funciones RSC2 o RSCFRC, la solución es:

edu.red

§6. Sistemas de congruencias de grado superior.

Este tipo de sistemas de congruencias tienen la forma siguiente:

edu.red (12)

Para que el sistema tenga soluciones cada congruencia debe tener soluciones y tienen que existir soluciones comunes. Primero hay que resolver la congruencia de menor módulo y luego hay que comprobar ¿cuáles de sus soluciones son soluciones de las otras congruencias? Si la primera congruencia no tuviera el menor módulo, hay que cambiar el sistema tal que la congruencia de menor módulo sea la primera congruencia del sistema (esto es importante puesto que las soluciones de la primera congruencia se buscarán por el método directo, es decir, comprobando ¿cuáles de los números de cero hasta el módulo son soluciones.

La función siguiente devuelve las soluciones de los sistemas de congruencias de grado superior (siempre y cuando los datos introducidos y los números que intervienen en los cálculos pueden ser almacenados en variables de tipo Long):

Public Function SCNL(ByRef sist() As String, ByVal mdls As String, ByVal nc As Integer) As String

Dim p() As Long, gp As Integer, gs As Integer, m As Long, m0() As Long, gpol() As Integer

Dim i As Integer, mcd() As Long, p0() As Long, s0() As Long, s1() As Long, rc As String

Dim z As Long, r As Long, rs As String, ns As Integer, sw As Integer, j As Integer

Dim res As String, ui As Long, s2() As Long, kk As Integer, xy As String, ii As Long

Dim w As Long, w1 As Long, vp0 As Long, vp00 As Long, vp() As Long, q() As Long, pol() As Long

Dim x As Long, y As Long, k As Integer, mcm() As Long, mo() As Long, rr() As Long

rc = Chr$(13) + Chr$(10)

ReDim mo(nc)

rr() = RutinaCoeficientes(mdls)

rr(0) = rr(0)

For i = 1 To nc

mo(i) = rr(i – 1)

Next i

'——— Cambios para que la primera congruencia tenga el módulo menor.

For i = 2 To nc

If mo(i) < mo(1) Then

xy = mo(1): mo(1) = mo(i): mo(i) = xy

xy = sist(1): sist(1) = sist(i): sist(i) = xy

End If

Next i

ReDim gpol(nc)

gs = 0

For j = 1 To nc

pol() = RutinaCoeficientes(sist(j))

gpol(j) = UBound(pol())

If gpol(j) > gs Then gs = gpol(j)

Next j

ReDim p(gs, nc)

For i = 1 To nc

pol() = RutinaCoeficientes(sist(i))

For j = 0 To gpol(i)

p(j, i) = pol(j)

Next j

Next i

' El sistema ¿puede tener soluciones?

ReDim mcd(nc)

For i = 1 To nc

x = Abs(p(0, i))

For j = 1 To gpol(i)

If j < gpol(i) Then y = Abs(p(j, i)) Else y = mo(i)

If y <> 0 Then x = MaxComDivC(x, y)

Next j

mcd(i) = x

y = p(gpol(i), i) Mod mcd(i)

If y <> 0 Then

SCNL = "No hay soluciones"

Exit Function

End If

Next i

ReDim p0(gs, nc), m0(nc)

For i = 1 To nc

If mcd(i) = 1 Then

m0(i) = mo(i)

For j = 0 To gpol(i)

p0(j, i) = p(j, i)

Next j

Else

m0(i) = mo(i) / mcd(i)

For j = 0 To gpol(i)

p0(j, i) = p(j, i) / mcd(i)

Next j

End If

Next i

'——– Resolución de la congruencia de módulo menor.

ReDim s0(m0(1))

For j = 0 To m0(1) – 1

x = 0

If j = 0 Then

x = p0(gpol(1), 1) Mod m0(1)

Else

x = p0(0, 1) Mod m0(1)

For i = 1 To gpol(1)

x = (x * j) Mod m0(1)

x = (x + p0(i, 1)) Mod m0(1)

Next i

End If

If x = 0 Then

k = k + 1

s0(k) = j

End If

Next j

ns = k

If ns <> 0 Then

ReDim s1(ns), s2(ns), vp(nc), mcm(nc)

For i = 1 To ns: s1(i) = s0(i): Next i

ReDim s2(m0(1))

w = MinComMultC(mo(1), mo(2))

For i = 3 To nc

w = MinComMultC(w, mo(i))

Next i

For i = 1 To ns: s1(i) = s0(i): Next i

mcm(1) = m0(1)

For i = 2 To nc

mcm(i) = MinComMultC(mcm(i – 1), m0(i))

Next i

w = MinComMultC(mo(1), mo(2))

For i = 3 To nc

w = MinComMultC(w, mo(i))

Next i

kk = 0

For k = 1 To ns

ii = 0

For i = 2 To nc

ReDim q(gpol(i))

q(0) = p(0, i)

Do

vp0 = s1(k) + ii * m0(1): vp00 = vp0 Mod mo(i)

For j = 1 To gpol(i)

q(j) = vp0 * q(j – 1) Mod mo(i)

q(j) = q(j) + p(j, i) Mod mo(i)

Next j

vp(i) = q(gpol(i)) Mod m0(i)

If vp(i) = 0 Then Exit Do

ii = ii + 1

Loop While vp0 < mcm(i) + m0(1)

Next i

For i = 2 To nc

If vp(i) <> 0 Then sw = 1

Next i

If sw = 0 Then

If vp0 <> s2(kk) Or kk = 0 Then

kk = kk + 1: s2(kk) = vp0

End If

Else

sw = 0

End If

Next k

If kk = 0 Then

SCNL = "No hay soluciones"

Exit Function

End If

'Ordenación de las soluciones

For i = 1 To kk

For j = i + 1 To kk

If s2(i) > s2(j) Then

z = s2(i): s2(i) = s2(j): s2(j) = z

End If

Next j

Next i

'Edición de los resultados

res = "Soluciónes: " + rc + rc

For i = 1 To kk

ui = s2(i)

res = res + "x = " + Str$(ui) + " + " + "k*" + Str$(mcm(nc)) + rc

Next i

If mcm(nc) < w Then

res = res + rc + "Soluciones respecto al módulo: " + Str$(w) + rc

res = res + rc

For i = 1 To kk

ui = s2(i): ii = 0

Do

y = ui + ii * mcm(nc)

res = res + "x = " + Str$(y) + " + k*" + Str(w) + rc

ii = ii + 1

Loop While y + mcm(nc) < w

res = res + rc: y = 0

Next i

End If

Else

res = "No hay soluciones"

End If

SCNL = res

End Function

Public Function MaxComDivC(ByVal a As Long, ByVal b As Long) As Long

Dim ax As Long, bx As Long, x As Long, qx As Long, rx As Long

ax = a: bx = b

If ax < bx Then

x = ax: ax = bx: bx = x

End If

Do

rx = ax Mod bx

If rx = 0 Then Exit Do

ax = bx: bx = rx

Loop

MaxComDivC = bx

End Function

Public Function MinComMultC(ByVal a As Long, ByVal b As Long) As Long

MinComMultC = (a * b) / MaxComDivC(a, b)

End Function

Public Function RutinaCoeficientes(ByVal t As String) As Variant

Dim i As Integer, j As Integer, k As Integer, lt As Integer

Dim i0 As Integer, nco As Integer, gp As Integer

Dim bb As String, px() As Long

'—- Número de las comas en la cadena t

If Right$(t, 1) <> "," Then t = t + ","

k = 1: lt = Len(t): nco = 0

Do

bb = Right$(Left$(t, k), 1)

If bb = "," Then

nco = nco + 1

End If

k = k + 1

If k > lt Then Exit Do

Loop

gp = nco – 1

'— Separación de los coeficientes

ReDim px(gp)

k = 1: i = 1: i0 = 0: j = 0

Do

bb = Right$(Left$(t, k), 1)

If bb = "," Then

j = j + 1

px(i0) = Val(Left$(t, k – 1))

i = i + 1: i0 = i0 + 1

t = Mid$(t, k + 1)

k = 1

Else

k = k + 1

End If

If j = nco Then Exit Do

Loop

RutinaCoeficientes = px()

End Function

Ejemplo 22: Para resolver el sistema de congruencias:

edu.red

, por el código anterior, hay que suministrar los argumentos siguientes:

edu.red

El resultado será:

edu.red

Ejemplo 23: Resolver el sistema:

edu.red

Se observa que todos los coeficientes y el módulo de la primera congruencia del sistema son múltiplos de 2. Al dividir en la primera congruencia los coeficientes y el módulo entre 2, la resolución del sistema se reduce a la resolución del sistema del ejemplo 21. Por tanto la solución del sistema del ejemplo 21 es la misma que la del ejemplo 21, respecto al módulo 555.

El mínimo común múltiplo de los módulo 74 y 15 es 1110 y respecto a este módulo la soluciones distintas son las siguientes:

edu.red edu.rededu.red

Cuando algunos de los coeficientes del sistema o los resultados intermedios de los cálculos no pueden ser almacenados en variables de tipo Long, para resolver el sistema hay que recurrir al programa siguiente que trabaja con variables de tipo string, utilizando las funciones Multiplicar, Sumar, Restar, DivisionEuclidea, MaxComDiv, MinComMult (expuestas en [11]):

Public Function SCNLNG(ByRef sist() As String, ByVal mdls As String, nc As Integer) As String

Dim p() As String, gp As Integer, gs As Integer, m As String, m0() As String

Dim i As Integer, mcd() As String, p0() As String, s0() As String, s1() As String

Dim z As String, r As String, rs As String, ns As Integer, sw As Integer

Dim res As String, ui As String, s2() As String, kk As Integer, xy As String

Dim w As String, vp0 As String, vp() As String, q() As String, pol() As String

Dim x(2) As String, y As String, k As Integer, mcm() As String, rr() As String

Dim mo() As String, gpol() As Integer, xx As String, rc As String, n As Integer

Dim ii As String, j As Integer, jj As String, w0 As String

ReDim mo(nc), gpol(nc)

rc = Chr$(13) + Chr$(10): n = 7

rr() = RutinaCoeficientes(mdls)

For i = 1 To nc : mo(i) = rr(i – 1) : Next i

'——— Cambios para que la primera congruencia tenga el módulo menor.

For i = 2 To nc

x(1) = mo(i): x(2) = mo(1): y = Restar(x(), n)

If Left$(y, 1) = "-" Then

xy = mo(1): mo(1) = mo(i): mo(i) = xy

xy = sist(1): sist(1) = sist(i): sist(i) = xy

End If

Next i

gs = 0

For j = 1 To nc

pol() = RutinaCoeficientes(sist(j))

gpol(j) = UBound(pol())

If gpol(j) > gs Then gs = gpol(j)

Next j

ReDim p(gs, nc)

For i = 1 To nc

pol() = RutinaCoeficientes(sist(i))

For j = 0 To gpol(i)

p(j, i) = pol(j)

Next j

Next i

' El sistema ¿puede tener soluciones?

ReDim mcd(nc)

For i = 1 To nc

If Left$(p(0, i), 1) = "-" Then y = Mid$(p(0, i), 2) Else y = p(0, i)

For j = 1 To gpol(i)

If j < gpol(i) Then

If Left$(p(j, i), 1) = "-" Then xx = Mid$(p(j, i), 2) Else xx = p(j, i)

Else

xx = mo(i)

End If

If xx <> "0" Then

x(1) = xx: x(2) = y: mcd(i) = MaxComDiv(x(), n)

y = mcd(i)

Else

mcd(i) = y

End If

Next j

x(1) = p(gpol(i), i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

y = rr(2)

If y <> "0" Then

SCNLNG = "No hay soluciones"

Exit Function

End If

Next i

ReDim p0(gs, nc), m0(nc)

For i = 1 To nc

If mcd(i) = "1" Then

m0(i) = mo(i)

For j = 0 To gpol(i)

p0(j, i) = p(j, i)

Next j

Else

x(1) = mo(i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

m0(i) = rr(1)

For j = 0 To gpol(i)

x(1) = p(j, i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

p0(j, i) = rr(1)

Next j

End If

Next i

'———- Resolución de la congruencia de módulo menor.

ReDim s0(m0(1))

jj = "0": k = 0

Do

If jj = "0" Then

x(1) = p(gpol(1), 1): x(2) = m0(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

z = rr(2)

Else

z = p(0, 1)

For i = 1 To gpol(1)

x(1) = jj: x(2) = z: x(1) = Multiplicar(x(), n)

x(2) = p(i, 1): z = Sumar(x(), n)

Next i

x(1) = z: x(2) = m0(1)

rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

z = rr(2)

End If

If z = "0" Then

k = k + 1: s0(k) = jj

End If

(1) = jj: x(2) = "1": jj = Sumar(x(), n)

f jj = m0(1) Then Exit Do

Loop

ns = k

' Resolución del sistema

If ns <> 0 Then

ReDim s1(ns), s2(ns), vp(nc), mcm(nc)

For i = 1 To ns: s1(i) = s0(i): Next i

ReDim s2(m0(1))

For i = 1 To ns: s1(i) = s0(i): Next i

mcm(1) = m0(1)

For i = 2 To nc

x(1) = mcm(i – 1): x(2) = m0(i)

mcm(i) = MinComMult(x(), n)

Next i

x(1) = m0(1): x(2) = m0(2)

w0 = MinComMult(x(), n)

For i = 3 To nc

x(1) = w0: x(2) = m0(i)

w0 = MinComMult(x(), n)

Next i

x(1) = mo(1): x(2) = mo(2)

w = MinComMult(x(), n)

For i = 3 To nc

x(1) = w: x(2) = mo(i)

w = MinComMult(x(), n)

Next i

kk = 0

For k = 1 To ns

ii = "0"

For i = 2 To nc

ReDim q(gpol(i))

q(0) = p(0, i)

Do

x(1) = ii: x(2) = m0(1): x(1) = Multiplicar(x(), n): x(2) = s1(k)

vp0 = Sumar(x(), n)

For j = 1 To gpol(i)

x(1) = vp0: x(2) = q(j – 1)

x(1) = Multiplicar(x(), n): x(2) = p(j, i)

q(j) = Sumar(x(), n)

Next j

x(1) = q(gpol(i)): x(2) = m0(i): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

vp(i) = rr(2)

If vp(i) = "0" Then Exit Do

x(1) = ii: x(2) = "1": ii = Sumar(x(), n)

x(1) = mcm(i): x(2) = m0(1): x(2) = Sumar(x(), n): x(1) = vp0

y = Restar(x(), n)

Loop While Left$(y, 1) = "-"

Next i

For i = 2 To nc

If vp(i) <> "0" Then sw = 1

Next i

If sw = 0 Then

If vp0 <> s2(kk) Or kk = 0 Then

kk = kk + 1: s2(kk) = vp0

End If

Else

sw = 0

End If

Next k

If kk = 0 Then

SCNLNG = "No hay soluciones"

Exit Function

End If

' Ordenar las soluciones

For i = 1 To kk

For j = i + 1 To kk

If s2(i) > s2(j) Then

xy = s2(i): s2(i) = s2(j): s2(j) = xy

End If

Next j

Next i

'Edición de las soluciones

res = "Soluciónes: " + rc + rc

For i = 1 To kk

ui = s2(i)

res = res + "x = " + ui + " + " + "k*" + mcm(nc) + rc

Next i

If w0 <> w Then

res = res + rc + "Soluciones respecto al módulo: " + w + rc

res = res + rc

For i = 1 To kk

ui = s2(i): ii = 0

Do

y = ui + ii * mcm(nc)

res = res + "x = " + y + " + k*" + w + rc

ii = ii + 1

x(1) = y: x(2) = mcm(nc)

x(1) = Sumar(x(), n): x(2) = w

y = Restar(x(), n)

Loop While Left$(y, 1) = "-"

res = res + rc: y = 0

Next i

End If

Else

res = "No hay soluciones"

End If

SCNLNG = res

End Function

Public Function RutinaCoeficientesB(ByVal t As String) As Variant

Dim i As Integer, j As Integer, k As Integer, lt As Integer

Dim i0 As Integer, nco As Integer, gp As Integer

Dim bb As String, px() As String

'—- Número de las comas en la cadena t

If Right$(t, 1) <> "," Then t = t + ","

k = 1: lt = Len(t): nco = 0

Do

bb = Right$(Left$(t, k), 1)

If bb = "," Then

nco = nco + 1

End If

k = k + 1

If k > lt Then Exit Do

Loop

gp = nco – 1

'— Separación de los coeficientes

ReDim px(gp)

k = 1: i = 1: i0 = 0: j = 0

Do

bb = Right$(Left$(t, k), 1)

If bb = "," Then

j = j + 1

px(i0) = Left$(t, k – 1)

i = i + 1: i0 = i0 + 1

t = Mid$(t, k + 1)

k = 1

Else

k = k + 1

End If

If j = nco Then Exit Do

Loop

RutinaCoeficientes = px()

End Function

En la función SCNLNG las soluciones de de la congruencia de módulo menor y las soluciones del sistema se almacenaban en matrices Si los módulos son moderadamente grandes y no primos esto tiene la desventaja que los matrices utilizados para contener las soluciones tienen demasiados elementos, aunque finalmente pocas soluciones tendremos que almacenar en ellas. El código siguiente no utilizara matrices para retener las soluciones pero tiene la desventaja de no ordenar las soluciones (de menor a mayor).

Public Function SCNLNGB(ByRef sist() As String, ByVal mdls As String, nc As Integer) As String

Dim p() As String, gp As Integer, gs As Integer, m As String, m0() As String

Dim i As Integer, mcd() As String, p0() As String, n As Integer. ii As String

Dim z As String, r As String, rs As String, ns As Integer, rc As String

Dim res As String, ui As String, kk As Integer, jj As String, sw As Integer

Dim vp0 As String, vp() As String, q() As String, pol() As String

Dim x(2) As String, y As String, mcm() As String, rr() As String

Dim mo() As String, gpol() As Integer, xx As String, xy As String

ReDim mo(nc), gpol(nc)

rc = Chr$(13) + Chr$(10): n = 7

rr() = RutinaCoeficientes(mdls)

For i = 1 To nc : mo(i) = rr(i – 1) : Next i

'——— Cambios para que la primera congruencia tenga el módulo menor.

For i = 2 To nc

x(1) = mo(i): x(2) = mo(1): y = Restar(x(), n)

If Left$(y, 1) = "-" Then

xy = mo(1): mo(1) = mo(i): mo(i) = xy

xy = sist(1): sist(1) = sist(i): sist(i) = xy

End If

Next i

gs = 0

For j = 1 To nc

pol() = RutinaCoeficientes(sist(j))

gpol(j) = UBound(pol())

If gpol(j) > gs Then gs = gpol(j)

Next j

ReDim p(gs, nc)

For i = 1 To nc

pol() = RutinaCoeficientes(sist(i))

For j = 0 To gpol(i)

p(j, i) = pol(j)

Next j

Next i

' El sistema ¿puede tener soluciones?

ReDim mcd(nc)

For i = 1 To nc

If Left$(p(0, i), 1) = "-" Then y = Mid$(p(0, i), 2) Else y = p(0, i)

For j = 1 To gpol(i)

If j < gpol(i) Then

If Left$(p(j, i), 1) = "-" Then xx = Mid$(p(j, i), 2) Else xx = p(j, i)

Else

xx = mo(i)

End If

If xx <> "0" Then

x(1) = xx: x(2) = y: mcd(i) = MaxComDiv(x(), n)

y = xx

Else

mcd(i) = y

End If

Next j

x(1) = p(gpol(i), i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

y = rr(2)

If y <> "0" Then

SCNLNGB = "No hay soluciones"

Exit Function

End If

Next i

ReDim p0(gs, nc), m0(nc)

For i = 1 To nc

If mcd(i) = "1" Then

m0(i) = mo(i)

For j = 0 To gpol(i)

p0(j, i) = p(j, i)

Next j

Else

x(1) = mo(i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

m0(i) = rr(1)

For j = 0 To gpol(i)

x(1) = p(j, i): x(2) = mcd(i): rr() = DivisionEuclidea(x(), n)

p0(j, i) = rr(1)

Next j

End If

Next i

ReDim mcm(nc), vp(nc)

mcm(1) = m0(1)

For i = 2 To nc

x(1) = mcm(i – 1): x(2) = m0(i)

mcm(i) = MinComMult(x(), n)

Next i

"———- Resolución de la congruencia de módulo menor.

jj = "0"

Do

If jj = "0" Then

x(1) = p(gpol(1), 1): x(2) = m0(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

z = rr(2)

Else

x(1) = p(0, 1): x(2) = m0(1): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

z = rr(2)

For i = 1 To gpol(1)

x(1) = z: x(2) = jj: x(1) = Multiplicar(x(), n)

x(2) = p(i, 1): x(1) = Sumar(x(), n): x(2) = m0(1)

rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

z = rr(2)

Next i

End If

If z = "0" Then

' Comprobación si jj verifica las otras congruencias

For i = 2 To nc

ReDim q(gpol(i))

q(0) = p(0, i)

Do

x(1) = ii: x(2) = m0(1): x(1) = Multiplicar(x(), n): x(2) = jj

vp0 = Sumar(x(), n)

For j = 1 To gpol(i)

x(1) = vp0: x(2) = q(j – 1)

x(1) = Multiplicar(x(), n): x(2) = p(j, i)

q(j) = Sumar(x(), n)

Next j

x(1) = q(gpol(i)): x(2) = m0(i): rr() = DivisionEuclidea(x(), n)

If rr(2) = "-0" Then rr(2) = "0"

Vp(i) = rr(2)

If vp(i) = "0" Then Exit Do

x(1) = ii: x(2) = "1": ii = Sumar(x(), n)

x(1) = mcm(i): x(2) = m0(1): x(2) = Sumar(x(), n): x(1) = vp0

y = Restar(x(), n)

Loop While Left$(y, 1) = "-"

Next i

ii = "0"

For i = 2 To nc

If vp(i) <> "0" Then sw = 1

Next i

If sw = 0 Then

vp0 = vp0 Mod mcm(nc)

If kk = 0 Then res = "x = "

res = res + vp0 + ","

If kk = 0 Then kk = 1

Else

sw = 0

End If

End If

x(1) = jj: x(2) = "1": jj = Sumar(x(), n)

If jj = mo(1) Then Exit Do

Loop

If Right$(res, 1) = "," Then res = Left$(res, Len(res) – 1)

If kk = 1 Then res = res + " + k*" + mcm(nc) Else res = "No hay soluciones"

SCNLNGB = res

End Function

Ejemplo 24: Resolver el sistema de congruencias siguiente:

edu.red

Aplicando uno de los dos códigos anteriores se obtiene que las soluciones son las siguientes:

edu.red

Los dos últimos programas funcionan bien si los módulos no son demasiado grandes. En el caso contrario el tiempo de espera puede llegar considerable. Pero así son las cosas, siempre habrá límites (sobre todo para los módulos), que podrán mejorar con la evolución de los ordenadores, pero existirán siempre.

Observación 3: En los programas expuestos en este trabajo se utilizó con cierta frecuencia el código siguiente: rr() = DivisionEuclidea:If rr(2)="-0" then rr(2)="0".Se puede prescindir de la secuencia If rr(2)="-0" then rr(2)="0"si en el programa de operaciones con números enteros grandes [11] se elimina el resultado "-0" Para esto en la función DivisionEclidea, antes de devolver el resultado, hay que incluir el código If rt(2 ) = "-0" then rt(2) = "0" También en la función Multiplicar, antes de de devolver el resultado hay que incluir el código If at = "-0" then at= "0". De todos modos, si el usuario hace o no estas modificaciones, los programas que se refieren a congruencias o ecuaciones diofánticas, funcionarán perfectamente. Si se lleva a cabo esta pequeña modificación en [11], en las aplicaciones anteriores o futuras ya no debería preocuparse del resultado "-0".

Bibliografía:

[1] P.Bachmann, Niedere Zahlentheorie, 1910

[2] R.D Garmichael:Thérie des nombre, 1919

[3] L.E. Dickson. Einfürung in die Zahlentheorie, 1931

[4] B.P. Huppert, Endlichen gruppen

[5] Kiss Ernö, A számelmélet Elemei, Technikai Könyvkiado, Bukarest, 1960

[6] Eugen Rusu, Bazele teoriei numerelor, 1953

[7]Vinogradov, Los bases de la teoría de los números (en ruso), 1952

[8] I. Creanga, C. Czacu, P. Minu?, GH. Opai?, Corina Reischer, Introducere în teoría

numerelor, Editura Didactia ?i Pedagogica, Bucure?ti, 1965

[9] A.L. Hincin, Frac?ii Continue, Editura Tehnica, Bucarest, 1960

[10] A. Péter Santha, Índice y periódo de los elementos de un semigupo, Monografias.com, 2012

[11] A. Peter Santha, Cálculos con números enteros grandes en ordenadores, Monografias.com, 2012

 

 

Autor:

Aladar Peter Santha

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente