Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding multiple vertices with the same data #2

Open
Carpetfizz opened this issue Mar 18, 2017 · 4 comments
Open

Adding multiple vertices with the same data #2

Carpetfizz opened this issue Mar 18, 2017 · 4 comments
Assignees

Comments

@Carpetfizz
Copy link

Hello,

Let's say I have a Vertex of the following form:

Vertex<MyClass> myVertex = new Vertex<>(myObject.getMessage());

In my program, it is possible for a Vertex with the same data to get graph.addVertex()'d. I want to be able to stop the graph from adding a Vertex if another one with the same data exists. I saw that the Vertex.hashCode is a function of some auto generated ID. If my data source is guaranteed to be unique elements, is it possible to make the hash a function of the data instead of a random ID ?

Thanks for any advice.

@HendrixString
Copy link
Member

hi @Carpetfizz
I may have a solution for you, but first read why we made the Vertex class instances unique.
the hash is not exactly random id. It is an auto incremented integer.
building in the hashcode of a message is dangerous. It has been thought of back
then when the library was designed, basically:

  • even if the vertex's hashcode depends on the message, you will still need to override equals()
    so that the graph will understand it already has that vertex.
  • when the lib was first designed, on of it's intents was to easily move vertices from
    one graph to another and even to duplicate graphs(we didn't do it), therefore we wanted
    every vertex to be unique, so we don't get collisions and we also didn't override the equals() method.
  • we even made hashcode final for that purpose in Vertex

but you still can do it, my suggestion is very simple:

  • graphs receive IVertex in graph.addVertex(..)
  • implement a new IVertex, that uses most of the Vertex implementation, and
    write your own hashcode and override equals(..)
  • you are welcome to contribute this new vertex afterwards

hope that helps

@Carpetfizz
Copy link
Author

Carpetfizz commented Mar 19, 2017

Thank you so much! I just copied and pasted the Vertex code and overrode the following functions:

@Override
public final int hashCode() {
    return "unique_vertex".hashCode() + getData().hashCode();
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }

    if (obj == null) {
        return false;
    }

    if (getClass() != obj.getClass()) {
        return false;
    }

    UniqueVertex otherUniqueVertex = (UniqueVertex) obj;

    return this.getData().equals(otherUniqueVertex.getData());
}

Now, I'm trying to do the same for DirectedEdge but but the Edge class has the following comment in the header:

directed edges with similar vertices and direction are equal (Java equality).

But I'm not finding this to be the case. The edges in the graph keep increasing as I add more of the same edge. Consider the following toString representation of my graph:

id=null, tag=null::V = {4, 2, 1, 3, } E = {4->2, 2->4, 4->1, 2->1, 4->2, 1->2, 4->3, 2->3, 1->3, }

The Vertex fix has worked thanks to your help, but the DirectedEdge 4->2 appears twice.

My requirement is that the edge should be the same but the edge's data can be different. I'm using the graph to map geometric relationships between vertices, which can change. So, the edge (1, 2, data=x) and (1,2, data=y) should count as the same edge between (1, 2) but the data should get updated.

Any advice on this would be appreciated.

@HendrixString
Copy link
Member

@Carpetfizz yeah I see. because we wanted to support multi-edges, i.e - multiple edges on the same two vertices, no two edges can be the same, even if they may be isomorphic, so you can
have two edges that may seem the same like 4->2. but, it should only appear in graphs that support multi edges. In your case it is a bug, that can be fixed as follows:

override the Vertex.getId() method so it will return the same id for two similar vertices, i.e vertices that have the same data. stringify the hashcode for example.
it should work, since, the graph engine adds and detects edges presence by the id of their vertices.

under the hood, it serializes like this:

public static String getEdgeDesc(IVertex v1, IVertex v2, EDGE_DIRECTION edgeType) {
        String res      = null;

        if(edgeType==EDGE_DIRECTION.DIRECTED) {
            res         =  (v1.getId() + "->" + v2.getId());
        }
        else if(edgeType==EDGE_DIRECTION.UNDIRECTED) {
            int compare = v1.getId().compareTo(v2.getId());
            if(compare < 0)
                res     = v1.getId() + "<->" + v2.getId();
            else
                res     = v2.getId() + "<->" + v1.getId();
        }

        return res;
    }

@Carpetfizz
Copy link
Author

Thanks again for the response, I think I left out another requirement by accident. I do indeed want a directed multigraph, but multiple edges connecting the same two vertices will definitely contain different data. Will your above solution still work in this scenario?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants