如何将 jgrapht Graph<Foo,E> 映射到另一个 Graph<Bar,E>?
How to map jgrapht Graph<Foo,E> to another Graph<Bar,E>?
我有下图:
private final Graph<Foo, DefaultWeightedEdge> graph = buildGraph();
@Override
public Graph<Foo, DefaultWeightedEdge> buildGraph() {
return GraphTypeBuilder
.directed()
.allowingSelfLoops(false)
.weighted(true)
.allowingMultipleEdges(false)
.vertexClass(Foo.class)
.edgeClass(DefaultWeightedEdge.class)
.buildGraph();
}
如何将其映射到类型为 Graph<Bar, DefaultWeightedEdge>
的图表?
我在 Nikolais 答案中也添加了边缘映射,因为它没有转换 DefaultWeightedEdge 的源和目标类型:
public <V, Vv> Graph<Vv, DefaultWeightedEdge> convert(Graph<V, DefaultWeightedEdge> source, Function<V, Vv> vertexMapper) {
Graph<Vv, DefaultWeightedEdge> result = GraphTypeBuilder.<Vv, DefaultWeightedEdge>forGraphType(source.getType()).edgeClass(DefaultWeightedEdge.class).buildGraph();
source.vertexSet().forEach(v -> result.addVertex(vertexMapper.apply(v)));
source
.edgeSet()
.forEach(
e -> {
V sourceV = source.getEdgeSource(e);
Vv mappedSourceV = vertexMapper.apply(sourceV);
V targetV = source.getEdgeTarget(e);
Vv mappedTargetV = vertexMapper.apply(targetV);
result.addVertex(mappedSourceV);
result.addVertex(mappedTargetV);
DefaultWeightedEdge ee = result.addEdge(mappedSourceV, mappedTargetV);
double edgeWeight = source.getEdgeWeight(e);
result.setEdgeWeight(ee, edgeWeight);
});
return result;
}
我们能否通过添加边缘映射器以功能性/更通用的方式更优雅地做到这一点?
看了 AbstractBaseGraph. I have put the complete code with a small demo in a gist 中的 clone()
后,其实很简单。
public static <V, Vv, E> Graph<Vv, E> convert(Graph<V, E> source, Function<V, Vv> vertexMapper) {
Graph<Vv, E> result = GraphTypeBuilder.<Vv, E>forGraphType(source.getType()).buildGraph();
source.vertexSet().forEach(v -> result.addVertex(vertexMapper.apply(v)));
for (E e : source.edgeSet()) {
Vv s = vertexMapper.apply(source.getEdgeSource(e));
Vv t = vertexMapper.apply(source.getEdgeTarget(e));
result.addVertex(s);
result.addVertex(t);
result.addEdge(s, t, e);
}
return result;
}
我有下图:
private final Graph<Foo, DefaultWeightedEdge> graph = buildGraph();
@Override
public Graph<Foo, DefaultWeightedEdge> buildGraph() {
return GraphTypeBuilder
.directed()
.allowingSelfLoops(false)
.weighted(true)
.allowingMultipleEdges(false)
.vertexClass(Foo.class)
.edgeClass(DefaultWeightedEdge.class)
.buildGraph();
}
如何将其映射到类型为 Graph<Bar, DefaultWeightedEdge>
的图表?
我在 Nikolais 答案中也添加了边缘映射,因为它没有转换 DefaultWeightedEdge 的源和目标类型:
public <V, Vv> Graph<Vv, DefaultWeightedEdge> convert(Graph<V, DefaultWeightedEdge> source, Function<V, Vv> vertexMapper) {
Graph<Vv, DefaultWeightedEdge> result = GraphTypeBuilder.<Vv, DefaultWeightedEdge>forGraphType(source.getType()).edgeClass(DefaultWeightedEdge.class).buildGraph();
source.vertexSet().forEach(v -> result.addVertex(vertexMapper.apply(v)));
source
.edgeSet()
.forEach(
e -> {
V sourceV = source.getEdgeSource(e);
Vv mappedSourceV = vertexMapper.apply(sourceV);
V targetV = source.getEdgeTarget(e);
Vv mappedTargetV = vertexMapper.apply(targetV);
result.addVertex(mappedSourceV);
result.addVertex(mappedTargetV);
DefaultWeightedEdge ee = result.addEdge(mappedSourceV, mappedTargetV);
double edgeWeight = source.getEdgeWeight(e);
result.setEdgeWeight(ee, edgeWeight);
});
return result;
}
我们能否通过添加边缘映射器以功能性/更通用的方式更优雅地做到这一点?
看了 AbstractBaseGraph. I have put the complete code with a small demo in a gist 中的 clone()
后,其实很简单。
public static <V, Vv, E> Graph<Vv, E> convert(Graph<V, E> source, Function<V, Vv> vertexMapper) {
Graph<Vv, E> result = GraphTypeBuilder.<Vv, E>forGraphType(source.getType()).buildGraph();
source.vertexSet().forEach(v -> result.addVertex(vertexMapper.apply(v)));
for (E e : source.edgeSet()) {
Vv s = vertexMapper.apply(source.getEdgeSource(e));
Vv t = vertexMapper.apply(source.getEdgeTarget(e));
result.addVertex(s);
result.addVertex(t);
result.addEdge(s, t, e);
}
return result;
}