Java 图形库

Rupam Yadav 2023年10月12日
  1. 在 Java 中使用 JGraphtT 库创建图形
  2. 在 Java 中使用 Guava 库创建图形
Java 图形库

图是 Java 中的一种数据结构,由节点及其边组成。一个节点表示数据,而边表示节点之间的关系。

在下面的部分中,我们将查看两个库,它们可以帮助我们在 Java 中实现图的概念。

在 Java 中使用 JGraphtT 库创建图形

JGraphT 是一个第三方库,包含实现不同图的类和方法,如有向图、加权图、伪图等。我们可以使用图算法执行各种操作,如遍历。

在程序中,我们创建 DefaultDirectedGraph 类的对象,JGraphT 中的图结构类,并返回 Graph 的实例。我们在 DefaultDirectedGraph 类的构造函数中传递了一个边类 DefaultEdge

Graph 采用节点类型和边类型两个类型参数,其中我们使用 String 作为节点中的数据类型,而边应该是 DefaultEdge

我们使用 addVertex() 方法将顶点或节点添加到 graph。接下来,我们需要使用 addEdge() 函数指定节点之间的边。

我们在 addEdges() 函数中传递两个参数:边缘的源和目标。第一条边从具有数据 a 的节点到具有 b 的节点。

我们有一个既有顶点又有边的图。尽管如此,我们还可以使用 JGraphT 库使用 JGraphX 库来可视化图形,可以使用以下 maven 依赖项将其导入项目中。

<dependency>
    <groupId>com.github.vlsi.mxgraph</groupId>
    <artifactId>jgraphx</artifactId>
    <version>4.2.2</version>
</dependency>

在我们导入 JGraphX 库之后,我们创建 JGraphXAdapter 的对象并在其返回 jGraphXAdapter 引用的构造函数中传递 graph 对象。现在我们需要设置布局以显示节点和边。

这是使用扩展 mxGraphLayoutmxCircleLayout 对象完成的,我们将 jGraphXAdapter 传递给 mxCircleLayout 类的构造函数,该类返回类型 mxGraphLayout 的引用。

我们使用将布局的父级作为参数的 mxGraphLayout.execute() 执行布局。

现在我们调用 mxCellRenderer 类的 createBufferedImage(),它接受六个参数:JGraphXAdapter 对象、单元格数、图像的比例或大小、生成图像的背景,以启用或禁用反- 锯齿,并剪辑图像。

我们传递所有各自的参数并获得一个 BufferedImage 对象。

最后,我们创建一个文件,生成的文件将使用 File() 对象存储在其中,并在写入图像时传递文件名及其路径;我们使用 ImageIO.write() 获取 BufferedImage 对象、要写入的图像格式和 File 对象。

import com.mxgraph.layout.*;
import com.mxgraph.util.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.jgrapht.Graph;
import org.jgrapht.ext.JGraphXAdapter;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;

public class JavaExample {
  public static void main(String[] args) throws IOException {
    Graph<String, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);

    graph.addVertex("a");
    graph.addVertex("b");
    graph.addVertex("c");
    graph.addVertex("d");
    graph.addVertex("e");
    graph.addVertex("f");

    graph.addEdge("a", "b");
    graph.addEdge("a", "c");
    graph.addEdge("b", "d");
    graph.addEdge("b", "f");
    graph.addEdge("d", "f");
    graph.addEdge("d", "e");
    graph.addEdge("c", "e");

    JGraphXAdapter<String, DefaultEdge> jGraphXAdapter = new JGraphXAdapter<>(graph);

    mxIGraphLayout mxIGraphLayout = new mxCircleLayout(jGraphXAdapter);
    mxIGraphLayout.execute(jGraphXAdapter.getDefaultParent());

    BufferedImage bufferedImage =
        mxCellRenderer.createBufferedImage(jGraphXAdapter, null, 3, Color.WHITE, true, null);

    File newFIle = new File("graph.png");
    ImageIO.write(bufferedImage, "PNG", newFIle);
  }
}

输出:

图形

在 Java 中使用 Guava 库创建图形

另一个在 Java 中实现图形的库是 Guava 库,我们可以使用以下 maven 依赖项在我们的项目中使用它。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

一旦设置了依赖关系,我们就可以进入程序。

我们使用 GraphBuilder 调用其静态方法 directed(),该方法用于构建有向图,并调用返回空 MutableGraph 对象的 build() 方法。我们将节点数据的类型设置为字符串。

我们使用 addNode 方法添加节点数据,使用 putEdge() 方法添加边。在 putEdge() 函数中,我们传递源顶点和目标顶点。

添加节点及其边后,我们通过调用 Traverser 类的 forGraph() 方法并传递 mutableGraph 对象来创建可遍历图。

我们可以执行不同类型的遍历算法,但在本例中,我们通过调用 breadthFirst() 函数使用广度优先方法遍历图,并将节点数据从哪里开始遍历。

breadthFirst() 返回一个 Iterable 实例,该实例可以使用循环进行迭代并打印节点。

import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
import com.google.common.graph.Traverser;

public class JavaExample {
  public static void main(String[] args) {
    MutableGraph<String> mutableGraph = GraphBuilder.directed().build();

    mutableGraph.addNode("root");
    mutableGraph.addNode("l1");
    mutableGraph.addNode("r1");
    mutableGraph.addNode("l2");
    mutableGraph.addNode("r2");
    mutableGraph.addNode("l3");
    mutableGraph.addNode("r3");
    mutableGraph.addNode("l4");
    mutableGraph.addNode("r4");

    mutableGraph.putEdge("root", "l1");
    mutableGraph.putEdge("root", "r1");
    mutableGraph.putEdge("l1", "l2");
    mutableGraph.putEdge("l1", "r2");
    mutableGraph.putEdge("r1", "l3");
    mutableGraph.putEdge("r1", "r3");
    mutableGraph.putEdge("l3", "l4");
    mutableGraph.putEdge("l3", "r4");

    Traverser<String> traversedGraph = Traverser.forGraph(mutableGraph);
    Iterable<String> getDepthFirstResult = traversedGraph.breadthFirst("root");

    for (String s : getDepthFirstResult) {
      System.out.println(s);
    }
  }
}

输出:

root
l1
r1
r2
l2
r3
l3
l4
r4
作者: Rupam Yadav
Rupam Yadav avatar Rupam Yadav avatar

Rupam Saini is an android developer, who also works sometimes as a web developer., He likes to read books and write about various things.

LinkedIn

相关文章 - Java Graph