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