简体   繁体   English

Java中无向图的边缘

[英]Edge of undirected graph in Java

Suppose I am writing a Java class to represent an edge of undirected graph. 假设我正在编写一个Java类来表示无向图的边缘。 This class Edge contains two vertices to and from . 这个类Edge包含两个顶点tofrom

class Edge<Vertex> {

  private final Vertex to, from

  public Edge(Vertex to, Vertex from) {
    this.to = to;
    this.from = from;
  } 
  ... // getters, equals, hashCode ...
}

Obviously e1 = new Edge(v1, v2) and e2 = new Edge(v2, v1) are actually the same in an undirected graph. 显然e1 = new Edge(v1, v2)在无向图中e1 = new Edge(v1, v2)e2 = new Edge(v2, v1)实际上是相同的。 Does it make sense? 是否有意义? How would you implement class Edge to meet that requirement? 您将如何实现Edge类以满足这一要求?

Perform a sort on the vertices in the constructor based on some unique identifier. 根据一些唯一的标识符对构造函数中的顶点执行排序。 This way they are stored consistently regardless of order. 这样,无论顺序如何,都可以一致地存储它们。

I find this preferable to noMAD's solution because all code interacting with these objects will treat them identically, not just your implementation of equals . 我发现这比noMAD的解决方案更可取,因为与这些对象交互的所有代码将对它们进行相同的对待,而不仅仅是您对equals的实现。

Also, calling your class members to and from is confusing because it sounds like a directed graph. 此外,调用类的成员tofrom是混乱,因为它听起来像一个有向图。 I would rename these to something more generic like vertex1 and vertex2 . 我将它们重命名为更通用的名称,例如vertex1vertex2

  public Edge(Vertex x, Vertex y) {
      if (vertex2.getId() > vertex1.getId()) {
          this.vertex1 = x;
          this.vertex2 = y;
      } else {
          this.vertex1 = y;
          this.vertex2 = x;
      }
  } 

I actually wouldn't have this logic in my Edge class but rather some sort of over-seeing class such as a Graph class. 实际上,我的Edge类中不会包含这种逻辑,而是某种可监督的类,例如Graph类。 The reason for this is because an Edge is just an object with 2 vertices. 其原因是因为“ Edge只是具有两个顶点的对象。 It doesn't know anything about the rest of the edges in the graph. 它对图形的其余边缘一无所知。

So, to expand on @noMad's answer, I would actually put his checkIfSameEdge method in my Graph class: 因此,为了扩展@noMad的答案,我实际上将他的checkIfSameEdge方法放在我的Graph类中:

public class Graph {
    private List<Edge> edges;
    ....
    public void addEdge(Edge e) {
        for (Edge edge : edges) {
            if (isSameEdge(edge, e) {
                return; // Edge already in Graph, nothing to do
        }
        edges.add(e);
    }
    private boolean isSameEdge(Edge edge1, Edge edge2) {
        return ((edge1.to.equals(edge2.to) && edge1.from.equals(edge2.from))
             || (edge1.to.equals(edge2.from) && edge1.from.equals(edge2.to)))
    }
}

BTW: I would rename to and from to vertex1 and vertex2 because it is an undirected graph and to and from indicate direction, but that's just my opion. BTW:我会重新命名tofromvertex1vertex2因为它是一个无向图,并和指示方向,但是这只是我的opion。

Well, of the top of my head, the naivest method would be: 好吧,在我的头上,最幼稚的方法是:

protected boolean checkIfSameEdge(Vertex to, Vertex from) {
  if(to.equals(this.from) && from.equals(this.to) || to.equals(this.to) && from.equals(this.from)) {
    return true;
  return false;
}

Obviously you would have to override equals and hashcode 显然,您将必须重写equalshashcode

假定节点包含某种标量值-根据这些值对参数进行排序(使用compareTo方法),并使用工厂创建新实例或返回现有实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM