如何将 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;
}