我想实现一些图形算法,这就是我创建一种图形框架的原因。到目前为止,我使用以下类很容易实现有向图;
class Vertex {
String id;
String name;
}
class Edge {
String id;
Vertex source;
Vertex destination;
int weight;
}
class Graph {
List<Vertex> vertexes;
List<Edge> edges; }
测试时我创建:
Edge edge = new Edge(id, source_node, destination_node, weight)
这在有向图中完全没问题。但是在无向图中; 我必须这样写; 假设我们有2个节点,分别是A,B,它们之间的权重是10。因此,由于无向图的结构,我必须放两条边;
Edge e1 = new Edge(id1, A, B, 10)
Edge e2 = new Edge(id2, B, A, 10)
这种边缘创建既低效又详尽。
因此,我如何修改我的代码,这样我就不必在两个节点之间放置两条边用于无向图。 将无向图类型集成到我的代码中的最佳方法是什么?
感谢您的时间。
答案 0 :(得分:3)
我最近遇到了一个有趣的Java API Blueprints Tinkerpop,你可以使用它,或者看一下如何实现自己的图框架。
我正在开发一个使用JSON的图形框架。这是由于图的可变性。图论中的算法倾向于将数据添加到其他算法使用的图形中。因此,试图具体描述图形本身存在缺陷。
答案 1 :(得分:1)
自然的解决方案是使边缘的方向成为属性。创建一个枚举:
public enum EdgeType {
Undirected,
From1to2,
From2to1,
Cyclic
}
然后向Edge类添加一个属性:
public EdgeType enumEdgeType;
在进行遍历和其他操作时,您可以使用switch语句来处理4种不同的情况。我的经验是,这种方法最简单,最有效。
答案 2 :(得分:1)
我不同意现有的答案......
通常,在代码中表示图形时,出于效率原因,您不希望将边缘存储为一个大列表,甚至根本不作为对象存储。您通常希望使用adjacency matrix(对于相对密集的图形)或adjacency lists(对于相对稀疏的图形)。这允许您轻松查找顶点的邻居,这主要是您在图算法中使用的。因此,通常在实现中,您只需要一个索引数组或Vertex
个对象的集合或列表。
在无向图中,您可以将边(i,j)
和(j,i)
添加到数据结构中。在有向图中,您只需添加其中一个。
答案 3 :(得分:0)
根据您要实现的图形算法,您将需要不同的图形表示,因此您必须能够使用其中的几个。大多数算法使用邻域列表,而在代码中使用边缘列表。
你真的不应该担心边缘创建。大多数情况下,与实际算法相比,它可以忽略不计。现在取决于你尝试做的事情,你可能只需要一个边缘,但大多数时候,两个边缘都非常精细和理智。
答案 4 :(得分:0)
我将不同意有关蓝图的答案。围绕这个库有很多炒作,除了图形实现抽象的优点之外,图形算法(熔炉)包中绝对没有实现,使得复杂的堆栈完全没用。
当我的意思是什么都没有实现时,那真的没什么(看看here),并且repo一段时间没有更新,所以你可以认为它已经死了。如果你想使用
我的2美分,使用经验丰富的图表框架:Jgrapht。我将它用于几个研究项目,有20个标准(和一些非平凡的)graph algorithms implemented。所以你不需要重新发明轮子。它还支持大量graph types。
避免炒作,寻找有效的解决方案。