PRÁCTICA NΊ 1: 1 sesión
(del 8 de Marzo al 14 de Marzo de 2000)
Tipos Abstractos de Datos. Trabajo con Vectores y Matrices
0. Objetivo
El objetivo de esta práctica es la realización de dos programas. Uno para trabajar con vectores y otro para operar con matrices ambos con distintos tipos de datos: enteros y complejos. Para ello, el profesor dará al alumno dos unidades en Turbo Pascal (U_entero, U_comple) con las que deberán funcionar los programas principales sin modificaciones.
1. Tipos Abstractos de Datos
Un tipo abstracto de datos (TAD) es, básicamente, una colección de valores junto con unas determinadas operaciones definidas sobre ellos. Para el usuario del tipo abstracto de datos sólo importan los valores que puedan guardar las variables asociadas al TAD y las operaciones de manipulación del mismo, dejando para el programador la tarea de la implementación de la estructura o tipo de dato que soporte el TAD y de las operaciones relacionadas con él.
En esta práctica vamos a limitarnos a utilizar un determinado tipo abstracto de datos para implementar algunas operaciones habituales sobre matrices.
2. Unidades para la especificación de los tipos abstractos de datos "complejo" y "Entero"
Unidad para la manipulación del tipo "complejo". U_comple
Supongamos el tipo abstracto de datos Complejo, capaz de almacenar valores complejos (con componentes reales.) Este tipo abstracto de datos tiene asociadas las siguientes operaciones:
Procedure Iniciar_Valor ( Var a: Complejo );
Que inicia el contenido de la parte Real y de la parte Compleja del Valor a.
Procedure Ver_Valor ( a: Complejo );
Que muestra el valor complejo a.
Procedure Sumar_Valor ( a, b: Complejo; Var c: Complejo );
Que suma los valores complejos de a y de b y los guarda en c.
Procedure Resta_Valor ( a, b Complejo; Var c: Complejo );
Que resta los valores complejos de a y de b y los guarda en c.
Procedure Multiplicar_Valor ( a, b: Complejo; Var c: Complejo );
Que multiplica los valores complejos de a y de b y los guarda en c.
Procedure Dividir_Valor ( a, b: Complejo; Var c: Complejo );
Que divide los valores complejos de a y de b y los guarda en c.
Tanto el tipo de datos asociados a Complejo como las operaciones de manipulación del tipo Complejo estarán implementados en la unidad U_Comple proporcionada por el profesor de prácticas.
Unidad para la manipulación del tipo "Entero". U_entero
Supongamos el tipo abstracto de datos Entero, capaz de almacenar valores enteros. Este tipo abstracto de datos tiene asociadas las siguientes operaciones:
Procedure Iniciar_Valor ( Var a: Entero );
Que inicia el contenido del valor entero a.
Procedure Ver_Valor ( a: Entero );
Que muestra el valor entero a.
procedure Sumar_Valor ( a, b: Entero; Var c: Entero );
Que suma los valores enteros de a y de b y los guarda en c.
Procedure Resta_Valor ( a, b: Entero; Var c: Entero );
Que resta los valores enteros de a y de b y los guarda en c.
Procedure Multiplicar_Valor ( a, b: Entero; Var c: Entero );
Que multiplica los valores enteros de a y de b y los guarda en c.
Procedure Dividir_Valor ( a, b: Entero; Var c: Enteo );
Que divide los valores enteros de a y de b y los guarda en c.
Tanto el tipo de datos asociados a Entero como las operaciones de manipulación del tipo Entero estarán implementados en la unidad U_Entero proporcionada por el profesor de prácticas.
3. Trabajo con Vectores
Se pide realizar un programa en Turbo Pascal que permita realizar algunas operaciones sencillas con vectores, independientemente del tipo de valores almacenados en ellos.
La cabecera del programa será la siguiente:
Program Vectores ( Input, Output ); Uses [ U_Complej / U_Entero ] Const MAX = 20; Type Valor = [ Complejo / Entero ]; Indice = 1..MAX; Vector = Record info: Array [Indice] Of Valor; Num: Indice; End;
El programa deberá contener necesariamente los siguientes subprogramas:
Procedure Introducir_Vector ( Var vec: Vector );Procedimiento que pedirá el número de elementos del vector y los valores contenidos en el vector.
Procedure Ver_Vector ( vec: Vector );Procedimiento que mostrará por pantalla los valores almacenados en el vector.
Procedure Sumar_Vector ( ve1, ve2: Vector; Var res: Vector ): Boolean;Función que sumará los vectores ve1 y ve2 poniendo el resultado en res y devolviendo TRUE. Si los vectores no se pudieran sumar (número de elementos distinto) devolverá FALSE.
Function Multiplica_Escalar ( ve1, ve2: Vector; Var res: Valor ): Boolean;Función que multiplicará escalarmente los vectores ve1 y ve2 poniendo el resultado en res y devolviendo TRUE. Si los vectores no se pudieran multiplicar (número de elementos distinto) devolverá FALSE.
Function Multiplica_Vectorial ( ve1, ve2: Vector; Var res: Vector ): Boolean;Función que multiplicará vectorialmente los vectores ve1 y ve2 poniendo el resultado en res y devolviendo TRUE. Si los vectores no se pudieran multiplicar (número de elementos distinto) devolverá FALSE.
Advertencia: Sólo realizaremos la multiplicación vectorial de vectores de 3 componentes. Si los vectores tuvieran una dimensión distinta devolveremos FALSEEl programa principal se limitará a:
1.- Pedir dos matrices, vect1 y vect2.
2.- Mostrar los vectores vect1 y vect2 por pantalla.
3.- Multiplicar escalarmente los vectores y mostrar el resultado por pantalla. Si los vectores no se pueden multiplicar, informará de ello al usuario.
4.- Multiplicar vectorialmente los vectores y mostrar el resultado por pantalla. Si los vectores no se pueden multiplicar, informará de ello al usuario.
4. Trabajo Con Matrices
Realizar también un programa que trabaje con matrices, independientemente del tipo de valores que contengan.
La cabecera del programa será la siguiente:
Program Matrices ( Input, Output ); Uses [ U_Complej / U_Entero ] Const MAX = 20; Type Valor = [ Complejo / Entero ]; Indice = 1..MAX; Matriz = Record Info: Array [Indice, Indice] Of Valor; Col, Fil: Indice; End;
El programa deberá contener los siguientes subprogramas:
Procedure Introducir_Matriz ( Var mat: Matriz );Procedimiento que pedirá el número de filas y de columnas de la matriz y los valores contenidos en la matriz.
Procedure Ver_Matriz ( mat: Matriz );Procedimiento que mostrará por pantalla los valores almacenados en la matriz.
Function Sumar_Matrices ( ma1, ma2: Matriz, Var res: Matriz ): Boolean;Función que sumará las matrices ma1 y ma2 poniendo el resultado en res y devolviendo TRUE. Si las matrices no se pudieran sumar (número de filas o de columnas distintas) devolverá FALSE.
Function Restar_Matrices ( ma1, ma2: Matriz, Var res: Matriz ): Boolean;Función que restará las matrices ma1 y ma2 poniendo el resultado en res y devolviendo TRUE. Si las matrices no se pudieran restar (número de filas o de columnas distintas) devolverá FALSE.
Function Multiplicar_Matrices ( ma1, ma2: Matriz, Var res: Matriz ): Boolean;Función que multiplicará las matrices ma1 y ma2 poniendo el resultado en res y devolviendo TRUE. Si las matrices no se pudieran multiplicar (número de columnas de ma1 distinto del número de filas de ma2) devolverá FALSE.
El programa principal se limitará a:
1.- Pedir dos matrices, matriz1 y matriz2.
2.- Mostrar las matices matriz1 y matriz2 por pantalla.
3.- Sumar las matrices y mostrar el resultado por pantalla. Si las matrices no se pueden sumar, informará de ello al usuario.
4.- Restar las matrices y mostrar el resultado por pantalla. Si las matrices no se pueden restar, informará de ello al usuario.
5.- Multiplicar las matrices y mostrar el resultado por pantalla. Si las matrices no se pueden multiplicar, informará de ello al usuario.
En ningún caso se pide la utilización de menús ni opciones en estos programas.
En esta práctica, se trata, por un lado, de realizar un programa debidamente estructurado, mediante la utilización de subprogramas adecuados, y por otro, empezar a utilizar de forma estricta las normas de estilo de la Guía de Pascal. Las prácticas que no cumplan las normas de estilo serán mal calificadas.
En estos programas hay que tener en cuenta que deben funcionar correctamente tanto con el tipo Valor complejo, y la unidad U_Comple asociada, como con el tipo Valor Entero y la unidad U_Entero asociada, de manera que cualquier proceso de manipulación de los tipos Complejo y Entero se debe realizar a través de las operaciones definidas en las unidades anteriormente mencionadas, de forma que en los programas no aparezca ningún detalle que indique cómo se ha representado el tipo Complejo o el tipo Entero. Las soluciones que no cumplan este requisito serán consideradas incorrectas.
5. Trabajos Opcionales
Se propone como trabajo opcional:
Añadir al programa de trabajo con matrices las siguientes funciones:
y al programa principal el punto:
7.-Calcular la Inversa de la matriz matriz1 y calcular y mostrar por pantalla el resultado de multiplicar matriz1 por su inversa.
6. Entrega de programas
Al finalizar la sesión de prácticas se entregarán al profesor dos programas principales en Turbo Pascal llamados: Vectores.pas y Matrices.pas que cumpla los requisitos reseñados en el enunciado de la práctica.
ENTREGA DE PROGRAMAS: Al finalizar la sesión de prácticas correspondiente.
Cálculo del determinante
El cálculo del determinante se puede hacer de diversas maneras, pero se aconseja utilizar el método del desarrollo por filas o columnas.
Este método nos dice que el valor del determinante de una matriz cuadrada (n x n) es igual a la suma de los productos de los elementos de una columna (o fila) por los respectivos adjuntos.
Se llama adjunto, Aij, de un elemento aij perteneciente a una matriz, al producto del menor complementario del elemento por (-1)i+j. Y el menor complementario de un elemento aij es el determinante de orden n-1 que se obtiene eliminando la fila i y la columna j, del determinante original de orden n.
Así un determinante general de orden n será:
para cualquier valor de j.
El determinante de una matriz de 1x1 es el propio elemento almacenado en la matriz.
Con esta definición de determinante, es fácil construir una función recurrente que calcule el determinante, que contenga como condición de final el determinante 'trivial' (determinante de orden 1). Y como caso general el desarrollo por la fila o la columna 1.
Para la utilización de este método general de resolución de determinantes quizá sería necesaria la implementación de un subprograma que reduzca de una matriz la fila i y la columna j (elimine de la matriz los elementos correspondientes a la fila i y la columna j.)
Para más información acerca de la resolución del determinante podeis consultar la práctica 2: Tablas del curso 1998/99