Con ella también se puede sacar el M.C.D. con una función que se implementó en el módulo para alivianar el proceso.
El módulo que les dejo aún está muy incompleto y lo pienso ampliar con los conocimientos que valla aprendiendo de Matemáticas Discretas.
# -*- coding: utf-8 -*-
###############################################################
# MATEMATICAS DISCRETAS
# Juan Fernando Hernandez Z - Universidad de Antioquia
#
# Clase para el manejo de matematicas discretas
###############################################################
def mcd(a, b):
D = Diofanticas(a, b)
D.__calcularMCD__()
return D.MCD
class Diofantica:
#a es la constante de la x y b la de la y
def __init__(self, a, b):
self.__a__ , self.__b__ = a, b
self.__c__ = int()
#GLOBAL
#Matriz nx4 (Dividedo, Divisor, cociente, residuo)
self.__mMCD__ = []
self.MCD = int()
#CL de valores Para la Ecn
self.CL = []
# Calculo del MCD
####################################################################
def __calcularMCD__(self):
if(len(self.__mMCD__) != 0): self.__mMCD__.clear()
a_aux, b_aux = sorted([self.__a__, self.__b__], reverse=True)
div = self.__divisionA__(a_aux, b_aux)
self.__mMCD__.append(div)
#Mientras el residuo no sea cero
while (div[3] != 0):
div = self.__divisionA__(div[1],div[3])
self.__mMCD__.append(div)
#Retorno el ultimo divisor (Penultimo residuo)
self.MCD = div[1]
def __divisionA__(self,x, y):
return [x, y, x//y, x%y]
# Calculo del MCD como C.L. (AX + BY = MCD)
####################################################################
# R1 = [1, -C1]
# R2 = [0, 1] - C2*R1
# Rn = [R(n-2)] - Cn[R(n-1)] /n >= 3
def __reverseMCD__(self):
#Matriz nx2 para hallar la CL (A, B)
mRegresion = []
fMatriz = len(self.__mMCD__)
# R1
Cn = self.__mMCD__[0][2]
Rn = [1, -Cn]
mRegresion.append(Rn)
if(self.__a__ < self.__b__): self.CL = mRegresion[fMatriz-2][::-1]
else: self.CL = mRegresion[fMatriz-2]
return 0
#R2
Cn = self.__mMCD__[1][2]
Rn = self.__sumaV__([0 , 1] , self.__multEV__(-Cn, mRegresion[0]))
mRegresion.append(Rn)
if(fMatriz == 2): return Rn
if(self.__a__ < self.__b__): self.CL = mRegresion[fMatriz-2][::-1]
else: self.CL = mRegresion[fMatriz-2]
return 0
#R >=3 Range no me saca en lista el valor maximo
for n in range(2, fMatriz - 1):
Cn = self.__mMCD__[n][2]
Rn = self.__sumaV__(mRegresion[n-2] , self.__multEV__(-Cn, mRegresion[n-1]))
mRegresion.append(Rn)
if(self.__a__ < self.__b__): self.CL = mRegresion[fMatriz-2][::-1]
else: self.CL = mRegresion[fMatriz-2]
return 0
#suma de vectores(Dim = 2)
def __sumaV__(self, V1, V2):
return [V1[0]+V2[0] , V1[1]+V2[1]]
#multiplicacion vector(Dim = 2) escalar
def __multEV__(self, C, V):
return [C*V[0] , C*V[1]]
# Solucion Ecn diofántica 2 variables AX + BY = C
####################################################################
#Retorna una matriz 2x2 con la Sln general de la Ecuacion
def __solve__(self):
self.__calcularMCD__()
self.__reverseMCD__()
def solucionGeneral(self, c):
if(len(self.CL) == 0): self.__solve__()
self.__c__ = c
if (self.__solucionable__(c) == False): return -1
mult = c//self.MCD
SlnX = [self.CL[0] * mult, self.__b__//self.MCD]
SlnY = [self.CL[1] * mult, -(self.__a__//self.MCD)]
return [SlnX, SlnY]
def __solucionable__(self, c):
prueba = c%self.MCD
if (prueba == 0):
return True
return False
Las dos funciones principales del módulo son mcd(n1, n2) que retorna el máximo común divisor entre dos números y Diofantica.solucionGeneral(c) la cual retorna una matriz 4x4 con la solucion general de la ecuación donde la primera fila corresponde a la solución en X y la segunda fila a la solución en Y.
Para hallar la C.L. implementé un algoritmo general así:
# R1 = [1, -C1] # R2 = [0, 1] - C2*R1 # Rn = [R(n-2)] - Cn[R(n-1)] /n >= 3
Donde Rn es la combinación lineal buscada.
No hay comentarios:
Publicar un comentario