我有一个非常简单的图
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>;
}
我试图用以下代码导入它
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));
但这段代码却把顶点的名字改成了这样。
strict digraph G {
0;
1;
2;
3;
4;
5;
0 -> 1;
1 -> 2;
1 -> 3;
1 -> 4;
2 -> 4;
3 -> 4;
4 -> 5;
}
如何导入我的图并保留顶点的id?
或者更简单的解决方案是将顶点的类型从String改为复杂类?
如果你正在使用1.4.1 SNAPSHOT版本(或更高版本),有一个更简单的方法来获得所需的结果:只需使用 importer.setVertexFactory(id->id);
只有在用户提供了工厂的情况下,才会调用文件中的顶点标识符。给定文件中的顶点标识符的方法应该返回一个实际的图顶点。 用户返回的顶点被直接添加到图中,而不使用顶点提供者。
如果没有提供这样的工厂,默认的行为是从图顶点供应者那里获取一个新的顶点,并将文件中的原始标识符关联为新顶点的属性。
将此应用到上面的例子中,我们得到。
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);
这是一种方法。这个方法使用了2个步骤。第一步,我像你一样读取图。顶点名称可以存储在一个属性图中。第二步,我创建一个新图,它使用第一个图的结构,但重命名顶点。
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);