René Mario Montante Pardo |
El mexicano René Mario Montante Pardo desarrolló en 1973 un método numérico que resuelve un sistema de ecuaciones en álgebra lineal utilizando solamente enteros, a diferencia del método de Gauss. No sólo eso, sino que con el mismo método se obtiene el determinante y la inversa de la matriz. El método es el más exacto que hay para encontrar la solución de un sistema de ecuaciones, ya que las presenta al final en forma de fracción y no pierde información en el camino, lo cual sí pasa con el método de Gauss - Jordan.
El método consiste en formar la matriz extendida C con las entradas de la matriz de coeficientes del sistema, la matriz identidad y el vector de las entradas independientes del sistema. Posteriormente es necesario ir cambiando las entradas de C por medio de la siguiente fórmula:
para k != i
C(k, l) = [(C(i,i)*C(k,l) - C(k,i)*C(i,l)]/pant;
Se utiliza un par de variables auxiliares llamadas pact (pivote actual) y pant ( pivote anterior). Al inicio pant = 1; y pact = C(i,i). Donde i corre desde 1 hasta N, N el número de ecuaciones del sistema. Los pivotes van tomando los valores de la diagonal principal. Al final, el número que queda en la diagonal principal es el determinante, lo que queda en lugar de la matriz identidad es la inversa y la última columna corresponde a la solución del sistema multiplicada por el último pivote actual (pact).
Como ejemplo, sea el sistema de ecuaciones
2x - y + z = 2 x + 3z = 4 2y + 2z = 4
Al añadir la matriz unidad se obtiene:
2 -1 1 1 0 0 2 1 0 3 0 1 0 4 0 2 2 0 0 1 4
en el primer paso ( i = 1) pact = 2 y pant = 1. Después del primer ciclo se obtiene
2 -1 1 1 0 0 2 0 1 5 -1 2 0 6 0 4 4 0 0 2 8
Aquí i = 2, pact = 1 y pant = 2. Al terminar este ciclo la matriz es:
1 0 3 0 1 0 4 0 1 5 -1 2 0 6 0 0 -8 2 -4 1 -8
Aquí i = 3, pact = -8 y pant = 1. Después de éste ciclo finalmente se obtiene la matriz:
-8 0 0 -6 4 -3 -8 0 -8 0 -2 4 -5 -8 0 0 -8 2 -4 1 -8
En lugar de la matriz del sistema se obtuvo
-8 0 0 0 -8 0 0 0 -8
Lo cual indica que el determinante de la matriz
2 -1 1 1 0 3 0 2 2
es -8
En tanto que la inversa de esta matriz es:
-6 4 -3 (1/-8) -2 4 -5 2 -4 1
y la solución del sistema es
-8 1 (-1/8) -8 = 1 -8 1
Lo cual indica que x = 1, y = 1, z = 1 es la solución.
A continuación se presenta el algoritmo en C. Este programa es completo, en el sentido de que es, creo, bastante amable con el usuario. Se puede cambiar la variable Tamano para resolver sistemas de cualquier tamaño.
#include <stdio.h> #define Tamano 3 // La variable Tamano controla el numero de ecuaciones del sistema // se puede cambiar facilmente para resolver sistemas de cualquier // tamano // Prototipos de funciones void Recibe(int Arreglo[][2*Tamano + 1]); void Imprime(int Array[][2*Tamano + 1]); void Calcula(int C[][2*Tamano + 1]); int main() { // Abre main int i; int j; printf("\nEste programa usa el metodo de Montante para calcular"); printf(" el determinante, la matriz inversa y la solucion de un"); printf(" sistema de %d ecuaciones lineales con %d incognitas.\n", Tamano, Tamano); // Se define una matriz que incluye la matriz de coeficientes, la unidad de // Tamano X Tamano y los terminos independientes del sistema int Matriz[Tamano][2*Tamano + 1] = { {0, 0} }; // Llamada a la funcion Recibe Recibe(Matriz); // Llamada a la funcion Imprime Imprime(Matriz); // Llamada a la funcion Calcula Calcula(Matriz); // Se llama a la funcion Imprime Imprime(Matriz); // Se imprime el determinante printf("\n\nEl determinante de la matriz es: %d\n", Matriz[0][0]); // Se imprime la matriz inversa printf("\n\n\nEsta es la matriz inversa:\n \n"); for ( j = 0; j < Tamano; j++ ) { // Abre for for ( i = Tamano; i < 2*Tamano; i++ ) { // Abre for anidado printf("\t%3d\t", Matriz[j][i]); } // cierra for anidado printf("\n"); if ( Tamano/2 - 1 == j ) printf("(1/%d)", Matriz[0][0]); } // Cierra for // Se imprime la solucion del sistema printf("\n\n\nA continuacion se presentan las soluciones del sistema."); printf(" Los numeros de la izquierda se refieren a la variable. \n"); for ( i = 0; i < Tamano; i++ ) { // Abre for printf("%3d\t = %6d/%d\n", i + 1, Matriz[i][2*Tamano], Matriz[0][0]); } // Cierra for return 0; } // Cierra main //////////////////////////////////////////////////////////// //FUNCION RECIBE ///////////////////////////////////////////////////////////// void Recibe( int Arreglo[][2*Tamano + 1]) { // Abre funcion Recibe int i; int j; int k; int l; int m; // Este par de ciclos reciben los coeficientes del sistema printf("\nSE RECIBEN LOS COEFICIENTES DEL SISTEMA: \n"); for ( i = 0; i < Tamano; i++ ) for ( j = 0; j < Tamano; j++ ) { // Abre for printf("\nPor favor introduzca el coeficiente %d de la ecuacion %d: ", j + 1, i + 1); scanf("%d", &Arreglo[i][j]); } // Cierra for // Este ciclo adiciona la matriz unidad de TamanoXTamano for ( k = 0; k < Tamano; k++ ) Arreglo[k][Tamano + k] = 1; // Este ciclo recibe los terminos independientes printf("\nSE RECIBEN LOS TERMINOS INDEPENDIENTES. \n"); for ( m = 0; m < Tamano; m++ ) { // Abre for printf("\nIntroduzca el termino independiente de la ecuacion %d: ", m + 1); scanf("%d", &Arreglo[m][2*Tamano ]); } // Cierra for } // Cierra funcion Recibe ////////////////////////////////////////////////// //FUNCION IMPRIME ////////////////////////////////////////////////// void Imprime(int Array[][2*Tamano + 1]) { // Abre la funcion Imprime int i; int j; printf("\n\n"); for ( i = 0; i < Tamano; i++ ) { // Abre for for ( j = 0; j < 2*Tamano + 1; j++ ) { // Abre for anidado printf("%3d\t", Array[i][j]); } // Cierra for anidado printf("\n"); } // Cierra for } // Cierra la funcion Imprime /////////////////////////////////////////////////////// //FUNCION CALCULA /////////////////////////////////////////////////////// void Calcula(int C[][2*Tamano + 1]) { // Abre funcion Calcula /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + El algoritmo requiere que se haga una copia de la matriz original + + Solo debe alterarse la matriz C cuando i se incrementa, esto se + + Introducir la sentencia + + B[k][l] = ( (C[i][i]*C[k][l]) - (C[k][i]*C[i][l]) )/pant; + + + + hace en la parte principal de la funcion + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ // Se definen las variables pact (pivote actual) y pant(pivote anterior) // ademas de variables controladoras de ciclos int B[Tamano][2*Tamano + 1]; int pant = 1; // Al principio pant = 1 int pact; int l; int k; int i = 0; int j; int s; int t; // El pivote siempre va tomando valores consecutivos de la diagonal // principal, esto se controla con la variable i en el siguiente ciclo // for for ( i = 0; i < Tamano; i++ ) { // Abre for // Se cambia el valor de pact pact = C[i][i]; /* Descomente estas lineas para ver la impresion de estas variables printf ("\npact = %d", pact); printf ("\npant = %d", pant); */ // Los siguientes ciclos controlan las columnas y las filas respectivamente for ( l = 0; l < 2*Tamano + 1; l++) for ( k = 0; k < Tamano; k++ ) { // Abre for anidado // El renglon sobre el que se ha tomado el pivote actual se deja intacta // esto se logra con el siguiente condicional if ( k != i ) { // Abre if // La asignacion de valores no se hace directamente sobre la matriz C sino sobre // una copia. Esto porque de lo contrario se estaria modificando la matriz con // la que se calcula cada vez que se asigna un nuevo valor B[k][l] = ( (C[i][i]*C[k][l]) - (C[k][i]*C[i][l]) )/pant; } // Cierra if } // Cierra for anidado // Se asigna los valores de la matriz A a la matriz C for ( s = 0; s < Tamano; s++ ) { // Abre for anidado for ( t = 0; t < 2*Tamano + 1; t++ ) { // Abre for anidado //Como el renglon del pivote actual (pact) no se modifico //entonces no se asigna en la variable original if ( s != i) C[s][t] = B[s][t] ; } // Cierra for anidado } /* Descomente estas lineas para ver la evolucion del algoritmo cada vez que cambia i printf("\n"); Imprime(C); */ // Se cambia el valor de pant pant = pact; } // Cierra for } // Cierra funcion Calcula
:) Muy bien. Aunque creo que se debe especificar que este método está pensado para coeficientes enteros de cada una de las variables (en tu código si lo manejas así)... del hecho de que calcule la inversa también se desprende que sólo debe funcionar para sistemas de nxn...
ResponderEliminarSaludos y gracias :)
por que al digitar todos los coeficientes, se sale el programa?.
ResponderEliminarNo me queda claro a qué te refieres exactamente. Si se sale debe ser un error. Probablemente estás haciendo referencia a algún elemento de arreglo que no es accesible. Ten cuidado con que las matrices sean de tamaño adecuado, sobre todo si estás cambiando el tamaño en el código. Si puedes ser más específico, tal vez te pueda ayudar mejor.
EliminarGracias funciona a la perfeccion, el programa, Se te agradece el codigo.
ResponderEliminarGracias.
EliminarPor que cuando hemos ingresado los valores al programa correctamente, al finalizar esperamos el resultado pero el programa se sale sin motivo alguno, estoy utilizando C ++ para compilar, de todos modos muchas gracias por el algoritmo :)
ResponderEliminarSeguro tiene que ver con que el programa se ejecuta tan rápido que no lo ves.
EliminarSi estás programando en Windows agréga al final la instrucción
cin.get();
y eso hará que la ejecución se detenga.
¡Saludos!
como seria de una matriz de 4x4
ResponderEliminarBro necesito ayuda con este mismo algoritmo de montante pero en lenguaje python no se si tu lo manejas , para ver si me puedes ayudar
ResponderEliminar