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

 

 


Tema destacado: Introducción a Git (Primera Parte)


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 21
11  Sistemas Operativos / GNU/Linux / Re: Kali Linux 2021.4 Virtualbox no se escucha el audio y no hay sonido en: 22 Diciembre 2021, 22:56 pm
En "root" no pirula el sonido. Créate una cuenta de usuario y tendrás audio casi seguro.
12  Foros Generales / Foro Libre / Re: Qué canción estás escuchando ahora ? en: 22 Diciembre 2021, 22:53 pm
13  Foros Generales / Dudas Generales / Re: Deep and Dark Web en: 22 Diciembre 2021, 22:50 pm
No sé que sentido puede tener usar un Tails persistente. Para mi, desde el momento en que sea persistente deja de ser Tails, al menos en concepto, en el sentido original para el que se concibió.

Desde el momento en que se empieza a guardar unas cosas... ¡puede que se guarden otras!... y entonces... deja de ser Tails.
14  Foros Generales / Foro Libre / Re: Qué canción estás escuchando ahora ? en: 19 Diciembre 2021, 16:08 pm
Hablando del Boss. Esta me pone los pelos como escarpias. ¡Anda que no debieron pasar cosas "down in te valley"!...

"Me and Mary"... "my baby and I"...superfuerte...

"Down to the river"... vaya si habrá visto cosas el rio ése... Lo mejor es que se las guarda para él mismo... o los que por allí pasaron.

15  Foros Generales / Foro Libre / Re: Qué canción estás escuchando ahora ? en: 18 Diciembre 2021, 22:36 pm
16  Foros Generales / Foro Libre / Re: Qué canción estás escuchando ahora ? en: 18 Diciembre 2021, 18:03 pm
17  Seguridad Informática / Seguridad / Re: La mejor opcion para tener kali linux ? en: 13 Diciembre 2021, 11:37 am
No, pingu489, como ya te han comentado, una vez estás en lla MV no puedes arrancar el SO-USB desde dentro de la MV.

Las tres formas de trabajo son incompatibles entre sí: o trabajas arrancando con el SO-USB y el sistema reside ahí, o trabajas con el SO-Disco_duro, o trabajas con el SO-MV dentro de un sistema anfitrión.

Como ya te dije, desde la MV creo que no tendrás acceso a la tarjeta de red interna del ordenador, quizá en Mware sí, no lo sé porque no lo he usado, pero en VBox no. Quizá sí puedas trabajar con otra tarjeta adicional exterior, pero te advierto que puede no ser compatible, aségurate antes de conprar alguna si vas a hacerlo así.

Yo lo dejaría tal cómo lo tienes, en el ordenador "malo", o lo instalaría en un USB (no chino  :D).
18  Programación / Programación C/C++ / Re: Un algoritmo para calcular si un grafo es conexo o no en: 13 Diciembre 2021, 11:32 am
Serapis: gracias por la respuesta, completísima y exhaustiva; te ha debido de llevar un buen rato redactarla. Muchísima información; me tomará tiempo digerirla, e indagar. Lo dicho: gracias por tus conocimientos y dedicación.
19  Foros Generales / Dudas Generales / Re: ¿Cómo saber la contraseña de administrador en windows 10? en: 12 Diciembre 2021, 17:16 pm
Me parece que papá se va a cabrear mucho...  :silbar:
...
...
... ¡pero mucho mucho!...  :xD  :rolleyes:
20  Programación / Programación C/C++ / Un algoritmo para calcular si un grafo es conexo o no en: 12 Diciembre 2021, 15:15 pm
He escrito un código que compruebe si un grafo es o no conexo a partir de la matriz de adherencia del grafo. Creo que funciona, he hecho algunos ejemplos y parece que sí; adjunto unos gráficos. Supongo que debe de ser válido para otros. Pero me gustaría saber si a alguien se le ocurren contra-ejemplos, o si quiere exponer (puede ser por privado) una matriz de adherencia de un grafo (claro, yo los ejemplos que he hecho son a partir de grafos de los que conozco su representación gráfica en papel) para ver si funciona. Pero me gustaría probar con un grafo del que no conozca su representación gráfica en papel, sino solo su matriz de adherencia.

Pero sobre todo querría opiniones sobre el código, posibles fallos, y posibles mejoras. Solo opiniones generales, pseudocódigo quizá..., no hace falta código explícito; tampoco es para volver a escribirlo, que no tengo intención (salvo que vea fallos serios), sino para ver por dónde van los tiros.

Doy una idea general de cómo lo he hecho, luego expongo el código y luego pregunto las cosas que más me interesan.

La idea que se me ha ocurrido es algo parecido a "fuerza bruta". Se trata de recorrer todos los nodos que se pueda, a partir del primero. A partir del nodo inicial del grafo voy recorriendo un camino hasta que llega un nodo en el que no puedo ir más allá, doy marcha atrás y busco otro nodo para proseguir... y así sucesívamente. Voy yendo hacia adelante-atrás-adelante-atrás... Conforme voy agotando caminos posibles voy volviendo hacia atrás cada vez más, hasta que llega un punto en el que vuelvo al nodo de salida -después de haber ido explorando todos los caminos posibles-. En ese momento en el que he vuelto al nodo de partida veo si existe algún nodo al que no he llegado. Si existe es que el grafo es no conexo, ya que de haber habido un camino para llegar hasta él lo habría recorrido. Si no existen nodos sin visitar es que he llegado a todos y el grafo es conexo.

Ahora el código que he escrito y algunos ejemplos que he usado.

Código
  1. // Calcula si un grafo es conexo o no
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define ORDEN_MATR (num_nodos * num_nodos)
  6.  
  7. void intro_grafo (int num_nodos, int ** matr_adher);
  8. void procesa_grafo (int num_nodos, int nodo_actual, char * estado_nodo, int * camino, int posicion, char sentido, int ** matr_adher);
  9. char es_conexo (int num_nodos, char * estado_nodo); // =0 si existe algun estado_nodo [i] == 0 ; =1 en caso contrario
  10.  
  11. int main ()
  12. {
  13. int num_nodos; // Nº de nodos del grafo
  14. int ** matr_adher; // Matriz de adherencia del grafo
  15. int nodo_actual; // El que se está procesando en un momento dado
  16. char * estado_nodo; // 1 - si ya se ha pasado por él al menos una vez; 0 - en caso contrario
  17. int * camino; // Guarda los nodos que se van recorriendo
  18. int posicion; // subindice del arreglo camino [] que corresponde a nodo_actual
  19. char sentido; // 1 si se va avanzando hacia nodo no visitado; 0 - si se va retrocediendo a nodo ya visitado
  20. int i, j;
  21.  
  22. printf ("Introducir no. de nodos del grafo: ");
  23. scanf ("%d", &num_nodos);
  24. printf ("el numero es: %d\n", num_nodos);
  25. // Declara arreglos
  26. matr_adher = (int **) malloc ( ORDEN_MATR * sizeof (int *) ); // Filas
  27. for ( i=0; i < num_nodos; i++ )
  28. {
  29. matr_adher [i] = (int *) malloc ( num_nodos * sizeof (int) ); // Columnas
  30. }
  31. estado_nodo = (char *) malloc ( num_nodos * sizeof (char *) );
  32. camino = (int *) malloc ( num_nodos * sizeof (int *) );
  33.  
  34. // Inicializa variables
  35. for (i = 0; i < num_nodos; i++)
  36. for (j = 0; j < num_nodos; j++)
  37. matr_adher [i][j] = 0; // Por defecto ningun nodo esta conectado con nigun otro
  38. for (i = 0; i < num_nodos; i++)
  39. estado_nodo [i] = 0; // Al inicio no se ha visitado ningun nodo
  40. sentido = 1;
  41. posicion = 0;
  42. nodo_actual = 0;
  43. camino [0] = 0;
  44.  
  45. // Ejecucion
  46. intro_grafo (num_nodos, matr_adher);
  47. procesa_grafo (num_nodos, nodo_actual, estado_nodo, camino, posicion, sentido, matr_adher);
  48. if ( es_conexo (num_nodos, estado_nodo) )
  49. printf ("El grafo es conexo\n");
  50. else
  51. printf ("El grafo NO es conexo\n");
  52.  
  53. return 0;
  54. }
  55.  
  56. void intro_grafo (int num_nodos, int ** matr_adher)
  57. {
  58. int nodo1, nodo2, peso;
  59.  
  60. printf ("Introducir conexiones y pesos entre nodos en la forma:\n");
  61. printf ("nudo inicial... nudo final... peso conexion\n\n");
  62. printf ("No es necesario introducir conexiones reciprocas, la conexion i-j automaticamente es = a la j-i\n");
  63. printf ("Una nueva conexion i-j actualiza a la anterior si existiera\n");
  64. printf ("para finalizar el grafo introduzcir nudo incial = 0 y nudo final = 0\n\n");
  65. for (;;)
  66. {
  67. printf ("Nodo inicial: ");
  68. scanf ("%d", &nodo1);
  69. printf ("Nodo final: ");
  70. scanf ("%d", &nodo2);
  71. if (nodo1 == 0 && nodo2 == 0)
  72. return;
  73. else
  74. {
  75. printf ("Peso conexion: ");
  76. scanf ("%d", &peso);
  77. if (nodo1 != nodo2)
  78. {
  79. matr_adher [nodo1][nodo2] = peso;
  80. matr_adher [nodo2][nodo1] = peso;
  81. }
  82. printf ("\n");
  83. }
  84. }
  85. }
  86.  
  87. void procesa_grafo (int num_nodos, int nodo_actual, char * estado_nodo, int * camino, int posicion, char sentido, int ** matr_adher)
  88. {
  89. int j;
  90. printf ("\nfuncion procesa_grafo\n"); // SOLO PARA DEPURACION DEL PROGRAMA - BORAR
  91. printf ("nodo actual: %d\n", nodo_actual); // SOLO PARA DEPURACION DEL PROGRAMA - BORAR
  92. estado_nodo [nodo_actual] = 1;
  93. if ( (nodo_actual == 0) && (sentido == 0) )
  94. return;
  95.  
  96. for (j = 0; j < num_nodos; j++)
  97. if ( (matr_adher [nodo_actual][j] != 0) && (estado_nodo[j] == 0) )
  98. {
  99. posicion += 1; // Recorre la fila de la matriz del nodo en proceso hasta encontrar
  100. camino [posicion] = j; // una conexión con un nodo que no hay sido visitado anteriormente,
  101. sentido = 1; // si lo encuentra cambia el control del proceso a ese nodo
  102. procesa_grafo(num_nodos, j, estado_nodo, camino, posicion, sentido, matr_adher);
  103. }
  104.  
  105. posicion -=1; // Caso de recorrer toda la fila y no encontrar un nodo en avance
  106. sentido = 0;  // retrocede al nodo anterior y cambial el control del proceso a ese punto
  107. procesa_grafo (num_nodos, camino [posicion], estado_nodo, camino, posicion, sentido, matr_adher);
  108. }
  109.  
  110. char es_conexo (int num_nodos, char * estado_nodo)
  111. {
  112. int i;
  113. for (i = 0; i < num_nodos; i++)
  114. if ( estado_nodo [i] == 0 )
  115. return 0;
  116. return 1;
  117. }
  118.  

Algunos ejemplo que he hecho



Algunas consideraciones:
- He considerado que un nodo no puede estar conectado consigo mismo; para saber si los nodos están conectados entre sí no hace falta, y estorba para el algoritmo.
- También he considerado solamente grafos en los cuáles los nodos están conectados en ambas direcciones: si se puede ir desde a hacia b, entonces también se puede ir desde b hacia a. (Creo que existen grafos en los cuáles puede haber trayectorias en un sentido pero no en el contrario).
- El peso de la conexión únicamente es útil para saber si dos nodos están conectados (==0 SI // !=0 NO), daría igual que fuesen sencillamente 1 ó 0. He dejado cualuier entero solamente por generalidad de la función de entrada de datos (no se trata de calcular longitudes mínimas o máximas de distintos caminos). Incluso podrían ser negativos ya que el programa solo considera si son o no igual a cero.
- He utilizado un arreglo (camino []) y una variable (posicion) para ir recorriendo la malla. Aunque creo que se podría utilizar una pila LIFO y push-pop).

Defectos que ya veo:
- Si el nodo 0 está aislado el programa se pierde. Se podría corregir fácilmente haciendo que antes de comenzar a procesar se comprobara que la fila 0 de la matriz no es todo ceros; pero es trivial y no merece la pena; no afecta al algoritmo.
- He visto -a través de las líneas 90 y 91 que están solamente para depuración- que el algoritmo pasa varias veces por nudos que no haría falta (no afecta a la eficacia del código pero sí a la eficiencia del mismo: retardo). Veo que ésto es así por comenzar siempre el análisis de cada nuevo nodo (fila) desde cero (línea 96) en lugar de hacerlo desde el último nodo (columna) que se visitó a partir del nodo_actual. Pero no estoy muy seguro de cómo corregirlo; se me ocurre tener otro arreglo similar a camino [] en el cuál se anote ese nº de columna y comenzar el bucle de la línea 96 en ese lugar en vez de cero. No lo he hecho porque, bueno, lo que me importa es más bien que la idea general funcione, ya que no se trata de una aplicación práctica. Además añadiría más argumentos a la función procesa_grafo, que ya tiene bastantes.

Entonces:
- ¿Algún error de bulto? ¿Fallos, ejemplos de grafos que hagan que claramente el algoritmo no funcione...?
- ¿Alguna idea para corregir el bucle de la línea 96 y que no empiece desde cero?
- ¿Se mejoraría la eficiencia del programa usando una pila en lugar del arreglo y la posición?
- Y lo principal: ¿existiría otro tipo de algoritmo que no fuera recorrer todos los caminos posibles?; no sé, algo de tipo matemático, alguna propiedad matemática de la matriz de adherencia, algún método que use de expresiones matemáticas, en lugar de un algoritmo de recorrido paso a paso, que determine si el grafo es conexo o no. O en caso de algorimo de recorrido, ¿otra forma de hacer el recorrido que sea más eficiente?
- Por último: ¿alguna manera de programar más elegante (o eficaz) sin usar una función recursiva. Tengo entendido que los goto, las variables globales y la recursividad (por este orden) no son muy bienvenidas por los programadores ( al menos en C); y si se puede escribir un código más acorde a los usos habituales o deseables en programación, pues bienvenidos sean consejos.

Gracias de antemano por las respuestas.
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 21
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines