【问题标题】:Need some advice for my graph implementation with java需要一些关于我用 java 实现图形的建议
【发布时间】:2013-01-26 13:14:42
【问题描述】:

我想实现一些图形算法,这就是我创建一种图形框架的原因。到目前为止,我使用以下类非常轻松地实现了有向图

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)

这种类型的边缘创建既低效又费力。

因此,我如何修改我的代码,以便不必在无向图的两个节点之间放置两条边。 将无向图类型也集成到我的代码中的最佳方法是什么?

感谢您的宝贵时间。

【问题讨论】:

  • 为什么不将Edge类拆分为两个:UndirectedEdgeDirectedEdge,它们也可以从一个名为Edge的基类extend
  • 除了您将其命名为源/目标之外,您的 Edge 类中没有任何内容表明它是有向边。
  • 有向图和无向图的区别在于你如何解释它。

标签: java algorithm graph-algorithm


【解决方案1】:

我将不得不不同意有关蓝图的答案。这个库有很多炒作,除了图形实现抽象的好特性外,图形算法(熔炉)包中绝对没有实现任何东西,使得复杂的堆栈完全无用。

当我的意思是什么都没有实现时,那真的什么都没有(看看here),并且回购已经有一段时间没有更新了,所以你可以认为它已经死了。如果你想使用

我的 2 美分,使用经验丰富的图形框架:Jgrapht。我将它用于几个研究项目,有 20 个标准(和一些非平凡的)graph algorithms implemented。所以你不需要重新发明轮子。它还支持graph types的重载。

避免炒作,寻找可行的解决方案。

【讨论】:

    【解决方案2】:

    我最近遇到了一个有趣的 Java API,名为 Blueprints,由 Tinkerpop 编写,您可以使用它,或者查看一些关于如何实现自己的图形框架的想法。

    我正在开发一个使用 JSON 的图形框架。这是由于图形的可变性。图论中的算法倾向于将数据添加到其他算法使用的图中。因此,试图具体描述图表本身就是有缺陷的。

    【讨论】:

      【解决方案3】:

      我不同意现有的答案...

      通常,在代码中表示图形时,出于效率原因,您不希望将边存储为一个大列表,甚​​至根本不希望存储为对象。您通常需要使用adjacency matrix(用于相对密集的图)或adjacency lists(用于相对稀疏的图)。这使您可以轻松查找顶点的邻居,这主要是您在图形算法中使用的。因此,在实现中,您通常只需要一个索引数组或Vertex 对象的集合或列表。

      在无向图中,您可以将边 (i,j)(j,i) 添加到数据结构中。在有向图中,您只需添加其中一个即可。

      【讨论】:

      • 同意。您在图上执行的任何操作都将要求您显式或隐式地为图创建邻接矩阵或列表。预先创建您需要的数据结构会更有效。
      【解决方案4】:

      自然的解决方案是让边缘的方向成为一个属性。创建一个枚举:

      public enum EdgeType {
           Undirected,
           From1to2,
           From2to1,
           Cyclic
      }
      

      然后给你的 Edge 类添加一个属性:

      public EdgeType enumEdgeType;
      

      在进行遍历和其他操作时,您可以使用 switch 语句来处理 4 种不同的情况。我的经验是,这种方法是最简单、最有效的。

      【讨论】:

        【解决方案5】:

        根据您要实现的图形算法,您将需要不同的图形表示,因此您必须能够使用其中的几种。大多数算法使用邻域列表,而在您的代码中使用边缘列表。

        您真的不应该担心边缘创建。大多数情况下,与实际算法相比,它可以忽略不计。现在,根据您尝试执行的操作,您可能只需要其中一个边缘,但大多数情况下,拥有两个边缘是非常好的和理智的。

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 2021-12-11
          • 2014-01-19
          • 1970-01-01
          • 2014-05-21
          • 2021-04-02
          • 1970-01-01
          • 1970-01-01
          • 2017-09-28
          相关资源
          最近更新 更多