views:

122

answers:

2

I can't figure out what's going wrong here. This test fails:

@Test
    public void testSimpleCase() {
     assertTrue(JGraphtUtilities.graphEquality(ChooseRootTest.generateSimpleCaseGraph(), ChooseRootTest.generateSimpleCaseGraph()));
    }

public static <V, E> boolean graphEquality(Graph<V, E> g0, Graph<V, E> g1) {

 boolean result = true;

 if (g0.edgeSet().equals(g1.edgeSet()) && g0.vertexSet().equals(g1.vertexSet())) {
  for (E e : g0.edgeSet()) {
   if (g0.getEdgeWeight(e) != g1.getEdgeWeight(e)) {
    result = false;
   }
  }
 }
 else {
  return false; //for the above test, this is what is returned
 }

 return result;
}

The debugger shows that the method decides that the two vertex sets and edge sets aren't equal, so it returns false. How is this possible?

Side note: I'm trying to write an equality check for JGraphT graphs. How is it possible that this hasn't been done already?

UPDATE: I think that DefaultWeightedEdge doesn't override equals, so that wouldn't work. I did a different way of checking that edges exist between all necessary vertices, and now it seems to work.

+1  A: 

According to the JavaDoc DefaultWeightedEdge hasn't implemented equals() and hashCode() and thus uses the methods defined in java.lang.Object. This means that two DefaultWeightedEdge objects a and b with the same values will not return true from a.equals(b). That would only return true if a and b actually refer to the same object.

You need to use an edge implementation class that implements .equals() and hashCode() to get useful results here.

Joachim Sauer
yeah, that's what I figured out. Do you have such an implementation in mind?
Rosarch
A: 

I'm not familiar with JGraphT, but there are two issues I can think of.

First, what does it mean for two sets of edges to be equivalent? What is it that makes two edges equivalent? If I create a graph, and create an identical graph separately, both might have the same structure. But if edge comparison of two matching edges uses the node identities, the two edges would not be "equal".

Second, I've noted this in the JavaDocs:

"The graph implementation may maintain a particular set ordering (e.g. via LinkedHashSet) for deterministic iteration, but this is not required. It is the responsibility of callers who rely on this behavior to only use graph implementations which support it."

I would try (at least for sanity) to make sure that the two sets contain each other, as it is possible that equals is not implemented correctly (e.g., it may take order into account).

Uri