[C con Clase] Programa resolucion de sistema ecuaciones lineal

Facundo Curti facu.curti en gmail.com
Vie Sep 30 15:00:51 CEST 2016


El 26 de septiembre de 2016, 12:11, Davidson, Steven <srd4121 en njit.edu>
escribió:

> Hola Facundo,
>
> - El primer problema que veo en la implementación del algoritmo es en el
> 2º bucle 'for', que corresponde al paso #2 en el algoritmo, en la función
> 'sustAtras()'. El algoritmo indica que debes buscar el menor valor de 'p',
> pero tu implementación busca el valor de 'p' que corresponda al menor
> elemento de 'm[p][i]'. La implementación debería ser:
>
> for( p=i; p<n && m[p][i] == 0; p++ ) {}
>
> if( p == n )  // No se encontró ninguno
>   return nullptr;  // => retornamos un puntero nulo como error del
> algoritmo
>
> // Paso #3
> if( p != i )
> {
>   // Intercambio de filas: E[p] <-> E[i]
> }
>
> - Te falta la implementación del paso #8 antes del #9; esto es,
>
> // Paso #8
> resultados[n-1] = m[n-1][n] / m[n-1][n-1];
>
> - La implementación del paso #9 del algoritmo no es del todo correcta.
> Tienes que tener cuidado al "traducir" las cotas de los índices del
> algoritmo a las de C/C++ para que sus índices sean correctos al usarlos con
> los arrays. Reescribiendo tu código fuente, esto sería:
>
> for( int x=n-2; x>=0; x-- )  //Sustitución hacia atrás
> {
>   resultados[x] = m[x][n];
>   for( int y=x+1; y<n; y++ )
>   {
>     resultados[x] -= m[x][y]*resultados[y];
>   }
>
>   resultados[x] /= m[x][x];
> }
>
> - Por último, esta función debe retornar un puntero a 'float'. Debería ser,
>
> float* sustAtras( float m[10][11], int n )
> {
>   ...
>   return resultados;
> }
>
> Esto implica que tendremos un problema, ya que el array 'resultados' se
> destruirá al terminar esta función, al ser un array local al aámbito de
> 'sustAtras()'. Una solución es definir 'resultados' como estático; esto es,
>
> float* sustAtras( float m[10][11], int n )
> {
>   static float resultados[10];
>   ...
>   return resultados;
> }
>
> De esta manera, el array no se destruirá hasta que termine el programa.
>
> Otra solución es pasar el array resultante como parámetro a la función;
> esto es,
>
> bool sustAtras( float resultados[10], float m[10][11], int n )
> {
>   ...
>   return true;  // Todo ha ido bien
> }
>
> De esta manera, puedes comunicarte fuera de esta función para indicar si
> hubo algún error durante el algoritmo, en lugar de enviar mensaje
> directamente al usuario. Por ejemplo,
>
> int main()
> {
>   float resultados[10];
>   ...
>   if( sustAtras(resultados, matriz, n) )
>   {
>     printf("Resultados:\n");
>     for(int i=0; i<n; i++){
>         printf("\tx%d: %f", i+1, resultados[i]);  // Escribiste:
> resultados+i, lo cual es incorrecto en esta situación y sustituí %d por %f
> porque queremos 'float'
>     }
>   }
>   else
>     printf("El sistema no tiene una unica solucion\n");
>   ...
> }
>
>
> Espero que esto te ayude.
>
> Steven
>
>
> 2016-09-25 9:30 GMT-04:00 Facundo Curti <facu.curti en gmail.com>:
>
>> Hola lista!
>> Estoy haciendo un trabajo para la uni, la cosa es que hice un algoritmo
>> que permite resolver un sistema de ecuaciones lineales con el metodo de
>> sustitucion hacia atras.
>>
>> Este es el algoritmo: https://k61.kn3.net/E/6/D/C/3/4/C05.png
>>
>> Lamentablemente, el algoritmo esta explicado muy vagamente, o por lo
>> menos ami se me hizo dificil entenderlo.
>>
>> De cualquier forma, googleando y tratando de sacar el codigo por mi
>> cuenta, he logrado hacer un algoritmo que aplica gauss correctamente, sin
>> embargo, el codigo me falla al realizar la sustitucion hacia atras. (el
>> ultimo paso).
>>
>> Por ej, ingreso la siguiente matriz:
>> 1  -5  1  7
>> 10  0  20  6
>> 5  0  -1  4
>>
>> Y luego de aplicar gauss, la matriz resultante es esta:
>> 1  -5  1  7
>> 0  25  -6  -31
>> 0  0  22  -2
>>
>> Lo cual es correcto. Sin embargo, al momento de calcular el valor de las
>> variables, el resultado es este:
>>   x1=4  x2=8  x3=12
>>
>> Cuando en realidad debria ser:
>> x3=-2/22
>> x2=-31/25 - (-6*x3)
>> x1= 7/1 - (-5*x2) - (1*x3)
>>
>> Les adjunto el programa en C que hice, y tambien se los dejo en el
>> siguiente link de pastebin:
>> http://pastebin.com/ca1Y8dA9
>>
>> El lugar donde aparentemente esta el error es este:
>>
>>
>>    1.     //::::Aca es donde aparentemente esta el error::::
>>    2.     for(int x=n; x>0; x--){ //Sustitucion hacia atras
>>    3.         resultados[x]=m[x][n+1]/m[x][x]; //Es igual a su B
>>    4.
>>    5.         for (int y=x+1; y<n+1; y++) { //Le resto a eso las demas
>>    variables
>>    6.             resultados[x]=resultados[x]-m[x][y]*resultados[y];
>>    7.         }
>>    8.
>>    9.     }
>>
>>
>>
>> Por ultimo aclarar. Se que hay otros metodos para calcular Gauss (usando
>> pivotes), y que me ahorrarian hacer la sustitucion hacia atras, sin
>> embargo, el ejercicio me pide resolverlo de esta forma. (Luego también
>> tengo que hacer otros algoritmos que si usen pivote).
>>
>> Espero puedan ayudarme, perdon por un mensaje tan extenso. Muchas
>> gracias! :)
>>
>>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>



Perdón por haber demorado en responder. Estoy a full con otros trabajos
ademas de este, y fui adelantando en los otros.
Ya lo pude arreglar, muchas gracias! :) No quedó exactamente como decias,
pero funciona. Tenias razon un esto:

Tienes que tener cuidado al "traducir" las cotas de los índices del
> algoritmo a las de C/C++ para que sus índices sean correctos al usarlos con
> los arrays


Como decías, el error estaba a la hora de traducir los indices. Además, me
di cuenta que en ningún momento había colocado un return al codigo xD. De
todas formas, como decías, el array luego era destruido.
En definitiva, el codigo me quedó de la siguiente manera (también lo
adjunto):

http://pastebin.com/7nPft0Mu

Muchas gracias! :)
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20160930/b1f1146c/attachment-0001.html>
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: gauss (1).c
Type: text/x-csrc
Size: 2752 bytes
Desc: no disponible
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20160930/b1f1146c/attachment-0001.bin>


Más información sobre la lista de distribución Cconclase