在JGraphT SimpleGraph中使用相等的顶点

时间:2014-04-16 15:57:34

标签: java graph-theory jgrapht

在Java中,想要创建一个包含相等顶点/边的简单图形(一个不包含图形循环或多边的未加权无向图)。

我有两个Java类,一个用于顶点:

 class Vertex {

    private int field;

    public Vertex(int field) {
        this.field = field;
    }

    @Override
    public boolean equals(Object obj) {

        if (obj.getClass().getPackage()
                .equals(this.getClass().getPackage())
                && obj.getClass().getName()
                        .equals(this.getClass().getName())) {

            Vertex vertex = (Vertex) obj;

            if (this.field == vertex.field)
                return true;
        }

        // Else
        return false;
    }

    @Override
    public int hashCode() {
        // No need for a perfect hash
        return this.field;
    }
}

边缘的一个类:

class Edge {

    private int field;

    public Edge(int field) {
        this.field = field;
    }

    @Override
    public boolean equals(Object obj) {

        if (obj.getClass().getPackage()
                .equals(this.getClass().getPackage())
                && obj.getClass().getName()
                        .equals(this.getClass().getName())) {

            Edge edge = (Edge) obj;

            if (this.field == edge.field)
                return true;
        }

        // Else
        return false;
    }

    @Override
    public int hashCode() {
        // No need for a perfect hash
        return this.field;
    }
}

我目前使用JGraphT library。但是在开始这段代码之后我遇到了IllegalArgumentException: "loops not allowed"

    // Define a EdgeFactory
    EdgeFactory<Vertex, Edge> BOND_FACTORY = new EdgeFactory<Vertex, Edge>() {
        @Override
        public Edge createEdge(Vertex sourceVertex, Vertex targetVertex) {
            return new Edge(2);
        }
    };
    // Create the graph
    SimpleGraph<Vertex, Edge> graph = new SimpleGraph<Vertex, Edge>(
            BOND_FACTORY);

    // Create vertexes
    Vertex v1 = new Vertex(1);
    Vertex v2 = new Vertex(1);

    // Add them to the graph
    graph.addVertex(v1);
    graph.addVertex(v2);
    graph.addEdge(v1, v2);

问题是我尝试将v2添加到图表中,但因为v1.equals(v2) == true v2从未添加到图表中。来自lib的JavaDoc:

  

如果尚未存在,则将指定的顶点添加到此图形中。更正式地说,如果此图形不包含u.equals(v)的顶点u,则将指定的顶点v添加到此图形中。

此检查已实施here

但是,我如何才能完成我想要做的事情?我可以在这个库中使用另一个实现,或者更改equals()方法是个好主意吗?

1 个答案:

答案 0 :(得分:1)

似乎对你来说,示例中的顶点v1和v2是可区分的。然后你必须确保它们也可以与图形区分开来。换句话说,请确保v1.equals(v2)返回false。 您可能需要考虑向Vertex添加成员变量“id”(或其他内容),并在该变量上添加equals和hashcode。该成员变量的契约是两个具有相同id的顶点相等。

如果然后创建两个具有相同字段但具有不同ID的顶点,则v1.equals(v2)将为false,并且两个Vertex对象表示图形中的不同顶点。例如:

Vertex v1 = new Vertex("a", 1);
Vertex v2 = new Vertex("b", 1);

Vertex的构造函数必须如下所示:

public Vertex(String id, int field) {
  this.id = id;
  this.field = field;
}

另一个解决方案是简单地从Vertex中删除hashcode和equals方法,以便使用Object中的继承方法,在这种情况下,两个Vertex实例相等,当且仅当它们引用同一个对象时(即内存)地址)。

Edge类也是如此。我不太确定你打算如何使用Edge的字段属性,但我只是删除它以避免遇到同样的问题。