我正在实施一些算法来教自己关于图形以及如何使用它们。你会推荐什么是在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
}
但我基本上只是做了这件事。还有更好的方法吗?
此外,我希望它能够支持诸如有向图,加权边,多图等香草图的变化。
答案 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 matrix或adjacency 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。
答案 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;
}