Java:如何表示图形?

时间:2009-11-15 14:17:28

标签: java graph

我正在实施一些算法来教自己关于图形以及如何使用它们。你会推荐什么是在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
}

但我基本上只是做了这件事。还有更好的方法吗?

此外,我希望它能够支持诸如有向图,加权边,多图等香草图的变化。

12 个答案:

答案 0 :(得分:29)

每个节点都是唯一的名称,并知道它与谁连接。连接列表允许节点连接到任意数量的其他节点。

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;
}

答案 1 :(得分:16)

如果您需要加权边和多图,则可能需要添加另一个类

我还建议使用泛型来指定当前使用的Vertex和Edge的哪个子类。例如:

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

在实现图算法时,您还可以为算法可以运行的图类定义接口,以便您可以使用实际图形表示的不同实现。例如,连接良好的简单图表可以通过 adjacency matrix 更好地实现,较稀疏的图表可能由 adjacency lists 表示 - 所有这些取决于...

BTW高效地构建这样的结构可能非常具有挑战性,所以也许你可以给我们一些关于你想用它们做什么工作的更多细节?对于更复杂的任务,我建议您查看各种Java图形库,以获得一些灵感。

答案 2 :(得分:6)

查看http://jung.sourceforge.net/doc/index.html图表库。您仍然可以练习实现自己的算法(可能是广度优先或深度优先搜索开始),但您无需担心创建图形结构。

答案 3 :(得分:4)

为什么不保持简单并使用adjacency matrixadjacency list

答案 4 :(得分:2)

前一段时间我遇到了同样的问题并完成了自己的实施。我建议你实现另一个类:Edge。然后,顶点将具有边缘列表。

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

它对我有用。但也许这么简单。如果您查看代码,可以使用此库来帮助您:http://jgrapht.sourceforge.net/

答案 5 :(得分:2)

当你到达想要渲染图形的位置时,我会高度推荐graphviz

及其同伴:看看Laszlo Szathmary's GraphViz class以及notugly.xls

答案 6 :(得分:2)

即使在这个问题的时候,3年前,Sage(完全免费)已经存在并且非常擅长图论。但是,在2012年它是关于最好的图论工具。因此,Sage已经内置了大量的图论材料,包括其他免费和开源的东西。因此,简单地处理各种事情以便学习更容易,因为不需要编程。

而且,如果您对编程部分感兴趣,首先Sage是开源的,因此您可以看到任何已存在的代码。其次,如果你真的想要练习,你可以重新编写你想要的任何功能,或者你可以成为第一个编程不存在的东西。在后一种情况下,您甚至可以提交新功能,并使Sage更好地适用于所有其他用户。

目前,这个答案可能对OP没有用(因为它已经有3年了),但希望它对将来看到这个问题的任何其他人都有用。

答案 7 :(得分:1)

Graph的Adjacency List实现适用于解决大多数与图形相关的问题。

我的博客上的here的Java实现是{{3}}。

答案 8 :(得分:1)

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

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

答案 9 :(得分:0)

由Robert Sedgwick编写的简单陈述#39;和凯文韦恩&#39;可在http://algs4.cs.princeton.edu/41graph/Graph.java.html

获取

从上页复制的说明。

  

Graph类表示顶点的无向图    名称为0至 V - 1。

     

它支持以下两个主要操作:向图形添加边缘,    迭代邻近顶点的所有顶点。它还提供    返回顶点数 V 的方法和数字    边 E 。允许平行边缘和自环。    按照惯例,自循环 v - v 出现在     v 的邻接列表两次,并为学位贡献两个    of v

     

此实现使用邻接列表表示,其中   是Bag对象的顶点索引数组。   所有操作都需要恒定的时间(在最坏的情况下)除外   迭代与给定顶点相邻的顶点   时间与这些顶点的数量成正比。

答案 10 :(得分:0)

学习算法时,在确定表示形式时不应考虑编程语言(Java)。每个问题都可以受益于独特的表示形式,此外,对其进行设计可以增加一点学习。首先不依赖特定语言即可解决问题,然后任何特定语言的表示都会自然地流动。

当然,一般的表示形式和库在实际应用中很有用。但是其中一些也可以从一些定制中受益。使用其他答案来了解可用的不同技术,但在适当时考虑进行定制。

答案 11 :(得分:-1)

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;
}