简体   繁体   English

导入图时使用顶点字符串 ID 作为实际顶点(jgrapht 1.4)

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

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?如何导入我的图形并保留顶点 id?

Or the easier solution is to change type of vertex from String to complex class?或者更简单的解决方案是将顶点类型从 String 更改为复杂类?

Update March 4 2020: 2020 年 3 月 4 日更新:

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);如果您使用的是 1.4.1 SNAPSHOT 版本(或更高版本),则有一种更简单的方法可以获得所需的结果:只需使用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.此方法使用 2 个步骤。 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM