ホームページ  >  記事  >  Java  >  Javaを使用してグラフの最小スパニングツリーアルゴリズムを実装する方法

Javaを使用してグラフの最小スパニングツリーアルゴリズムを実装する方法

WBOY
WBOYオリジナル
2023-09-19 14:07:541251ブラウズ

Javaを使用してグラフの最小スパニングツリーアルゴリズムを実装する方法

Java を使用してグラフの最小スパニング ツリー アルゴリズムを実装する方法

概念の紹介:
最小スパニング ツリー (MST) とは、重み付けされた有向グラフまたは無向グラフを使用して、グラフ内のすべての頂点を含み、重みの合計が最小となるツリーを見つけます。最小スパニング ツリー アルゴリズムは数多くありますが、最も古典的な 2 つのアルゴリズムは、Prim のアルゴリズムと Kruskal のアルゴリズムです。

Prim アルゴリズム:
Prim アルゴリズムは、頂点から開始し、最小スパニング ツリー全体が生成されるまで徐々に拡張するポイントベースの貪欲アルゴリズムです。以下は、Java を使用して Prim のアルゴリズムを実装するためのサンプル コードです:

import java.util.Arrays;

public class PrimAlgorithm {

    // 表示无穷大
    private static final int INF = Integer.MAX_VALUE;

    public static void primMST(int[][] graph) {
        int vertices = graph.length;

        // 创建一个数组用来保存最小生成树的顶点
        int[] parent = new int[vertices];

        // 创建一个数组用来保存每个顶点与最小生成树的最小权值
        int[] key = new int[vertices];

        // 创建一个数组用来标记顶点是否已经加入最小生成树
        boolean[] mstSet = new boolean[vertices];

        // 初始化key数组和mstSet数组的值
        Arrays.fill(key, INF);
        Arrays.fill(mstSet, false);

        //将第一个顶点加入最小生成树
        key[0] = 0;
        parent[0] = -1;

        for (int count = 0; count < vertices - 1; count++) {
            // 选择key值最小的顶点
            int minKey = getMinKey(key, mstSet);
            mstSet[minKey] = true;

            // 更新与该顶点相邻的顶点的key值
            for (int v = 0; v < vertices; v++) {
                if (graph[minKey][v] != 0 && !mstSet[v] && graph[minKey][v] < key[v]) {
                    parent[v] = minKey;
                    key[v] = graph[minKey][v];
                }
            }
        }

        // 输出最小生成树
        printMST(parent, graph);
    }

    // 获得key值最小的顶点
    private static int getMinKey(int[] key, boolean[] mstSet) {
        int minKey = INF, minIndex = -1;
        for (int v = 0; v < key.length; v++) {
            if (!mstSet[v] && key[v] < minKey) {
                minKey = key[v];
                minIndex = v;
            }
        }
        return minIndex;
    }

    // 输出最小生成树
    private static void printMST(int[] parent, int[][] graph) {
        System.out.println("Edge   Weight");
        for (int i = 1; i < graph.length; i++) {
            System.out.println(parent[i] + " - " + i + "    " + graph[i][parent[i]]);
        }
    }

    public static void main(String[] args) {
        int[][] graph = {{0, 2, 0, 6, 0},
                         {2, 0, 3, 8, 5},
                         {0, 3, 0, 0, 7},
                         {6, 8, 0, 0, 9},
                         {0, 5, 7, 9, 0}};
        primMST(graph);
    }
}

Kruskal アルゴリズム:
Kruskal アルゴリズムは、エッジに基づく貪欲なアルゴリズムです。重みの小さいエッジから順にエッジを選択し、重みの大きいエッジのみを選択します。最小スパニング ツリー全体が生成されるまで、ループ エッジは生成されません。以下は、Java を使用して Kruskal のアルゴリズムを実装するためのサンプル コードです:

import java.util.*;

class Edge implements Comparable<Edge> {
    int src, dest, weight;

    public int compareTo(Edge compareEdge) {
        return this.weight - compareEdge.weight;
    }
}

class KruskalAlgorithm {
    public List<Edge> kruskalMST(List<Edge> edges, int vertices) {
        List<Edge> result = new ArrayList<>();
        Collections.sort(edges);

        int[] parent = new int[vertices];
        for (int i = 0; i < vertices; i++) {
            parent[i] = i;
        }

        int count = 0, i = 0;
        while (count < vertices - 1) {
            Edge currentEdge = edges.get(i);

            int x = find(parent, currentEdge.src);
            int y = find(parent, currentEdge.dest);

            if (x != y) {
                result.add(currentEdge);
                union(parent, x, y);
                count++;
            }

            i++;
        }

        return result;
    }

    private int find(int[] parent, int vertex) {
        if (parent[vertex] != vertex) {
            parent[vertex] = find(parent, parent[vertex]);
        }
        return parent[vertex];
    }

    private void union(int[] parent, int x, int y) {
        int xSet = find(parent, x);
        int ySet = find(parent, y);
        parent[xSet] = ySet;
    }

    public static void main(String[] args) {
        int vertices = 4;
        List<Edge> edges = new ArrayList<>();
        edges.add(new Edge(0, 1, 10));
        edges.add(new Edge(0, 2, 6));
        edges.add(new Edge(0, 3, 5));
        edges.add(new Edge(1, 3, 15));
        edges.add(new Edge(2, 3, 4));

        KruskalAlgorithm kruskal = new KruskalAlgorithm();
        List<Edge> result = kruskal.kruskalMST(edges, vertices);

        System.out.println("Edge   Weight");
        for (Edge edge : result) {
            System.out.println(edge.src + " - " + edge.dest + "    " + edge.weight);
        }
    }
}

上記は、Java を使用して Prim のアルゴリズムと Kruskal のアルゴリズムを実装するためのサンプル コードです。どちらも最小スパニング ツリー アルゴリズムを実装するための古典的な方法です。グラフの。これらのコードを学習して理解することで、Java を使用してグラフの最小スパニング ツリー アルゴリズムを実装する方法をよりよく理解し、習得することができます。

以上がJavaを使用してグラフの最小スパニングツリーアルゴリズムを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。