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

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [C] Determinante de orden N
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [C] Determinante de orden N  (Leído 5,220 veces)
BatchianoISpyxolo

Desconectado Desconectado

Mensajes: 166


Ver Perfil
[C] Determinante de orden N
« en: 29 Marzo 2013, 20:57 pm »

A partir del título de este post ( http://foro.elhacker.net/programacion_cc/determinante_matriz_de_orden_n-t352910.0.html )  me entró la curiosidad de resolverlo de manera dinámica. Y la manera que se me ocurría para un algoritmo sencillo pues es la regla de Laplace o el desarrollo por menores complementarios de manera recursiva:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define N 4
  6.  
  7. /* DETERMINANTE DE UNA MATRIZ de orden N - por MAFH */
  8.  
  9. typedef int ** matriz;
  10.  
  11. void visualizar_matriz (matriz matrix, int m, int n) {
  12.    int i,j;
  13.    for (i=0; i<m; i++) {
  14.        for(j=0; j<n; j++) {
  15.            printf("%d ", matrix[i][j]);
  16.        }
  17.        printf("\n");
  18.    }
  19. }
  20.  
  21. matriz generar_matriz (int m, int n) {
  22.    int i;
  23.    matriz temp;
  24.    if ((temp = (matriz) malloc(m*sizeof(int*))) == NULL)
  25.        return NULL;
  26.    for (i=0; i<m; i++)
  27.        if ((temp[i] = (int *)malloc(n*sizeof(int))) == NULL)
  28.            return NULL;
  29.    return temp;
  30. }
  31.  
  32. matriz copiar_matriz (matriz matrix, int m, int n) {
  33.    int i,j;
  34.    matriz temp = (matriz) generar_matriz(m,n);
  35.    if (temp != NULL) {
  36. for (i=0; i<m; i++)
  37. for (j=0; j<n; j++)
  38. temp[i][j] = matrix[i][j];
  39.    }
  40.    return temp;
  41. }
  42.  
  43. void liberar_matriz (matriz matrix, int m) {
  44.    int i;
  45.    for (i=0; i<m; i++)
  46.        free(matrix[i]);
  47.    free(matrix);
  48. }
  49.  
  50. void rellenar_matriz (matriz matrix, int m, int n) {
  51.    int i,j;
  52.    for (i=0; i<m; i++)
  53.        for(j=0; j<n; j++) {
  54.            printf("Valor de matrix[%d,%d] = ", i, j);
  55.            scanf("%d", &(matrix[i][j]));
  56.        }
  57. }
  58.  
  59. matriz adjunto_matriz (matriz matrix, int fila, int columna, int n) {
  60.    matriz adjunto = (matriz) generar_matriz(n-1,n-1);
  61.    if (adjunto != NULL) {
  62. int i, j, k=0, l=0;
  63. for (i=0; i<n; i++)
  64. for (j=0; j<n; j++) {
  65. if ((i != fila) && (j != columna)) {
  66. adjunto[k][l] = matrix[i][j];
  67. if (++l == n-1) {
  68. l=0;
  69. k++;
  70. }
  71. }
  72. }
  73.    }
  74.    return adjunto;
  75. }
  76.  
  77. int determinante (matriz matrix, int n) {
  78.    if (n == 1) {
  79.        return matrix[0][0];
  80.    } else {
  81.        int j;
  82.        int res = 0;
  83.        for (j=0; j<n; j++){
  84.            matriz adjunto = (matriz) adjunto_matriz(matrix, 0, j, n);
  85.            if (adjunto == NULL) exit(1);
  86.            res += pow(-1, (j%2))*matrix[0][j]*determinante(adjunto, n-1);
  87.            liberar_matriz(adjunto,n-1);
  88.        }
  89.        return res;
  90.    }
  91. }
  92.  
  93.  
  94. int main (int argc, char ** argv) {
  95.    matriz m = (matriz) generar_matriz(N,N);
  96.    rellenar_matriz(m,N,N);
  97.    visualizar_matriz(m,N,N);
  98.    printf("|M| = %d\n", determinante(m,N));
  99.    liberar_matriz(m,N);
  100.    return 0;
  101. }
  102.  

Aunque tenemos la constante N para el orden de la matriz, podemos utilizar una variable para que el usuario introduzca el orden, evidentemente.

Una ejecución del código con Valgrind:
Citar
pyxolo@ubuntu:~/Escritorio$ gcc -o det determinanteN.c -lm
pyxolo@ubuntu:~/Escritorio$ valgrind ./det -all
==4938== Memcheck, a memory error detector
==4938== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4938== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4938== Command: ./det -all
==4938==
Valor de matrix[0,0] = 2
Valor de matrix[0,1] = 3
Valor de matrix[0,2] = -4
Valor de matrix[0,3] = 2
Valor de matrix[1,0] = 9
Valor de matrix[1,1] = 11
Valor de matrix[1,2] = 0
Valor de matrix[1,3] = 3
Valor de matrix[2,0] = 2
Valor de matrix[2,1] = -4
Valor de matrix[2,2] = -5
Valor de matrix[2,3] = -6
Valor de matrix[3,0] = 21
Valor de matrix[3,1] = 100
Valor de matrix[3,2] = 2
Valor de matrix[3,3] = 3
2 3 -4 2
9 11 0 3
2 -4 -5 -6
21 100 2 3
|M| = -23240
==4938==
==4938== HEAP SUMMARY:
==4938==     in use at exit: 0 bytes in 0 blocks
==4938==   total heap usage: 105 allocs, 105 frees, 752 bytes allocated
==4938==
==4938== All heap blocks were freed -- no leaks are possible
==4938==
==4938== For counts of detected and suppressed errors, rerun with: -v
==4938== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Conclusión del desarrollo por menores:

Orden 1:
1 de orden 1
no llamadas recursivas

Orden 2:
2 de orden 1
2 = 2 llamadas recursivas

Orden 3:
3 de orden 2
2 de orden 1
3*2 = 6 llamadas recursivas

Orden 4:
4 de orden 3
3 de orden 2
2 de orden 1
4*3*2 = 24 llamadas recursivas

Orden 5:
5 de orden 4
4 de orden 3
3 de orden 2
2 de orden 1
5*4*3*2 = 120 llamadas recursivas

Orden n:
n de orden n-1
n-1 de orden n-2
.... de orden ...
3 de orden 2
2 de orden 1
n*(n-1)*(n-2)*(n-3)*...*(n-n+1) = (productorio desde i=n hasta 2 de i) = n! llamadas recursivas

Como conclusión a los resultados expuestos obtenemos que el número de llamadas recursivas que se realizan viene dado por:

Nº llamadas recursivas = Permutaciones(Orden) = Orden!


Como bien había dicho ghastlyX en respuesta al tema arriba enlazado.



Edit:

He tratado de lanzar el código con un determinante de orden 13 y evidentemente "no terminaba"...
Nº llamadas recursivas = P(13) = 13! = 6227020800

T(n) es exponencial y encima con los alojos y desalojos de memoria... Para morirse xD

Por otra parte, convendría generar los adjuntos con la misma matriz que se usa o de alguna manera sin generar otra matriz de tamaño n-1 para cada adjunto ._.


« Última modificación: 30 Marzo 2013, 02:31 am por BatchianoISpyxolo » En línea

Puede que desees aprender a programar desde 0: www.espascal.es
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: [C] Determinante de orden N
« Respuesta #1 en: 29 Marzo 2013, 21:41 pm »

Buena idea, yo hize también un algoritmo recursivo pero en C++... Andara por algun lugar de este foro.

El determinante es una operacion complej, hacer un determinante de 20x20 puede trardar semanas (y me quedo corto).


En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] Determinante de orden N
« Respuesta #2 en: 30 Marzo 2013, 05:11 am »


El determinante es una operacion complej, hacer un determinante de 20x20 puede trardar semanas (y me quedo corto).

Es que el sistema que utilizan es de "fuerza bruta".

Para hacerlo razonable habría que usar Gauss con/sin pivotes.

Saluditos!, ....
En línea

BatchianoISpyxolo

Desconectado Desconectado

Mensajes: 166


Ver Perfil
Re: [C] Determinante de orden N
« Respuesta #3 en: 30 Marzo 2013, 07:05 am »

Es que el sistema que utilizan es de "fuerza bruta".

Para hacerlo razonable habría que usar Gauss con/sin pivotes.

Saluditos!, ....


No, ya, ya. diagonalizar la matriz para obtener la solución con el producto de los elementos de la diagonal principal xD Pero para diagonalizar la matriz... xD No sabría como hacerlo de forma eficiente. Aunque bueno, debería tratar de pensarlo para afirmar eso xD
En línea

Puede que desees aprender a programar desde 0: www.espascal.es
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: [C] Determinante de orden N
« Respuesta #4 en: 31 Marzo 2013, 15:18 pm »

.......................................
Pero para diagonalizar la matriz... xD No sabría como hacerlo de forma eficiente.
........................................

No es tan complicado, al menos sin pivote. Un ejemplo:

Código
  1. /* Función para triangularizar una matriz */
  2. /************************************************/
  3. int triang(int N, double **a, double *b)
  4. {
  5.    int i, j, k, error;
  6.    double fac;
  7.    for (k=0; k<N-1; k++)
  8.        for (i=k+1; i<N; i++)
  9.            {
  10.                if (fabs(a[k][k])<EPS) return -1;
  11.                fac=-a[i][k]/a[k][k];
  12.                 for (j=k; j<N; j++)
  13.                    {
  14.                        a[i][j]+=a[k][j]*fac;
  15.                    }
  16.                b[i]=b[i]+b[k]*fac;
  17.  
  18.            }return 1;
  19. }
  20. /* Función para resolver un sistema triangular superior */
  21. /************************************************/
  22.  

Saluditos!. ...
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[C] Calcular determinante de una matriz de orden 'n'
Programación C/C++
Kasswed 9 39,711 Último mensaje 24 Enero 2013, 15:37 pm
por flony
Determinante matriz de orden 'N'
Programación C/C++
juancaa 1 12,257 Último mensaje 7 Febrero 2012, 12:29 pm
por ghastlyX
[C] [Source] Determinante Matriz orden "N"
Programación C/C++
juancaa 0 3,157 Último mensaje 13 Junio 2012, 02:26 am
por juancaa
Calcular determinante de una matriz NxN
Programación C/C++
amchacon 1 15,380 Último mensaje 13 Febrero 2013, 20:35 pm
por leosansan
[Vbs] Calculo de un determinante Algebra Lineal
Scripting
.:: KsV ::. 0 2,270 Último mensaje 11 Julio 2015, 23:20 pm
por .:: KsV ::.
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines