FACULTAD REGIONAL MULTIDISCIPLINARIA DE CARAZO IV Trabajo de Computación (Programación) Programa de doctorado en Matemática Aplicada Aprendizaje basado en la resolución de problemas, mediante la programación C Los arreglos bidimensionales y los parámetros por referencia Autores Cliffor Jerry Herrera Castrillo Norman Rafael López Sánchez Donald Ariel Hernández Muñoz Ileana María Martínez Méndez Docente: Dr. Harold Ramiro Gutiérrez Marcenaro. 09 Agosto 2019 Índice I. Introducción La programación y las matemáticas van de la mano, esto por la estrecha relación que existe entre ambas, si bien se dice que la programación nace de las matemáticas, las cuales son muy importantes y esenciales ya que todo código, sistema, circuito, software y algoritmo por muy sencillo que se vea las utiliza, esto conlleva a darle importancia al uso y entendimiento de esta, donde prácticamente todos los avances tecnológicos, los nuevos software, equipos entre otras cosas que son ahora la representación viva de los avances científicos, es la conformación pura de la matemática. Este informe aborda dos aspectos muy importantes que complementan el repertorio de conocimientos básicos que todo programador de computadoras debe poseer: Los arreglos bidimensionales y los parámetros por referencia. A través de los arreglos bidimensionales se pueden representar matrices numéricas y por ende se tiene la posibilidad de implementar a través de ellos una amplia gama de métodos matemáticos. Habitualmente, la forma de procesamiento de los arreglos bidimensionales es por filas y columnas, en ese orden, para lo cual se utilizan ciclos for anidados, que generalmente utilizan los índices i,j. La metodología de análisis del Problema único, de la cuarta evaluación del Módulo de Computación (programación), se basa en la explicación a detalle, describiendo la forma que se utilizó para llegar a la solución del problema, así mismo se hacen comentarios de los integrantes de este trabajo, los cuales contribuyeron a encontrar el algoritmo, que si bien es una forma de hacerlo existen otras (con variaciones) en dependencia del estilo del programador, además de forma implícita se presentan comentario sobre los aciertos y dificultades en la resolución del problema, resaltando el proceso heurístico inherente y la serendipia. II. Objetivos 1. Hacer uso de la programación estructurada, modular y descendente, para resolver problemas computacionales de nivel intermedio y avanzado. 2. Desarrollar técnicas de programación orientadas a la creación de programas robustos, eficaces, eficientes, expandibles y reutilizables. 3. Reconocer la importancia de la dimensión estética de la programación, que contribuya a la creación de su propio estilo como programador. III. Desarrollo EJERCICIO ÚNICO: La regla de Cramer es una técnica de solución adecuada cuando se tiene un sistema pequeño de ecuaciones. Su implementación requiere del cálculo de determinantes: Tomando como referencia a (Chapra & Canale, 2007, págs. 250-251): Determinantes: El determinante se puede ilustrar para un sistema de tres ecuaciones simultáneas: [A] {X} = {B} Donde [A] es la matriz de coeficientes: [A]= a11 a12 a13 a21 a22 a23 a31 a32 a33 El determinante D de este sistema se forma, a partir de los coeficientes del sistema, de la siguiente manera: D= a11 a12 a13 a21 a22 a23 a31 a32 a33 Aunque el determinante D y la matriz de coeficientes [A] se componen de los mismos elementos, son conceptos matemáticos completamente diferentes. Por esto, para distinguirlos visualmente se emplean corchetes para encerrar la matriz y líneas rectas verticales para el determinante. En contraste con una matriz, el determinante es un simple número. Por ejemplo, el valor del determinante de segundo orden D= a11 a12 a21 a22 Se calcula como D = a11a22 - a12a21 En el caso del determinante de tercer orden … el determinante, que es un simple valor numérico, se calcula así D= a11 a22 a23 a32 a33 - a12 a21 a23 a31 a33 + a13 a21 a22 a31 a32 Donde a los determinantes de 2 por 2 se les llama menores. … Regla de Cramer Esta regla establece que cada incógnita de un sistema de ecuaciones lineales algebraicas puede expresarse como una fracción de dos determinantes con denominador D y con el numerador obtenido a partir de D, al reemplazar la columna de coeficientes de la incógnita en cuestión por las constantes b1,b2,…,bn. Por ejemplo, x1 se calcula como x1= b1 a12 a13 b2 a22 a23 b3 a32 a33 D Realice un programa que implemente la técnica de la Regla de Cramer para la resolución de un sistema de tres ecuaciones. Tome en cuenta lo siguiente: a) Haga uso de la programación modular, diseñando subprogramas que realicen procesos específicos, dejando a la función main solamente las instrucciones más generales. b) Tome en consideración las recomendaciones y convenciones sobre el diseño de funciones y sobre el diseño de procedimientos. Diseñe el dialogo de interacción con el usuario de la manera más estéticamente posible y comunicacionalmente correcta, en función de la naturaleza del problema a resolver //Problema aplicando CRAMER #include <stdio.h> #include <conio.h> #define TAM 3 void llenarmatriz(int [][TAM], int [TAM]); void imprimirmatriz(int [][TAM], int resaltar=-1); int determinantematriz(int [][TAM]); int resolvervariable(int [][TAM], int [TAM], int); void esperar(); int main(){ int M[TAM][TAM]; // Una matriz de 3 x 3 int independientes[TAM]; // Los valores independientes de las 3 ecuaciones. llenarmatriz(M, independientes); clrscr(); printf("La matriz ingresada fue:\n\n"); imprimirmatriz(M); printf("Con valores independientes: \n"); textcolor(YELLOW); for(int i = 0; i < TAM; i++){ cprintf("%d", independientes[i]); printf("\n"); } textcolor(WHITE) esperar(); // Calcular el determinante de la matriz completa. int D = determinantematriz(M); int valores[TAM]; printf("El determinante de la matriz es: %d\n", D); if (D == 0){ printf("El sistema de ecuaciones no tiene una solucion definida.\n"); } else { // Recorrer cada columna en la matriz for(int i = 0; i < TAM; i++){ printf("\nResolviendo variable %d.\n", i+1); int valorvariable = resolvervariable(M, independientes, i); printf("El valor de la variable %d es: %d.\n", i+1, valorvariable); valores[i] = valorvariable; esperar(); } } printf("\nValores: x= %d, y= %d, z= %d.\n", valores[0], valores[1], valores[2]); printf("Saliendo\n"); //return 0; getch(); } void llenarmatriz(int M[TAM][TAM], int independientes[TAM]){ printf("Por favor, llene la matriz de tamano %d X %d\n\n", TAM, TAM); for(int i = 0; i < TAM; i++){ clrscr(); printf("Ecuacion %d: \n\n", i+1); for(int j = 0; j < TAM; j++){ printf("Matriz[%d][%d] = ", i+1, j+1); scanf("%d", &M[i][j]); printf("\n"); } printf("El valor independiente de la ecuacion %d es: ", i+1); scanf("%d", &independientes[i]); } } void imprimirmatriz(int M[TAM][TAM], int resaltar){ for(int i = 0; i < TAM; i++){ for(int j = 0; j < TAM; j++){ // Por si hay que resaltar la columna reemplazada // por los valores independientes. if (resaltar > -1 textcolor(YELLOW); cprintf("%4d", M[i][j]); textcolor(WHITE); } printf("\n"); } && j == resaltar) printf("\n"); } int determinantematriz(int M[][TAM]){ int determinante = 0; // El determinante se calculara con // la primera fila en la matriz. for(int k = 0; k < TAM; k++){ int cofactor = M[0][k]; // El cofactor o pivote para la determinante // Una matriz de 2x2 // con los elementos de la original // que no comparten fila ni columna // con el cofactor. int submatriz[TAM-1][TAM-1]; // Para llenar la matriz mas pequeña. int sub_i = 0; for(int i = 0; i < TAM; i++){ int sub_j = 0; if (i != k){ for(int j = 0; j < TAM; j++){ if(j != 0){ submatriz[sub_j][sub_i] = M[j][i]; sub_j++; } } sub_i++; } } // La diagonal primaria en el menor. int subdiagonalp = submatriz[0][0] * submatriz[1][1]; // La diagonal secundaria en el menor. int subdiagonals = submatriz[0][1] * submatriz[1][0]; int sub_determinante = subdiagonalp - subdiagonals; int resultado = cofactor * sub_determinante; // El resultado de este proceso alterna entre sumarse // y restarse al resultado final // Al ser de 3x3 la matrix, la unica ocasion en que // se resta es cuando el indice es 1. if (k == 1) { determinante -= resultado; } else { determinante += resultado; } } return determinante; } int resolvervariable(int M[TAM][TAM], int independientes[TAM], int var){ int D = determinantematriz(M); if(D == 0){ printf("No hay una solucion definida para el sistema de ecuaciones.\n"); } // Para aplicar la regla de Cramer // se debe reemplazar la columna de // la variable deseada (x, y, z) por // Los valores independientes. int reemplazada[TAM][TAM]; for(int i = 0; i < TAM; i++){ for(int j = 0; j < TAM; j++){ if (j == var){ // Si es la columna de la variable buscada // Se toma el valor independiente de esta fila. reemplazada[i][j] = independientes[i]; } else { reemplazada[i][j] = M[i][j]; } } } // Imprimir la matriz reemplazada resaltando los valores diferentes. imprimirmatriz(reemplazada, var); int Dvar = determinantematriz(reemplazada); printf("Determinante de %d: %d\n", var+1, Dvar); // El valor de la variable deseada es su determinante entre // el de la matriz original. return Dvar/D; } void esperar(){ printf("Presione una tecla par continuar...\n\n"); getch(); } Explicación Al correr el ejercicio (ver Carpeta comprimida Guía 4) se muestran lo que se obteniendo al final, para esto se ira detallando a continuación. Siempre se inicia declarando las bibliotecas a utilizar #include <stdio.h> #include <conio.h> El ejercicio pide 3 ecuaciones, las cuales fueron probadas y pide también el valor de los coeficientes las variables y los valores independiente Una matriz que es bidimensional va a tener 2 pares de arreglos, separados por corchetes, el primero representa la fila y el segundo es la columna, la primer fila será 2 en valor 11, 3 y 1 y luego se pide el valor independiente de la ecuación. Al pedir la segunda ecuación la fila cambia a 2, entonces 1 - 2 = 1 y el valor independiente de esa ecuación es cero, se pasa a la ecuación 3, el valor de la fila 3 es 3, 1 – 1 y el valor independiente es 3, los valores independientes 6, 0, 3 (cambia de color) según la regla debe calcular primero el determínate de la matriz, que es 21. Se resuelve la variable 1 (𝑥) donde se marca la columna que es sustituida por el término independiente, igualmente se realiza el cálculo de la variable 2 (𝑦) tomando en cuenta que la columna 2 será sustituida por los términos independientes y de igual manera se hace para la variable 3 (𝑧) considerando que los términos independientes sustituyen a la columna 3. #define TAM 3 void llenarmatriz(int [][TAM], int [TAM]); void imprimirmatriz(int [][TAM], int resaltar=-1); int determinantematriz(int [][TAM]); int resolvervariable(int [][TAM], int [TAM], int); void esperar(); int main(){ int M[TAM][TAM]; // Una matriz de 3 x 3 int independientes[TAM]; // Los valores independientes de las 3 ecuaciones. llenarmatriz(M, independientes); clrscr(); printf("La matriz ingresada fue:\n\n"); imprimirmatriz(M); printf("Con valores independientes: \n"); textcolor(YELLOW); for(int i = 0; i < TAM; i++){ cprintf("%d", independientes[i]); printf("\n"); } Retomando lo anterior el programa queda descrito de la manera siguiente. Se declara una variable constante TAM caracterizada por tener un valor constante asignado en el caso de este ejercicio es tres. Se hace uso de varias funciones, tomando la primera con la finalidad de llenar la matriz, la segunda que permita imprimir la matriz, esta sería la salida, una tercera para encantar determinante, la cuarta que permite el cálculo de las variables 𝑥, 𝑦, 𝑧 y por último una de mensaje. Se inicia el main. Una matriz 3x3 la que forma un arreglo bidimensional. Se declara una matriz unidimensional, a la cual se le pasa el tamaño y en ella se encontraran los valores de los términos independientes los cuales irán reemplazando a la columna de acuerdo con la variable que se esté utilizando. Se efectúa el llamado de la función llenar matriz a la cual se le pasa dos parámetros, estos corresponden a la matriz 3𝑥3 y la otra que es el arreglo bidimensional que corresponde a términos independientes. Se procede a digitar fila, en este caso la fila no se mueve, esta representa la ecuación, por tal razón ecuación 1 cambia hasta que se produce el cambio el primer par. Las filas están representadas por i, las que van de 0 hasta i y están relacionadas con el primer ciclo for. Se limpia pantalla con clrscr() Para efectos visuales se le sumo uno para que aparezca la ecuación con el número que le corresponde, pero se tiene claro que en los arreglos se inicia con cero. Las columnas representadas por 𝑗 desde 0 hasta 𝑗, se pide el valor de la matriz y de igual manera que se hizo con las filas se le suma 1 por efectos visuales. Se procede a leer lo digitalizado que se asigna a la matriz 𝑚. Se realiza un salto antes de pedir el valor de términos independientes, los que se asignan a la variable unidimensional. El cálculo del determínate se realiza fijando la primera fila y se eliminando la columna que corresponde a cada elemento de la fila lo cual da como resultados matrices de 2𝑥2. Se vuelve al main, después de llenada la matriz manda la matriz ingresada. Se llama la función imprimir matriz. Se pide imprimir la matriz 𝑚𝑖𝑗 Se hizo uso de cprin para poder darle color a la columna que se va sustituyendo por los valores independientes. Se continua con main y se llama la función esperar. Se procede a realizar el primer cálculo de la matriz completa que es el determinante, a la variable main declarada de tipo entero se le asigna una función que le pasa m, se busca la función llamada determinante matriz. El determinante se calcula en función de la primera fila que al que ser eliminada sus elementos serán cero y se utiliza una variable llamada K que corre hasta el tamaño, es así que se forma una submatriz luego de ir eliminando cada columna y su tamaño corresponde a fila menos 1 y columna menos 1 y para llenar la matriz 2x2 se utilizan dos ciclos for tanto para las filas i y las columnas 𝑗. Con la matriz 2𝑥2 se realiza el cálculo de diagonal principal y diagonal secundaria, cuya diferencia de ambas diagonales son asignadas a una variable la que será multiplicada por el cofactor. Se vuelve al main. En el cálculo del determinante se condiciona que si es cero el sistema no tiene solución porque toda división entre cero no está definida. Pero si el valor de la determinante es diferente de cero entonces se establece un ciclo for calcular el valor de cada variable de la matriz introducida. Se llama a imprimir los valores de cada incógnita como lo es 𝑋, 𝑌 𝑦 𝑍, en las posiciones 0,1 𝑦 2, con un retorno cuando ese sea cero. Se establece dos for 𝑖 y 𝑗, el valor j rellena la matriz internamente debido a que los arreglos seria [0][0] [0][1] [0][2] y hasta la fila dos que sería la última de la matriz. Se suma a 𝑖 y 𝑗 uno por observación de la matriz al momento de introducir los valores de cada ecuación en su arreglo. El determinante se calculará con la primera fila en la matriz. El cofactor o pivote para la determinante Una matriz de 2𝑥2 con los elementos de la original que no comparten fila ni columna con el cofactor. Para llenar la matriz más pequeña se define una nueva matriz con un arreglo menos como se menciona anteriormente. Se realiza este proceso para definir las determinantes de cada variable como lo implementamos el método de Cramer para calcular cada uno de sus valores correspondientes. La diagonal primaria en el menor y la diagonal secundaria en el menor. El resultado de este proceso alterna entre sumarse y restarse al resultado final Al ser de 3x3 la matriz, la única ocasión en que se resta es cuando el índice es 1. Recordar que en una matriz de 3𝑥3 se toma como referencia los signos de cada columna lo que es +, – 𝑦 +, sin estos no sería posible tener una respuesta significativa. Para aplicar la regla de Cramer se debe reemplazar la columna de la variable deseada (x, y, z) por los valores independientes. Si es la columna de la variable buscada Se toma el valor independiente de esta fila. Imprimir la matriz reemplazada resaltando los valores diferentes. El valor de la variable deseada es su determinante entre el de la matriz original. IV. Conclusiones Una vez analizado el problema y después de encontrar un modelo matemático adecuado para su solución y obtenido la información, que se generó conjuntamente con el análisis de cada programa, se procede a presentar las siguientes conclusiones, de acuerdo a los logros, dificultades y aprendizajes obtenidos: Se destaca la importancia de este trabajo tanto en su condición de investigación así como de la contribución al fortalecimiento en proceso de aprendizaje de doctorandos Una matriz que es bidimensional va a tener 2 pares de arreglos, separados por corchetes, el primero representa la fila y el segundo es la columna Dentro de las principales dificultades, se destaca el factor tiempo, para profundizar más a fondo, también dificultad para encontrar un algoritmo de solución Se realizó revisión documental vinculada con el tema de investigación, en diferentes fuentes, tales como libros, sitios web y videos. Ello permitió fundamentar cada problema hasta llegar a la elaboración y resolución de los mismos. Como aprendizaje por descubrimiento (Heurística), se constató que la programación modular es una de las técnicas fundamentales de la programación. Y que se apoya en el diseño descendente y en la filosofía de "divide y vencerás”. Además, como descubrimiento se encontró el algoritmo adecuado para evaluar y ejecutar de manera satisfactoria.