# Programación en Java/Apéndices/Implementación del algoritmo de Floyd en Java

El algoritmo de Floyd intenta resolver el problema de encontrar el camino más corto entre todos los pares de nodos o vértices de un grafo. Esto es similar a construir una tabla con todas las distancias mínimas entre pares de ciudades de un mapa, indicando la ruta a seguir para ir de la primera ciudad a la segunda. Esto puede verse de la siguiente manera:
* Sea G= (V, A) un digrafo en el cual cada arco tiene asociado un costo no negativo. El problema es hallar para cualquier par de vértices (v, w) el camino más corto de v a w.
* G= (V, A), V= {1,...,n} y C[i, j] es el costo del arco que va de i a j.
* El algoritmo calcula la serie de matrices
* Ak[i, j] significa el costo del camino más corto que va de i a j y que no pasa por algún vértice mayor que k.
* El objetivo es calcular An[i, j]
Además de eso, se busca hallar también el camino más corto entre cada par de nodos, imprimiendo así en el programa no solo la matriz final sino también dichos caminos.

## Solución al problema

La solución al problema se puede dar aplicando el algoritmo de Floyd para encontrar las distancias y caminos mínimos entre nodos. Una forma de implementar el algoritmo de Floyd en java es como se muestra en el siguiente fragmento de código. Se utilizó un enfoque dinámico, ya que se guardan valores en una matriz para luego reutilizarlos y no repetir operaciones.
El método recibe una matriz, en este caso la matriz de adyacencia del grafo. Para calcular las distancias mínimas se crea una matriz D, la cual irá guardando los resultados que arroja el algoritmo de Floyd, y otra matriz que guardará los caminos mínimos llamada enlaces. Los caminos mínimos se calculan, utilizando el los diferentes k, que son guardados en la matriz enl_aux, y utilizada en el método enlaces. El método enlaces, utiliza una llamada recursiva para recorrer la matriz de enlaces y arrojar el camino mínimo entre los nodos. Este resultado será guardado en la matriz enlaces[i][j].

## Limitaciones

Las limitaciones que se encontraron con el algoritmo no son muchas, mejor dicho, no se encontraron, a excepción que cuando se va a resolver un grafo muy grande, éste no halla la respuesta porque se presenta un desborde de memoria, ya que debe iterar y almacenar demasiados valores.

## Complejidad temporal

Este es el método principal, es decir, el que halla la solución del problema que se le plantee (la matriz de adyacencia):
TABLA 1. Calculo del T (n) :
| Instrucción | Tiempo |
| long adyacencia | 1 |
| int n=adyacencia.length | 1 |
| long D=adyacencia | 1 |
| String enlaces=new String [n][n] | 1 |
| String aux_enlaces=new String[adyacencia.length][adyacencia.length] | 1 |
| (1)for concatenados | $4n^{2}+4n+2$ |
| String enl_rec="" | 1 |
| (2)for concatenados | $bn^{4}+an^{3}+12n^{3}+4n^{2}+4n+2$ |
| enlaces (int i, int k, String aux_enlaces,String enl_rec) | 1 |
| if(aux_enlaces[i][k].equals("")==true) | 1 |
| return " | 1 |
| enl_rec+=enlaces (i, Integer.parseInt(aux_enlaces[i][k].toString),aux_enlaces,enl_rec)+(Integer.parseInt(aux_enlaces[i][k].toString)+1)+" , " | an+b |
| T (n)=$bn^{4}+an^{3}+12n^{3}+8n^{2}+8n+13$ y $O(n^{4})$ | |

## Forma de compilar y ejecutar

Para poder compilar y ejecutar el programa debe tener instalado en su computador el jdk de java 1.5 o una actualización más reciente y además debe tener el path de Windows configurado con el jdk.
Este programa está hecho en lenguaje java, por lo que se puede compilar y ejecutar en cualquier IDE que tenga soporte JAVA ; si usa Netbeans o Java Eclipse, debe primero crear un proyecto con el nombre que quiera, y crea tres clases con los correspondientes nombres usados en el código fuente y lógicamente pega dicho código en la clase. Si usa JCreator, puede bien sea, crear una única clase con el nombre de Aplicación y pega ahí todo el código fuente, o crea las tres clases con los nombres que son y pega el código fuente correspondiente en cada clase.

## Tiempo empleado

El tiempo que nos tardo desarrollar el programa fue aproximadamente 3 días, el primer día desarrollando el algoritmo de solución, el segundo día desarrollando la interfaz grafica, y el tercero corrigiendo las excepciones que se pudieran presentar.

## Pruebas

Esta es la matriz de adyacencia de un grafo que puede ser utilizada para probar la efectividad del algoritmo: La i representa infinito.
Matriz de adyacencia :
| | 1 | 2 | 3 | 4 |
| 1 | 0 | 5 | i | i |
| 2 | 50 | 0 | 15 | 5 |
| 3 | 30 | i | 0 | 15 |
| 4 | 15 | i | 5 | 0 |
La respuesta es:
Los caminos mínimos entre nodos son:
De ( 1 a 2 ) = ( 1 , 2 )
De ( 1 a 3 ) = ( 1 , 2 , 4 , 3 )
De ( 1 a 4 ) = ( 1 , 2 , 4 )
De ( 2 a 1 ) = ( 2 , 4 , 1 )
De ( 2 a 3 ) = ( 2 , 4 , 3 )
De ( 2 a 4 ) = ( 2 , 4 )
De ( 3 a 1 ) = ( 3 , 1 )
De ( 3 a 2 ) = ( 3 , 1 , 2 )
De ( 3 a 4 ) = ( 3 , 4 )
De ( 4 a 1 ) = ( 4 , 1 )
De ( 4 a 2 ) = ( 4 , 1 , 2 )
De ( 4 a 3 ) = ( 4 , 3 )

## Conclusiones

* Con las herramientas adecuadas y unos buenos fundamentos en programación, además de tener un conocimiento en grafos, se podría concluir que el algoritmo es fácil de implementar.
* Para hallar mejor la solución, es decir, la óptima, es mucho mejor usar el enfoque dinámico, ya que éste no repite operaciones y acelera un poco el proceso de solución.
* Cuando se implementa el algoritmo tiene una pequeña desventaja, y es que, debido a su enfoque dinámico, realiza un uso masivo de memoria, lo cual puede no ser muy conveniente si se están usando otras aplicaciones que requieran usar buena parte de la memoria.