Using vertex String IDs as the actual vertices while importing graph (jgrapht 1.4)

瘦欲@ 提交于 2020-04-18 06:53:54

问题


I have very simple graph

strict digraph G {
  <assembly-raw-file>;
  <dataset-processing>;
  <feature-processing-1>;
  <feature-processing-2>;
  <mh.permute-variables-and-hyper-params>;
  <mh.finish>;
  <assembly-raw-file> -> <dataset-processing>;
  <dataset-processing> -> <feature-processing-1>;
  <dataset-processing> -> <feature-processing-2>;
  <dataset-processing> -> <mh.permute-variables-and-hyper-params>;
  <feature-processing-1> -> <mh.permute-variables-and-hyper-params>;
  <feature-processing-2> -> <mh.permute-variables-and-hyper-params>;
  <mh.permute-variables-and-hyper-params> -> <mh.finish>;
}

I'm trying to import it with the follow code

DirectedAcyclicGraph<String, DefaultEdge> processGraph = new DirectedAcyclicGraph<>(
        SupplierUtil.createStringSupplier(), SupplierUtil.DEFAULT_EDGE_SUPPLIER, false);

DOTImporter<String, DefaultEdge> importer = new DOTImporter<>();
importer.importGraph(processGraph, new StringReader(wpy.processesGraph));

but this code is changing names of vertices to this:

strict digraph G {
  0;
  1;
  2;
  3;
  4;
  5;
  0 -> 1;
  1 -> 2;
  1 -> 3;
  1 -> 4;
  2 -> 4;
  3 -> 4;
  4 -> 5;
}

How to import my graph with preserving id of vertices?

Or the easier solution is to change type of vertex from String to complex class?


回答1:


Update March 4 2020:

If you are using the 1.4.1 SNAPSHOT release (or beyond), there's an easier way to obtain the desired result: simply use importer.setVertexFactory(id->id);

Only in case the user supplies such as factory, it is called with the vertex identifier from the file. The method given the vertex identifier from the file should return an actual graph vertex. The user returned vertex is added directly into the graph without using the vertex supplier.

If no such factory is provided, the default behavior is to acquire a new vertex from the graph vertex supplier and associate the original identifier from the file as an attribute of the new vertex.

Applying this to the above example, we get:

String input="strict digraph G {\n" +
        "  <assembly-raw-file>;\n" +
        "  <dataset-processing>;\n" +
        "  <feature-processing-1>;\n" +
        "  <feature-processing-2>;\n" +
        "  <mh.permute-variables-and-hyper-params>;\n" +
        "  <mh.finish>;\n" +
        "  <assembly-raw-file> -> <dataset-processing>;\n" +
        "  <dataset-processing> -> <feature-processing-1>;\n" +
        "  <dataset-processing> -> <feature-processing-2>;\n" +
        "  <dataset-processing> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <feature-processing-1> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <feature-processing-2> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <mh.permute-variables-and-hyper-params> -> <mh.finish>;\n" +
        "}";
Graph<String, DefaultEdge> graph = new SimpleDirectedGraph<>(DefaultEdge.class);
DOTImporter<String, DefaultEdge> importer = new DOTImporter<>();
importer.setVertexFactory(id->id);
importer.importGraph(graph, new StringReader(input));
System.out.println(graph);

Original answer:

Here's one way to do it. This approach uses 2 steps. In the first step, I read the graph as you did. The vertex names can be stored in an attribute map. In the second step I create a new graph which uses the structure of the first graph, but renames the vertices.

String input="strict digraph G {\n" +
        "  <assembly-raw-file>;\n" +
        "  <dataset-processing>;\n" +
        "  <feature-processing-1>;\n" +
        "  <feature-processing-2>;\n" +
        "  <mh.permute-variables-and-hyper-params>;\n" +
        "  <mh.finish>;\n" +
        "  <assembly-raw-file> -> <dataset-processing>;\n" +
        "  <dataset-processing> -> <feature-processing-1>;\n" +
        "  <dataset-processing> -> <feature-processing-2>;\n" +
        "  <dataset-processing> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <feature-processing-1> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <feature-processing-2> -> <mh.permute-variables-and-hyper-params>;\n" +
        "  <mh.permute-variables-and-hyper-params> -> <mh.finish>;\n" +
        "}";
Graph<String, DefaultEdge> graph = new SimpleDirectedGraph<>(SupplierUtil.createStringSupplier(), SupplierUtil.DEFAULT_EDGE_SUPPLIER, false);

//Import the graph; the vertex names are stored as 'ID' in the attribute map
DOTImporter<String, DefaultEdge> importer = new DOTImporter<>();
Map<String, Map<String, Attribute>> attrs = new HashMap<>();
importer.addVertexAttributeConsumer((p, a) -> {
    Map<String, Attribute> map = attrs.computeIfAbsent(p.getFirst(), k -> new HashMap<>());
    map.put(p.getSecond(), a);
});
importer.importGraph(graph, new StringReader(input));

//Create a new graph, thereby creating String vertices equal to the ID attribute values
Graph<String,DefaultEdge> labeledGraph=new SimpleDirectedGraph<>(DefaultEdge.class);
for(String v : graph.vertexSet())
    labeledGraph.addVertex(attrs.get(v).get("ID").getValue());
for(DefaultEdge e : graph.edgeSet()){
    String source = graph.getEdgeSource(e);
    String target = graph.getEdgeTarget(e);
    String sourceID=attrs.get(source).get("ID").getValue();
    String targetID=attrs.get(target).get("ID").getValue();
    labeledGraph.addEdge(sourceID, targetID);
}

System.out.println(labeledGraph);


来源:https://stackoverflow.com/questions/60461351/using-vertex-string-ids-as-the-actual-vertices-while-importing-graph-jgrapht-1

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!