daisukeの技術ブログ

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

GradleプロジェクトでJGraphTを使う(Ubuntu22.04)

前回 は、前々回 に作った Gradle プロジェクトを、IntelliJ を使ってデバッグするところをやりました。

今回は、その Gradle プロジェクトを使って、JGraphT というグラフ理論のライブラリを Java で使ってみます。

JGraphT で簡単なサンプルを動かして、GraphViz で可視化するところまでやりたいと思います。

JGraphT には、Python バインディングもあるようです。

それではやっていきます!

参考文献

はじめに

「Javaでデザインパターンを学ぶ」の記事一覧です。良かったら参考にしてください。

Javaでデザインパターンの記事一覧

JGraphT の公式サイトは以下です。

jgrapht.org

それではやっていきます!

GradleプロジェクトにJGraphTを追加する

Gradleプロジェクトでは、外部ライブラリを使うときは、その依存関係をプロジェクトのビルドスクリプトに書く必要があります。

現在のプロジェクトのツリーを表示しておきます。

$ tree
.
|-- app
|   |-- build
|   |   |-- classes
|   |   |   `-- java
|   |   |       |-- main
|   |   |       |   `-- gradle
|   |   |       |       `-- demo
|   |   |       |           `-- App.class
|   |   |       `-- test
|   |   |           `-- gradle
|   |   |               `-- demo
|   |   |                   `-- AppTest.class
|   |   |-- distributions
|   |   |   |-- app
|   |   |   |   |-- bin
|   |   |   |   |   |-- app
|   |   |   |   |   `-- app.bat
|   |   |   |   `-- lib
|   |   |   |       |-- app.jar
|   |   |   |       |-- checker-qual-3.33.0.jar
|   |   |   |       |-- error_prone_annotations-2.18.0.jar
|   |   |   |       |-- failureaccess-1.0.1.jar
|   |   |   |       |-- guava-32.1.1-jre.jar
|   |   |   |       `-- jsr305-3.0.2.jar
|   |   |   |-- app.tar
|   |   |   `-- app.zip
|   |   |-- generated
|   |   |   `-- sources
|   |   |       |-- annotationProcessor
|   |   |       |   `-- java
|   |   |       |       |-- main
|   |   |       |       `-- test
|   |   |       `-- headers
|   |   |           `-- java
|   |   |               |-- main
|   |   |               `-- test
|   |   |-- libs
|   |   |   `-- app.jar
|   |   |-- reports
|   |   |   `-- tests
|   |   |       `-- test
|   |   |           |-- classes
|   |   |           |   `-- gradle.demo.AppTest.html
|   |   |           |-- css
|   |   |           |   |-- base-style.css
|   |   |           |   `-- style.css
|   |   |           |-- index.html
|   |   |           |-- js
|   |   |           |   `-- report.js
|   |   |           `-- packages
|   |   |               `-- gradle.demo.html
|   |   |-- scripts
|   |   |   |-- app
|   |   |   `-- app.bat
|   |   |-- test-results
|   |   |   `-- test
|   |   |       |-- TEST-gradle.demo.AppTest.xml
|   |   |       `-- binary
|   |   |           |-- output.bin
|   |   |           |-- output.bin.idx
|   |   |           `-- results.bin
|   |   `-- tmp
|   |       |-- compileJava
|   |       |   `-- previous-compilation-data.bin
|   |       |-- compileTestJava
|   |       |   `-- previous-compilation-data.bin
|   |       |-- jar
|   |       |   `-- MANIFEST.MF
|   |       `-- test
|   |-- build.gradle.kts
|   `-- src
|       |-- main
|       |   |-- java
|       |   |   `-- gradle
|       |   |       `-- demo
|       |   |           `-- App.java
|       |   `-- resources
|       `-- test
|           |-- java
|           |   `-- gradle
|           |       `-- demo
|           |           `-- AppTest.java
|           `-- resources
|-- gradle
|   `-- wrapper
|       |-- gradle-wrapper.jar
|       `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- settings.gradle.kts

54 directories, 36 files

重要なのは、以下の3ファイルです。

  • settings.gradle.kts:gradle-demoプロジェクトの設定ファイル
  • build.gradle.kts:appプロジェクトのビルドスクリプト
  • App.java:appプロジェクトのJavaソースファイル

appプロジェクトのビルドスクリプトに、JGraphT の依存関係を追加します。

公式サイトに、ビルドツールが Maven の場合の依存関係の追加方法が書かれていますが、Gradle の場合は書かれていません。

そういうときは、以下にアクセスします。

https://mvnrepository.com/

JGraphT で検索すると、いくつか出てきます。必要なのは、JGraphT Core と、可視化のための JGraphT I/O です。

最新バージョンは、両方とも 1.5.2 のようです。

JGraphT Core の 1.5.2 に、Gradle(Kotlin)の場合の書き方が書かれています。

// https://mvnrepository.com/artifact/org.jgrapht/jgrapht-core
implementation("org.jgrapht:jgrapht-core:1.5.2")

JGraphT I/O の方は、以下です。

// https://mvnrepository.com/artifact/org.jgrapht/jgrapht-io
implementation("org.jgrapht:jgrapht-io:1.5.2")

現在の appプロジェクトのビルドスクリプトの build.gradle.kts は以下です。

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    application
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")

    testRuntimeOnly("org.junit.platform:junit-platform-launcher")

    // This dependency is used by the application.
    implementation("com.google.guava:guava:32.1.1-jre")
}

// Apply a specific Java toolchain to ease working on different environments.
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

application {
    // Define the main class for the application.
    mainClass.set("gradle.demo.App")
}

tasks.named<Test>("test") {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}

dependencies {} に、上の2つを追加すればいいだけです。

これで準備は完了です。

HelloJGraphTを実行する

IntelliJ を起動して、gradle-demo プロジェクトを開きます。

JGraphT Core と JGraphT I/O が読み込まれています。

IntelliJでgradle-demoプロジェクトを開く
IntelliJでgradle-demoプロジェクトを開く

JGraphT の公式サイトに hello world があります(以下)。

jgrapht.org

これをコピーして、App.java と同じディレクトリに、HelloJGraphT.java を作って貼り付けます。

先頭にあるパッケージ名だけ変えておきます。

//package org.jgrapht.demo;
package gradle.demo;

また、appプロジェクトのビルドスクリプトの build.gradle.kts の application {} を以下のようにします。

application {
    // Define the main class for the application.
    //mainClass.set("gradle.demo.App")
    mainClass.set("gradle.demo.HelloJGraphT")
}

では、早速実行してみます。

ソースを変更したときや、ビルドスクリプトを変えたときは、左のサイドバーのビルドアイコンをクリックして、同期タブの「Gradleプロジェクトの再ロード」をクリックすると反映されます。

また、左のプロジェクトのツリーは、「ファイル→ディスクからすべて再読み込み」を行うと、反映されます。

以下が実行結果です。赤枠のような結果が出力されていれば成功だと思います。

HelloJGraphTの実行結果
HelloJGraphTの実行結果

一応、プログラムの出力結果だけを貼っておきます。

-- toString output
([v1, v2, v3, v4], [{v1,v2}, {v2,v3}, {v3,v4}, {v4,v1}])

-- traverseHrefGraph output
http://www.jgrapht.org
http://www.wikipedia.org
http://www.google.com

-- renderHrefGraph output
strict digraph G {
  www_google_com [ label="http://www.google.com" ];
  www_wikipedia_org [ label="http://www.wikipedia.org" ];
  www_jgrapht_org [ label="http://www.jgrapht.org" ];
  www_jgrapht_org -> www_wikipedia_org;
  www_google_com -> www_jgrapht_org;
  www_google_com -> www_wikipedia_org;
  www_wikipedia_org -> www_google_com;
}

HelloJGraphTをファイル出力に変更する

先ほどの出力結果の中で、-- renderHrefGraph output のところは、GraphViz を使うとグラフを可視化できます。

まず、GraphViz のインストールです。

$ sudo apt install graphviz

テキストファイルに先ほどの出力結果を貼り付けます。ファイル名は HelloJGraphT.dot とします。

strict digraph G {
  www_google_com [ label="http://www.google.com" ];
  www_wikipedia_org [ label="http://www.wikipedia.org" ];
  www_jgrapht_org [ label="http://www.jgrapht.org" ];
  www_jgrapht_org -> www_wikipedia_org;
  www_google_com -> www_jgrapht_org;
  www_google_com -> www_wikipedia_org;
  www_wikipedia_org -> www_google_com;
}

GraphViz で画像ファイルを出力します。

  • -T:出力フォーマットを指定します、今回は PNG を指定します
  • 入力ファイル:今回は、HelloJGraphT.dot です
  • -o:出力ファイル名を指定します
$ dot -Tpng HelloJGraphT.dot -oHelloJGraphT.png

出力された HelloJGraphT.png です。

HelloJGraphT.png
HelloJGraphT.png

ノード(頂点)が丸で囲まれていて、エッジ(辺)が矢印(今回は有向グラフ)で示されています。

今回は、ここまでにします。

おわりに

今回は、JGraphT を使ってみました。グラフは可視化することで、とても理解しやすくなりますね。

次回は、もう少し、JGraphT について使い方を調べていきたいと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。