簡體   English   中英

Java:如何表示圖形?

[英]Java: how to represent graphs?

我正在實施一些算法來自學圖形以及如何使用它們。 你會推薦什么是在 Java 中做到這一點的最佳方法? 我在想這樣的事情:

public class Vertex {

    private ArrayList<Vertex> outnodes; //Adjacency list. if I wanted to support edge weight, this would be a hash map.

    //methods to manipulate outnodes
}

public class Graph {
    private ArrayList<Vertex> nodes;
    //algorithms on graphs
}

但我基本上只是編造了這個。 有沒有更好的辦法?

此外,我希望它能夠支持普通圖的變化,如有向圖、加權邊、多重圖等。

每個節點都被唯一命名,並且知道它連接到誰。 連接列表允許一個節點連接到任意數量的其他節點。

public class Node {
    public String name;
    public List<Edge> connections;
}

每個連接都是有方向的,有起點和終點,並被加權。

public class Edge {
    public Node start;
    public Node end;
    public double weight;
}

圖只是您的節點集合。 而不是List<Node>考慮Map<String, Node>以按名稱快速查找。

public class Graph {
    List<Node> nodes;
}

如果您需要加權邊和多重圖,您可能需要添加另一個類Edge

我還建議使用泛型來指定當前使用的 Vertex 和 Edge 的子類。 例如:

public class Graph<V extends Vertex> {
List<V> vertices;
...
}

在實現圖算法時,您還可以為算法可以在其上運行的圖類定義接口,以便您可以嘗試實際圖表示的不同實現。 例如,連接良好的簡單圖可能通過鄰接矩陣更好地實現,稀疏圖可能由鄰接列表表示 - 這一切都取決於......

順便說一句,有效地構建這樣的結構可能非常具有挑戰性,所以也許您可以提供更多關於您希望將它們用於什么樣的工作的詳細信息? 對於更復雜的任務,我建議您查看各種 Java 圖形庫,以獲得一些靈感。

查看http://jung.sourceforge.net/doc/index.html圖形庫。 您仍然可以練習實現自己的算法(也許可以從廣度優先或深度優先搜索開始),但您無需擔心創建圖形結構。

為什么不保持簡單並使用鄰接矩陣鄰接表

前段時間我遇到了同樣的問題,並做了我自己的實現。 我建議你實現另一個類:Edge。 然后,一個頂點將有一個邊列表。

public class Edge {
    private Node a, b;
    private directionEnum direction;     // AB, BA or both
    private int weight;
    ...
}

它對我有用。 但也許就是這么簡單。 如果你查看它的代碼,這個庫可能可以幫助你: http : //jgrapht.sourceforge.net/

當您到達要渲染圖形的地步時,我強烈推薦graphviz

以及它的同伴:看看Laszlo Szathmary 的 GraphViz 類,以及notugly.xls

甚至在 3 年前提出這個問題的時候, Sage (完全免費)就已經存在並且非常擅長圖論。 但是,在 2012 年,它是最好的圖論工具。 因此,Sage 已經內置了大量圖論材料,包括其他免費和開源的東西。 因此,無需編程,只需搞亂各種事物即可輕松學習更多知識。

而且,如果您也對編程部分感興趣,首先 Sage 是開源的,因此您可以看到任何已經存在的代碼。 其次,如果您真的想練習,您可以重新編寫您想要的任何功能,或者您可以成為第一個編寫尚不存在的東西的人。 在后一種情況下,您甚至可以提交新功能並使 Sage 更好地供所有其他用戶使用。

目前,這個答案對 OP 來說可能不是那么有用(因為已經 3 年了),但希望它對將來看到這個問題的任何其他人都有用。

Graph 的 Adjacency List 實現適用於解決大多數與圖相關的問題。

Java實現相同的是這里對我的博客。

class Graph<E> {
    private List<Vertex<E>> vertices;

    private static class Vertex<E> {
        E elem;
        List<Vertex<E>> neighbors;
    }
}

'Robert Sedgwick' 和 'Kevin Wayne' 編寫的簡單表示可在http://algs4.cs.princeton.edu/41graph/Graph.java.html 獲得

解釋復制自上頁。

Graph 類表示名為 0 到V - 1 的頂點的無向圖。

它支持以下兩個主要操作:向圖中添加一條邊,迭代與頂點相鄰的所有頂點。 它還提供了返回頂點數V和邊數E 的方法 允許平行邊和自環。 按照慣例,自閉環V - v出現在V的鄰接表的兩倍,並有助於兩的程度。

這個實現使用鄰接表表示,它是一個 Bag 對象的頂點索引數組。 除了迭代與給定頂點相鄰的頂點之外,所有操作都需要恆定時間(在最壞的情況下),這花費的時間與這些頂點的數量成正比。

學習算法時,在決定表示時不應考慮編程語言(Java)。 每個問題都可以從獨特的表示中受益,而且設計它可以增加一些學習。 先不依賴特定語言解決問題,然后任何特定語言的表示都會自然而然地流動。

當然,通用表示和庫在實際應用中很有用。 但其中一些也可以從一些定制中受益。 使用其他答案了解可用的不同技術,但在適當時考慮定制。

class Vertex {
    private String name;
    private int score; // for path algos
    private boolean visited; // for path algos
    List<Edge> connections;
}

class Edge {
    private String vertex1Name; // same as Vertex.name
    private String vertex2Name;
    private int length;
}

class Graph {
    private List<Edge> edges;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM