在JGraphT SimpleGraph中使用相等的顶点 [英] Use equal vertex in a JGraphT SimpleGraph

查看:183
本文介绍了在JGraphT SimpleGraph中使用相等的顶点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Java, want to create a simple graph (a unweighted, undirected graph containing no graph loops or multiple edges) containing vertexes/edges that are equal.

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

I have two Java Classes, one for the vertexes:

 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库.但是启动此代码后,我遇到了IllegalArgumentException: "loops not allowed":

I currently use the JGraphT library. But I ran into a IllegalArgumentException: "loops not allowed" after starting this code:

    // 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从未添加到图中.来自库的JavaDoc:

The problem is that i try to add v2 to the graph, but because v1.equals(v2) == true v2 is never added to the graph. From the JavaDoc of the lib:

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

Adds the specified vertex to this graph if not already present. More formally, adds the specified vertex, v, to this graph if this graph contains no vertex u such that u.equals(v).

此检查已实现此处.

但是,然后,我如何完成我想做的事情?我可以在此库中使用其他实现,还是更改equals()方法是一个好主意?

But then, how do I acomplish what I'm trying to do? Is there another implemention in this library that I could use for it, or is changing the equals() method a good idea?

推荐答案

在您看来,示例中的顶点v1和v2可以区分.然后,您必须确保它们对于图形也是可区分的.换句话说,请确保v1.equals(v2)返回false. 您可能需要考虑将成员变量"id"(或其他内容)添加到Vertex,并以该变量为基础的equals和哈希码.该成员变量的约定为具有相同id的两个顶点相等.

It seems that for you, vertices v1 and v2 in the example are distinguishable. Then you must make sure that they're distinguishable for the graph as well. In other words, make sure that v1.equals(v2) returns false. You might want to consider adding a member variable "id" (or something) to Vertex, and base equals and hashcode on that variable. The contract of that member variable would be that two vertices having the same id are equal.

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

If you then create two vertices with the same field, but different ids, then v1.equals(v2) will be false, and the two Vertex objects represent different vertices in the graph. For example:

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

然后,Vertex的构造函数必须像这样:

The constructor of Vertex would then have to look like:

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

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

Another solution would be to simply remove the hashcode and equals methods from Vertex, so that the inherited methods from Object are used, in which case two Vertex instances are equal if and only if they refer to the same object (i.e., memory address).

Edge类也是如此.我不确定您打算如何使用Edge的field属性,但我只是将其删除以避免遇到类似的问题.

The same holds for the Edge class. I'm not really sure about how you intend to use the Edge's field property, but I'd simply remove it to avoid running into the same kind of problem.

这篇关于在JGraphT SimpleGraph中使用相等的顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆