Estoy usando common.graph de Google Guava en la versión 21.0 . Se adapta muy bien a mi caso de uso sin un aspecto: persistencia. El gráfico parece estar solo en la memoria. Las clases de gráficos no implementan Serializable , se explicó en las publicaciones de este problema .
Google describe tres modelos para almacenar la topología . La tercera opción es:
un repositorio de datos separado (por ejemplo, una base de datos) almacena la topología
Pero eso es todo. No encontré ningún método en el paquete para aplicar un repositorio de datos separado. ¿Hay alguna manera de hacer esto? ¿O es la única forma de usar el método nodes() y edges() para obtener un Set de mis nodos y un Set de mis bordes? Puedo conservarlos en una base de datos si implemento Serializable en estas clases y restauro el gráfico llamando a addNode(Node) y addEdge(Source, Target, Edge) (no hay métodos addAll). Pero esto parece ser una solución.
¡Gracias por su apoyo!
Para recapitular brevemente el motivo por el cual las clases common.graph de Guava no son Serializable : la serialización de Java es frágil porque depende de los detalles de la implementación, y eso puede cambiar en cualquier momento, por lo que no la admitimos para los tipos de gráficos.
En el corto plazo, su solución alternativa propuesta es probablemente su mejor apuesta, aunque deberá tener cuidado de almacenar los puntos finales (origen y destino) de los bordes junto con los objetos del borde para que pueda reconstruir el gráfico como tú describes. Y, de hecho, esto también puede funcionar para usted a largo plazo, si tiene una base de datos con la que está satisfecho y no necesita preocuparse por la interoperabilidad con nadie más.
Como mencioné en ese problema de GitHub , otra opción es conservar su gráfico en algún tipo de formato de archivo. (Guava en sí no proporciona un mecanismo para hacer esto, pero JUNG lo hará para gráficos common.graph una vez que pueda sacar 3.0, en el que todavía estoy trabajando). Tenga en cuenta que la mayoría de los formatos de archivos de gráficos (al menos los que yo estoy familiarizado) tienen un soporte bastante limitado para almacenar metadatos de nodo y borde, por lo que es posible que desee su propio formato de archivo (por ejemplo, algo basado en búferes de protocolo).
Una forma que encontré de almacenar el gráfico fue a través del formato DOT , así:
public class DOTWriter<INode, IEdge> { public static String write(final Graph graph) { StringBuilder sb = new StringBuilder(); sb.append("strict digraph G {\n"); for(INode n : graph.nodes()) { sb.append(" \"" + n.getId() + "\n"); } for(IEdge e : graph.edges()) { sb.append(" \"" + e.getSource().getId() + "\" -> \"" + e.getTarget().getId() + "\" " + "\n"); } sb.append("}"); return sb.toString(); } }Esto producirá algo como
strict digraph G { node_A; node_B; node_A -> node_B; }Es muy fácil leer esto y volver a construir el gráfico en la memoria.
Sin embargo, si sus nodos son objetos complejos, debe almacenarlos por separado.
Basado en la increíble respuesta de @Maria Ines Parnisari, modifiqué un poco 😊. Luego, al dibujar con mermaid (un complemento de descuento), obtengo una imagen clara como esta en Idea (> = 2021.2, ¡admite mejor el descuento)!
//noinspection UnstableApiUsage MutableGraph<String> graph = GraphBuilder.directed() .allowsSelfLoops(false) .build(); //noinspection UnstableApiUsage graph.addNode("root"); graph.putEdge("root", "s1_1"); graph.putEdge("root", "s1_2"); graph.putEdge("root", "s1_3"); graph.putEdge("s1_2", "s2"); graph.putEdge("s2", "s3"); graph.putEdge("s3", "s4"); graph.putEdge("s3", "s5"); graph.putEdge("s4", "s6"); graph.putEdge("s5", "s6"); graph.putEdge("s1_1", "s6"); graph.putEdge("s1_1", "s2"); // print mermaid text , then copy it StringBuilder sb = new StringBuilder(); for (EndpointPair<String> edge : graph.edges()) { // shoudle be `-->` to draw with mermaid sb.append(edge.nodeU() + " --> " + edge.nodeV() + "\n"); } System.out.println(sb);lo siento Como < 10 reputación, no puedo copiar la imagen directamente, esa imagen estará oculta