elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Resolución de sistemas de ecuaciones lineales de grado "n"
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Resolución de sistemas de ecuaciones lineales de grado "n"  (Leído 1,078 veces)
fzp

Desconectado Desconectado

Mensajes: 130


Ver Perfil
Resolución de sistemas de ecuaciones lineales de grado "n"
« en: 30 Diciembre 2021, 22:38 pm »

Dejo aquí un método -que creo que funciona- para la resolución de un sistema de "n" ecuaciones lineales con "n" incógnitas.
Está basado en el algoritmo de Gauss (no sé si otros lo llaman de Gauss-Jordan u otros de Gauss-Jacobi). Sea como sea que lo llamen consiste en dejar la matriz de coeficientes en una matriz triangular con 0 (ceros) por debajo de la diagonal principal de a matriz de coeficientes. Y luego ir resolviendo despejando in cógnitas de atrás hacia delante.

Sé que es un método poco eficiente. Para empezar los errores de cálculos sucesivos (especialmente en sistema muy grandes con muchas ecuaciones) pueden producir desbordamientos (overflow) o que, si hay términos relativamente pequeños respecto a otros, se produzcan reducciones a "1" que desvirtúen el resultado final, para sistemas de ecuaciones muy particulares. Como mi intención es simplemente una primera aproximación para reslover sistemas del tipo de los que se dan en Ingeniería (cálculo de estructuras, mallas de tuberías, etc...) de momento éso no me importa demasiado.

También la forma de introducir los datos es totalmente ineficiente -a mano-. Es sólo para pruebas; lo suyo es que sea a partir de datos de matrices que previamente se hayan almacenado en disco. Es más, esas matrices no se introducirán a mano -ni siquiera en disco- sino que provendrán de otros programas que las habrán guardado en disco a partir de otros datos (matrices de rigidez de una estructura -de construcción- a partir de sus datos de longitud de barras, inercia, material, etc; o longitud de tubería, diámetro, material, persión, etc...).

Por lo tanto, el hecho de la forma de introducción de datos no debe de ser valorado; solo el funcionamiento del algoritmo de resolución del sistema.

Por lo tanto, respecto al programa en general, me gustaría tener opiniones sobre:
- Sobre todo: ¡fallos que pueda tener! - He probado varios sistemas, algunos con bastantes incógnitas, y los ha resuelto. He probado varios sistemas con fallos "evidentes" (filas = 0; columnas = 0; filas/columnas = combinación lineal de otras filas/columnas;...) y me los ha detectado. En ese sentido, mi miedo es más bien -no que no me detecte sistemas sin solución-, sino que sistemas que SÍ tienen solución, me los detecte como que no la tienen. ¿Veis algún fallo? ¿Alguna forma de mejorarlo?

- ¿Se podría mejorar, mediante un algoritmo iterativo, la solución? He visto cosas, pero ninguna lo suficientemente clara -para mi- sobre cómo mejorar una solución a partir de una primera solución. En concreto he leído sobre los métodos de Richardson, de Jacobi, de Gauss-Seidel, que incluso empiezan con vectores/matrices de soluciones "alejadas" de la solución verdadera; cuando se podría mplementar desde una primera solución "muy aproximada" - la que ofrece el algoritmo que aquí se da-; pero no sé como implementarla.

- Por último: sé que hay un método muy potente (y con reducción de operaciones y de tiempo de cálculo y de disminución por errores de operaciones (¡justo lo que quiero disminuir!) que es la "condensación de ecuaciones"..., pero no encuentro información viable. Si alguien me puede ofrecer literatura sobre ese tema, pues estaría genial.

Bueno, aquí dejo el código que he hecho, para las críticas/comentarios/ayudas/mejoras/etc... que creáis convenientes (cualquier cosa será bien recibida):

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void intro_sistema (int n, double ** a);
  5. void combina_fila (int j, int n, double ** a); // Para dejar coeficientes de la columna a cero
  6. void intercambia_fila (int i, int j, int n, double ** a); // Para que no haya coefic. == 0 en la diagonal
  7. void calcula_incognitas (int n, double ** a, double * solucion); // A partir de una matriz ya triangular
  8.  
  9. int main ()
  10. {
  11. int n; // numero ecuaciones lineales
  12. int i, j;
  13. double ** a = NULL; // matriz ampliada: coeficientes | terminos independientes
  14. double * solucion = NULL;
  15.  
  16. printf ("Introducir no. de ecuaciones: ");
  17. scanf ("%d", &n);
  18.  
  19. a = (double **) malloc ( n * sizeof (double *) ); // filas
  20. for (j = 0; j < n; ++j)
  21. a[j] = (double *) malloc ( (n+1) * sizeof (double) ); // columnas
  22. solucion = (double *) malloc ( n * sizeof (double) );
  23.  
  24. intro_sistema (n, a);
  25.  
  26. for (j = 0; j < n-1; j++)  // Procesa elementos diagonal matriz coeficientes
  27. {
  28. if (a[j][j] == 0)
  29. {
  30. for (i = j+1; i < n; i++) // Busca un coeficiente de la misma columna != 0
  31. {
  32. if (a[i][j] != 0)
  33. {
  34. intercambia_fila (i, j, n, a);
  35. break;
  36. }
  37. printf ("\n\nEl sistema no tiene solucion unica"); // No hay coficiente != 0 sobre el que pivotar
  38. return 0;
  39. }
  40. }
  41. combina_fila (j, n, a);
  42. }
  43.  
  44. if (a[n-1][n-1] == 0)
  45. {
  46. printf ("\n\nEl sistema no tiene solucion unica\n"); // Toda la fila inferior es de ceros
  47. return 0;
  48. }
  49. else
  50. {
  51. calcula_incognitas (n, a, solucion);
  52. printf ("\n\n");
  53. for (j = 0; j < n; j++)
  54. printf ("soluc[%d] = %lf\n", j, solucion[j]);
  55. }
  56. return 0;
  57. }
  58.  
  59. void intro_sistema (int n, double ** a)
  60. {
  61. int i, j;
  62. double var;
  63.  
  64. printf ("\nIntroducir matriz de coeficientes del sistema de ecuaciones lineales\n");
  65. for (i = 0; i < n; i++)
  66. for (j = 0; j < n; j++)
  67. {
  68. printf ("a[%d][%d] = ", i, j);
  69. scanf ("%lf", &var);
  70. a[i][j] = var;
  71. }
  72. printf ("\nIntroducir terminos independientes del sistema\n");
  73. for (i = 0; i < n; i++)
  74. {
  75. printf ("b[%d] = ", i);
  76. scanf ("%lf", &var);
  77. a[i][n] = var;
  78. }
  79. }
  80.  
  81. void combina_fila (int j, int n, double ** a)
  82. {
  83. double factor;
  84. int i, k;
  85.  
  86. for (i = j+1; i < n; i++)
  87. {
  88. if (a[i][j] != 0)
  89. {
  90. factor = -a[j][j] / a[i][j];
  91. for (k = j; k < n+1; k++)
  92. a[i][k] = (factor * a[i][k]) + a[j][k];
  93. }
  94. }
  95. }
  96.  
  97. void intercambia_fila (int i, int j, int n, double ** a)
  98. {
  99. double var_intercamb;
  100. int k;
  101.  
  102. for (k = j; k < n+1; k++)
  103. {
  104. var_intercamb = a[i][k];
  105. a[i][k] = a[j][k];
  106. a[j][k] = var_intercamb;
  107. }
  108. }
  109.  
  110. void calcula_incognitas (int n, double ** a, double * solucion)
  111. {
  112. double acumulador;
  113. int i, j;
  114.  
  115. solucion[n-1] = a[n-1][n] / a[n-1][n-1];
  116. for (i = n-2; i >= 0; i--)
  117. {
  118. acumulador = a[i][n];
  119. for (j = i+1; j < n; j++)
  120. acumulador = acumulador - (a[i][j] * solucion[j]);
  121. solucion[i] = acumulador / a[i][i];
  122. }
  123. }
  124.  

Pues nada, lo dicho, que se agradece cualquier comentario.


« Última modificación: 30 Diciembre 2021, 22:40 pm por fzp » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Resolucion de ecuaciones de segundo grado y primer grado tmb :s
Java
Debci 8 13,280 Último mensaje 8 Noviembre 2009, 12:59 pm
por Debci
Resolucion de sistemas de ecuaciones sencillos
Java
Debci 6 6,789 Último mensaje 1 Abril 2010, 15:58 pm
por Debci
Ecuaciones Diferenciales de orden superior homogeneas lineales
Foro Libre
¡Micronet! 0 1,731 Último mensaje 16 Octubre 2010, 03:38 am
por ¡Micronet!
[Matemática] Resolviendo sistemas de ecuaciones lineales modulares.
Foro Libre
APOKLIPTICO 9 8,091 Último mensaje 5 Diciembre 2010, 05:17 am
por APOKLIPTICO
recursos visual basic, """"""proceso inmortal"""""
Análisis y Diseño de Malware
Dark4ngel 7 10,356 Último mensaje 3 Noviembre 2011, 10:42 am
por Dark4ngel
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines