Autor
|
Tema: Ayuda con implementacion algoritmo warshall en C (Leído 12,786 veces)
|
luar79
Desconectado
Mensajes: 12
|
Hola, necesito ayuda para implementar el algoritmo warshall, que ira recogiendo varias filas con dos ciudades, que se suponen que entre todas las ciudades hay conexion pasando a traves de otras. Entonces se busca con este algoritmo que vaya indicando si en cada fila devuelva true o false segun vaya recorriendo las filas. Yo al menos he entendido asi el problema. El primer problema que tengo es que, no consigo crear la matriz dinamica para guardar las ciudades en cada fila de la matriz, al leer de nuevo el fichero de texto se cuelga el programa, y no veo la razon. Vereis que he puesto varios printf(variable), para ver donde se quedaba colgado el programa, y muestra por pantalla el numero de filas. Y despues lo que no se es, en que tipo de variable debo recoger los resultados? en una matriz de tipo int?, y si es asi luego es ir recorriendo la matriz viendo cuantos 1, obtiene?y como discernir que por el numero de 1 que devuelve el algoritmo, no hay ninguna ciudad aislada?. Como imaginareis es un ejercicio que me han puesto, y estoy bloqueado desde hace dias haciendo pruebas. Pego el codigo: void warshall (bool *c, bool *a, unsigned int nNodos) { int i,j,k; for (i = 0; i < nNodos; i++) for (j=0; j< nNodos; j++) //A[i][j] = C[i][j]; a[(i*nNodos)+j] = c[(i*nNodos)+j]; for (k = 0; k < nNodos; k++) for (i = 0; i < nNodos; i++) for (j=0; j< nNodos; j++) //A[i][j] = A[i][j] || A[i][k] && A[k][j]; //Si hay un camino de ‘i’ a ‘j’ o si hay //un camino de ‘i’ a ‘j’ pasando por ‘k’ a[(i*nNodos)+j] = a[(i*nNodos)+j] || a[(i*nNodos)+k] && a[(k*nNodos)+j]; //Si hay un camino de ‘i’ a ‘j’ o si hay //un camino de ‘i’ a ‘j’ pasando por ‘k’ } int main() { FILE *fichero; bool *a; bool *test; int n_Nodos=19; char * campo; char ** datos; int filas=0; int MaxLinea=maxLinea; char lineaFinal[maxLinea]; char ciudad1[maxCiudad]; char ciudad2[maxCiudad]; char distancia[maxCiudad]; char linea[maxLinea]; fichero = fopen( "carreteras.txt", "r"); if(fichero==NULL) { printf("No se ha podido abrir el fichero.\n"); } else { while(fgets(linea ,MaxLinea ,fichero )) { filas++; } fichero = fopen( "carreteras.txt", "r"); datos =malloc(sizeof(char*)*filas ); // se lee cada fila de todo el fichero de elementos while(fscanf(fichero , "%s %s %s", ciudad1 , ciudad2 , distancia ) == 3) { datos[filas][0]=ciudad1; printf("El valor de la linea %s \n", ciudad1 ); datos[filas][1]=ciudad2; printf("El valor de la linea %s \n", ciudad2 ); datos[filas][2]=distancia; printf("El valor de la linea %s \n", distancia ); } } a = (bool *)malloc(sizeof(bool )*(n_Nodos * n_Nodos )); // aqui no tengo claro si se recoge asi los resultados del algoritmo int resul[filas][3]=warshall (a,datos,n_Nodos); return 0; }
Muchas gracias por la ayuda!
|
|
« Última modificación: 12 Mayo 2022, 20:27 pm por K-YreX »
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Pasa por aquí una copia del archivo de texto que usas.
|
|
|
En línea
|
|
|
|
luar79
Desconectado
Mensajes: 12
|
Vale, gracias:
Corunya Vigo 171 Corunya Valladolid 455 Vigo Valladolid 356 Valladolid Bilbao 280 Valladolid Madrid 193 Oviedo Bilbao 304 Bilbao Madrid 395 Bilbao Zaragoza 324 Madrid Zaragoza 325 Zaragoza Barcelona 296 Barcelona Gerona 100 Valencia Barcelona 349 Madrid Badajoz 403 Madrid Jaen 335 Madrid Albacete 251 Albacete Valencia 191 Albacete Murcia 150 Murcia Granada 284 Murcia Valencia 241 Granada Jaen 99 Granada Sevilla 256 Jaen Sevilla 242 Sevilla Cadiz 125
|
|
« Última modificación: 12 Mayo 2022, 23:48 pm por luar79 »
|
En línea
|
|
|
|
K-YreX
|
Ahora estoy que no se como en una matriz dinamica de cadenas de texto, compararla con una cadena de texto que seria una ciudad, y si coincide el campo de la matriz, se le da un valor numerico a esa ciudad Este problema está ya mencionado en el otro tema que abriste para esto mismo: https://foro.elhacker.net/programacion_cc/ayuda_con_fichero_y_cadenas_en_c-t514770.0.html
Me ha mostrado una tabla con 1 y 0, aunque no se si acertaba bien en las conexiones de los nodos Si no me he equivocado, esta matriz representa el número de ciudades por las que tienes que pasar para llegar desde la ciudad i hasta la ciudad j. (Por si te fias y quieres comparar) (0 = ya estás en esa ciudad | -1 = no se puede llegar de la ciudad i a la ciudad j) [INFO ] ---------- NODE LIST ---------- [ 0 - Corunya] [ 1 - Vigo] [ 2 - Valladolid] [ 3 - Bilbao] [ 4 - Madrid] [ 5 - Oviedo] [ 6 - Zaragoza] [ 7 - Barcelona] [ 8 - Gerona] [ 9 - Valencia] [10 - Badajoz] [11 - Jaen] [12 - Albacete] [13 - Murcia] [14 - Granada] [15 - Sevilla] [16 - Cadiz]
[INFO ] -------------------- WARSHALL MATRIX -------------------- 0 1 1 2 2 -1 3 4 5 4 3 3 3 4 5 4 5 -1 0 1 2 2 -1 3 4 5 4 3 3 3 4 5 4 5 -1 -1 0 1 1 -1 2 3 4 3 2 2 2 3 4 3 4 -1 -1 -1 0 1 -1 1 2 3 3 2 2 2 3 4 3 4 -1 -1 -1 -1 0 -1 1 2 3 2 1 1 1 2 3 2 3 -1 -1 -1 1 2 0 2 3 4 4 3 3 3 4 5 4 5 -1 -1 -1 -1 -1 -1 0 1 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 2 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 1 2 -1 -1 -1 -1 -1 -1 -1 2 3 1 -1 3 0 1 2 3 4 -1 -1 -1 -1 -1 -1 -1 2 3 1 -1 2 -1 0 1 2 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 0 1 2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 PD: Está hecho con el método mencionado en el otro tema al que hacía referencia.
Y otras cosillas: - A la función contar_filas() no necesitas pasarle filas/columnas como parámetros.
Basta con que pases el nombre del fichero y devuelvas con un return el número de filas. Debería quedar algo así: PD: Además debería limitarse a contar filas, no a "contar columnas" (cosa que no hace muy bien pues le has puesto el número de strtok() que tiene que hacer a mano)
int contar_filas(char *nombre_fichero);
- Las funciones auxiliares no deberían mostrar mensajes por pantalla a no ser que estén diseñadas específicamente para eso.
En la función contar_filas() por ejemplo, quedaría mejor devolver un -1 si no se puede abrir el fichero sin mostrar ningún mensaje ni salir con un exit()
Lo mismo para la función warshall(). Deja sólo la primera parte que modifica la matriz y luego muéstrala desde el main() o desde una función mostrar_matriz(). Los cambios que hagas en la matriz se mantendrán fuera también por lo que ten en cuenta que una vez llamas a warshall() has perdido tu matriz original. - De la parte del main() se te simplificaría utilizando la solución del enlace que hay al principio.
Además:
- No necesitas declarar filas/columnas como punteros.
- Utiliza constantes en lugar de número sueltos (ej: 17)
- Línea 82 -> Cuidado: Las multiplicaciones/divisiones se hacen antes que las sumas/restas (necesitas usar paréntesis)
Y por qué crear una matriz con 1 columna menos que el número de columnas que has "contado"?? Ahí algo de lógica está fallando - Línea 90 -> Cuidado: Estás guardando el valor de 'ciudad2' otra vez
- La última parte sobra por completo
Con eso yo creo que quedaría todo comentado
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
luar79
Desconectado
Mensajes: 12
|
Hola!, perdona no vi tu ultimo mensaje en el otro tema casualmente mientras me escribias este ultimo mensaje, estaba implementandolo con estructuras como sugerias en el otro tema. Y ya llama bien a al metodo warshall, pero creo devuelve mal los valores. Es que no me aclaro mucho con el metodo. Lo he tenido que modificar, porque si le implementaba tal como estaba, como le puedo asignar a una matriz de tipo bool, una matriz de tipo int que es donde van concatenadas las ciudades asignadas por una numeracion?. A mi me da como resultado la tabla con todos 1, supongo que no esta bien. En la tabla que compartes, el 0 es la ciudad actual, el -1 una ciudad inalcanzable, el 1 supongo que sera una ciudad alcanzable, pero los valores 4, 5 y 6 que aparecen en la tabla que significan. Pego el nuevo codigo por si esta muy mal lo repito, y si solo hay que retocarlo un poco lo del metodo warshall que la verdad es voy perdido como funciona, solo modifico ese metodo: En parte ya estaban las correciones que me has comentado, revisare las otras que no estan realizadas. Pego el codigo. Muchas gracias! struct ciudades { char ciudad1 [maxCiudad]; char ciudad2 [maxCiudad]; int distancia; }; /*void mas_corto(unsigned int c[][], unsigned int a[][], int P[][], unsigned int nNodos) { int i,j,k; for (i = 0; i < nNodos; i++) { for(j=0; j < nNodos; j++) { // Inicializamos con el coste de los caminos directos A[i][j] = C[i][j]; P[i][j] = -1; } } for (k = 0; k < nNodos; k++) for (i = 0; i < nNodos; i++) for (j=0; j< nNodos; j++) if (A[i][k]+A[k][j] < A[i][j]) { A[i][j] = A[i][k] + A[k][j]; P[i][j] = k; } } */ int contar_filas(int *filas) { FILE *fichero; char linea[maxLinea]; char * campo; fichero = fopen( "carreteras.txt", "r"); if(fichero==NULL) { printf("No se ha podido abrir el fichero.\n"); } else { while(fgets(linea ,maxLinea ,fichero )) { (*filas)++; } } return (*filas); } void warshall (int **A, unsigned int nNodos) { int i,j,k; for (k = 0; k < nNodos; k++) for (i = 0; i < nNodos; i++) for (j=0; j< nNodos; j++) A[i][j] = A[i][j] || A[i][k] && A[k][j]; //Si hay un camino de ‘i’ a ‘j’ o si hay //un camino de ‘i’ a ‘j’ pasando por ‘k’ for (int i=0; i<nNodos; i++) { for (int j=0; j<nNodos; j++) } } int main() { FILE *fichero; struct ciudades *city; int *filas=0, *columnas=0, clave=1; int cont=0, rows; char ciudad1[maxCiudad]; char ciudad2[maxCiudad]; char distancia[maxCiudad]; int **claves; fichero = fopen( "carreteras.txt", "r"); if(fichero==NULL) { printf("No se ha podido abrir el fichero.\n"); } else { filas=contar_filas(&filas); rows=filas; city =malloc(rows *sizeof(struct ciudades )); claves =malloc(rows *sizeof(int*)); for(int i=0; i<rows; i++) { claves [i ]=malloc(2*sizeof(int)); } // se lee cada fila de todo el fichero de elementos while(fscanf(fichero , "%s %s %s", ciudad1 , ciudad2 , distancia ) == 3) { strcpy(city [cont ]. ciudad1,ciudad1 ); strcpy(city [cont ]. ciudad2,ciudad2 ); city[cont].distancia=ciudad2; cont++; } } for(int i=0; i<rows; i++) { for(int j=0; j<2; j++) { if(strcmp(city [i ]. ciudad1,"Corunya")==0) claves[i][j]=1; if(strcmp(city [i ]. ciudad2,"Corunya")==0) claves[i][j]=1; if(strcmp(city [i ]. ciudad1,"Vigo")==0) claves[i][j]=2; if(strcmp(city [i ]. ciudad2,"Vigo")==0) claves[i][j]=2; if(strcmp(city [i ]. ciudad1,"Valladolid")==0) claves[i][j]=3; if(strcmp(city [i ]. ciudad2,"Valladolid")==0) claves[i][j]=3; if(strcmp(city [i ]. ciudad1,"Bilbao")==0) claves[i][j]=4; if(strcmp(city [i ]. ciudad2,"Bilbao")==0) claves[i][j]=4; if(strcmp(city [i ]. ciudad1,"Madrid")==0) claves[i][j]=5; if(strcmp(city [i ]. ciudad2,"Madrid")==0) claves[i][j]=5; if(strcmp(city [i ]. ciudad1,"Zaragoza")==0) claves[i][j]=7; if(strcmp(city [i ]. ciudad2,"Zaragoza")==0) claves[i][j]=7; if(strcmp(city [i ]. ciudad1,"Barcelona")==0) claves[i][j]=8; if(strcmp(city [i ]. ciudad2,"Barcelona")==0) claves[i][j]=8; if(strcmp(city [i ]. ciudad1,"Gerona")==0) claves[i][j]=9; if(strcmp(city [i ]. ciudad2,"Gerona")==0) claves[i][j]=9; if(strcmp(city [i ]. ciudad1,"Valencia")==0) claves[i][j]=10; if(strcmp(city [i ]. ciudad2,"Valencia")==0) claves[i][j]=10; if(strcmp(city [i ]. ciudad1,"Badajoz")==0) claves[i][j]=11; if(strcmp(city [i ]. ciudad2,"Badajoz")==0) claves[i][j]=11; if(strcmp(city [i ]. ciudad1,"Jaen")==0) claves[i][j]=12; if(strcmp(city [i ]. ciudad2,"Jaen")==0) claves[i][j]=12; if(strcmp(city [i ]. ciudad1,"Albacete")==0) claves[i][j]=13; if(strcmp(city [i ]. ciudad2,"Albacete")==0) claves[i][j]=13; if(strcmp(city [i ]. ciudad1,"Murcia")==0) claves[i][j]=14; if(strcmp(city [i ]. ciudad2,"Murcia")==0) claves[i][j]=14; if(strcmp(city [i ]. ciudad1,"Granada")==0) claves[i][j]=15; if(strcmp(city [i ]. ciudad2,"Granada")==0) claves[i][j]=15; if(strcmp(city [i ]. ciudad1,"Sevilla")==0) claves[i][j]=16; if(strcmp(city [i ]. ciudad2,"Sevilla")==0) claves[i][j]=16; if(strcmp(city [i ]. ciudad1,"Cadiz")==0) claves[i][j]=17; if(strcmp(city [i ]. ciudad2,"Cadiz")==0) claves[i][j]=17; } } warshall(claves,n_Nodos); return 0; }
Y el resultado que muestra por pantalla: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
|
« Última modificación: 13 Mayo 2022, 14:51 pm por K-YreX »
|
En línea
|
|
|
|
K-YreX
|
Al publicar código agrega en la primera etiqueta el lenguaje para facilitar un poco más la lectura. Tal que así: [code=c] Aquí pones tu código [/code] En los anteriores posts te lo he ido agregando yo pero para futuro.
En la tabla que compartes, el 0 es la ciudad actual, el -1 una ciudad inalcanzable, el 1 supongo que sera una ciudad alcanzable, pero los valores 4, 5 y 6 que aparecen en la tabla que significan. El valor del elemento [X][Y] es el número de ciudades por las que tienes que moverte para llegar desde la ciudad X hasta la ciudad Y. Es decir, cuando pone 1 significa que llegas directamente pero cuando pone 2 significa que tienes que pasar por una ciudad intermedia, y así sucesivamente...
A mi me da como resultado la tabla con todos 1, supongo que no esta bien. Esto es un problema de concepto. El algoritmo Warshall espera/trabaja con una matriz de entrada que está compuesta por 0s y 1s. El 0 en una casilla significa que no se puede llegar del elemento X al elemento Y y el 1 que sí que se puede. La implementación interna de la función warshall() parece correcta. El problema está en el input. La matriz que tú le estás haciendo llegar es la matriz 'claves' que no contiene la información esperada sino que contiene una serie de "índices" que has ido guardando tú en la parte final del código. Te recomiendo empezar resolviendo el problema sin memoria dinámica ya que sí que conoces el número de ciudades y sus nombres de antemano (Solución 1 del otro tema pero más simplificada). Realmente no necesitas una estructura para guardar cada "arista" del grafo compuesta por: {origen/ciudad1, destino/ciudad2, distancia}. Lo que sí necesitas es una forma de poder relacionar una ciudad con un número (índice). Ahora te voy a dar una solución más sencilla que la anterior. No necesitas ni crear structs: Puedes crear un array de cadenas y guardar todas las ciudades. El índice de cada ciudad será ni más ni menos que la posición que tiene esa ciudad en el array. #define NUM_CIUDADES 17 // Necesitaras usar 'define' en vez de 'const int' para esto si utilizas memoria dinamica int main() { char *ciudades[NUM_CIUDADES] = {"Valladolid", "Madrid", "Barcelona", ...}; }
El orden en que definas aquí las ciudades es indiferente pero hará variar la posición de los elementos en la matriz (no sus valores). El orden que usé en la solución mostrada antes fue: [Corunya, Vigo, Valladolid, Bilbao, Madrid, Oviedo, Zaragoza, Barcelona, Gerona, Valencia, Badajoz, Jaen, Albacete, Murcia, Granada, Sevilla, Cadiz] Ahora teniendo los pasos anteriores, debes crearte la matriz de entrada (la que luego le pasarás a la función warshall() para que trabaje con ella) Esta matriz contendrá 1s y 0s por lo que debería ser de tipo int (bool también es aceptable pero no deja de ser lo mismo -> 1 = true | 0 = false) #define NUM_CIUDADES 17 // Necesitaras usar 'define' en vez de 'const int' para esto si utilizas memoria dinamica int main() { char *ciudades[NUM_CIUDADES] = {"Valladolid", "Madrid", "Barcelona", ...}; int matriz_entrada[NUM_CIUDADES][NUM_CIUDADES] = {0}; // Asi inicializas toda la matriz a 0 }
De momento utiliza memoria estática y cuando lo tengas funcionando puedes agregarle la memoria dinámica. Y ahora lo que queda es recorrer el fichero (no necesitas contar el número de filas) e ir buscando el índice correspondiente que tiene cada una de las ciudades. Una vez hayas encontado ambos índices, guardas un 1 en esa posición porque el 1 significa que puedes llegar desde la ciudad origen hasta la ciudad destino y si has encontrado ambas ciudades en una línea del fichero realmente te da igual la distancia, ya sabes que sí se puede llegar. #define NUM_CIUDADES 17 const int MAX_NOMBRE_CIUDAD = 20; // En esta si puedes usar 'const int' en vez de 'define' int main() { char *ciudades[NUM_CIUDADES] = {"Valladolid", "Madrid", "Barcelona", ...}; int matriz_entrada[NUM_CIUDADES][NUM_CIUDADES] = {0}; // Asi inicializas toda la matriz a 0 char ciudad_origen[MAX_NOMBRE_CIUDAD]; char ciudad_destino[MAX_NOMBRE_CIUDAD]; int distancia; // Estrictamente hablando no necesitas ni guardar la distancia pero bueno, tampoco hacemos mal a nadie por ello // Otra cosa, al margen: Si al ver que el fichero no se abre, terminas la ejecucion, no necesitas despues poner un else, basta con poner el codigo seguido FILE *fichero = fopen("loquesea.txt", "r"); if(!fichero) { // Lo mismo que decir: fichero == NULL } while(fgets(fichero , "%s %s %d", ciudad_origen , ciudad_destino , &distancia ) == 3) { // Recordar que 'distancia' no es un puntero -> Necesitas usar & (creo que lo olvide la otra vez) printf("La distancia para ir de [%s] a [%s] es: %d\n", ciudad_origen , ciudad_destino , distancia ); // Por si no te fias que se este leyendo bien el fichero :) // Ahora viene la magia, necesitas saber que indices corresponden a 'ciudad_origen' y 'ciudad_destino' int indice_origen = buscarIndice(ciudad_origen, ciudades, NUM_CIUDADES); int indice_destino = buscarIndice(ciudad_destino, ciudades, NUM_CIUDADES); // Ahora puedes comprobar que ambas ciudades hayan sido encontradas o confiar... cuando programas es mejor desconfiar siempre y en la vida en general :( if(indice_origen != -1 && indice_destino != -1) matriz_entrada[indice_origen][indice_destino] = 1; // No necesitas guardar la distancia, basta con que pongas un 1 para saber que si se puede llegar } // Y ya estaria, ya tienes tu matriz_entrada con los 0s y 1s que necesita el algoritmo Warshall para trabajar warshall(matriz_entrada, NUM_CIUDADES); // Y como dije, yo dejaria que la funcion warshall() solo haga los calculos y luego ya los muestras cuando quieras for(int i = 0; i < NUM_CIUDADES; ++i) { for(int j = 0; j < NUM_CIUDADES, ++j) printf("%d ", matriz_entrada [i ][j ]); } }
Para que el código anterior funcione correctamente te faltaría implementar las funciones: // Devuelve el indice del elemento 'cadena' dentro del array 'cadenas'. Si no se encuentra, devuelve -1 int buscarIndice(char *cadena, char *cadenas[], int num_cadenas); // Reproduce el algoritmo Warshall contra la 'matriz_entrada' de orden (filas y columnas) indicado // Y por aclarar dudas, esta linea es la que te obliga a definir NUM_CIUDADES con 'define' y no con 'const int' void warshall(int matriz_entrada[][NUM_CIUDADES], int orden);
A partir de aquí ya sería agregar algunas mejoras como: - Utilizar memoria dinámica.
- Que la función warshall() no modifique la matriz_entrada sino que genere otra matriz para no perder los valores iniciales.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
luar79
Desconectado
Mensajes: 12
|
Muchisimas gracias! Lo voy probando en estos dias, a ver si lo consigo dejar correctamente hecho! Saludos!
|
|
|
En línea
|
|
|
|
luar79
Desconectado
Mensajes: 12
|
Hola!, he sacado un hueco para implementarlo, que voy a tope. Y me sale este resultado: 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Yo entiendo que todas las ciudades al final están conectadas unas con otras, no?. Osea desde Coruña puedes ir a Cadiz a través de las otras ciudades. Entonces no entiendo como la ultima fila da todo 0,s. Entiendo que la ultima fila es la de Cadiz en relación con las otras ciudades?. En ese caso llegando por Sevilla, hay conexión previa con las otras ciudades. No se si estaré entendiendo bien la interpretación del resultado Ahora eso si, la funcion buscar indices no se si la tengo muy afinada, porque solo me ha corrido el programa, declarando punteros como paso de variables. Adjunto el codigo: #define MAX_NOMBRE_CIUDAD 40 #define NUM_CIUDADES 17 int buscarIndice(char *ciudad, char *ciudades[NUM_CIUDADES], int numCiudades) { for(int i=0; i<numCiudades; i++) { if(strcmp(ciudad ,ciudades [i ])==0)return i ; } } void warshall(int A[][NUM_CIUDADES], int nNodos) { int i,j,k; for (k = 0; k < nNodos; k++) for (i = 0; i < nNodos; i++) for (j=0; j< nNodos; j++) A[i][j] = A[i][j] || A[i][k] && A[k][j]; } int main() { char *ciudades[NUM_CIUDADES] = {"Corunya", "Vigo", "Valladolid", "Bilbao", "Madrid", "Oviedo", "Zaragoza", "Barcelona", "Gerona", "Valencia", "Badajoz", "Jaen", "Albacete", "Murcia", "Granada", "Sevilla", "Cadiz"}; int matriz_entrada[NUM_CIUDADES][NUM_CIUDADES] = {0}; char ciudad_origen[MAX_NOMBRE_CIUDAD]; char ciudad_destino[MAX_NOMBRE_CIUDAD]; int distancia; FILE *fichero = fopen("carreteras.txt", "r"); if(!fichero) // Lo mismo que decir: fichero == NULL { printf("El fichero no ha podido abrirse\n"); } while(fscanf(fichero , "%s %s %d", ciudad_origen , ciudad_destino , &distancia ) == 3) { printf("La distancia para ir de [%s] a [%s] es: %d\n", ciudad_origen , ciudad_destino , distancia ); int indice_origen = buscarIndice(ciudad_origen, ciudades, NUM_CIUDADES); int indice_destino = buscarIndice(ciudad_destino, ciudades, NUM_CIUDADES); if(indice_origen != -1 && indice_destino != -1) matriz_entrada[indice_origen][indice_destino] = 1; } warshall(matriz_entrada, NUM_CIUDADES); for(int i = 0; i < NUM_CIUDADES; ++i) { for(int j = 0; j < NUM_CIUDADES; ++j) printf("%d ", matriz_entrada [i ][j ]); } return 0; }
Muchas gracias de nuevo por la aclaración!
|
|
« Última modificación: 18 Mayo 2022, 19:38 pm por K-YreX »
|
En línea
|
|
|
|
luar79
Desconectado
Mensajes: 12
|
Hola de nuevo,
porque en lo que me piden en este ejercicio es comprobar que no existen ciudades aisladas o ciudades inalcanzables partiendo desde otra ciudad, y viendo a simple vista el fichero de texto, todas las ciudades estan conectadas. Entonces entiendo que deberia dar todo 1 el resultado del algoritmo no?
Gracias de nuevo!
|
|
|
En línea
|
|
|
|
K-YreX
|
Hola de nuevo,
porque en lo que me piden en este ejercicio es comprobar que no existen ciudades aisladas o ciudades inalcanzables partiendo desde otra ciudad, y viendo a simple vista el fichero de texto, todas las ciudades estan conectadas. Entonces entiendo que deberia dar todo 1 el resultado del algoritmo no?
Gracias de nuevo!
El algoritmo de Warshall trabaja con grafos dirigidos. Es decir que una conexión: A->B no implica que haya una conexión: B->A. En el fichero de texto te dan los datos para ir de la 'ciudad_origen' a la 'ciudad_destino' pero no puedes ir en dirección contraria. De ahí los resultados de tu matriz, que son correctos. A Cádiz sí puedes llegar desde algunas ciudades (última columna) pero desde Cádiz no puedes ir a ninguna (última fila). Para que pudieras ir desde Cádiz a otra ciudad tendrías que tener al menos una línea del fichero que empezara por Cádiz, y no es así. Por otro lado: int buscarIndice(char *ciudad, char *ciudades[NUM_CIUDADES], int numCiudades) { for(int i=0; i<numCiudades; i++) { if(strcmp(ciudad ,ciudades [i ])==0)return i ; } }
Está función tiene un pequeño problema... Qué pasa si no encuentras la ciudad entre todas las ciudades?? No tienes un return por defecto por lo que la comprobación que haces en el main de si los índices son distintos de -1 no tiene sentido. Estas pequeñas cosas son las que hacen que se note que tu código es copiado...
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Algoritmo de Warshall
Java
|
atrillosu
|
3
|
11,733
|
10 Mayo 2010, 01:43 am
por h0oke
|
|
|
Ayuda con Algoritmo de warshall
Java
|
gallagher_daniel
|
1
|
2,041
|
11 Junio 2015, 15:41 pm
por Usuario Invitado
|
|
|
Ayuda para usar Algoritmo de Warshall
Programación C/C++
|
Deivbid
|
2
|
2,643
|
23 Noviembre 2015, 03:17 am
por Deivbid
|
|
|
Ayuda Antes de Usar el Algoritmo de Warshall
Programación C/C++
|
Deivbid
|
3
|
2,579
|
23 Noviembre 2015, 04:06 am
por 0xFer
|
|
|
Algoritmo de Floyd Warshall
Programación C/C++
|
Luisyoxd
|
1
|
3,154
|
6 Marzo 2020, 12:42 pm
por 98Fran
|
|