All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.graphs.core.GraphEquivalence Maven / Gradle / Ivy

There is a newer version: 0.71.2
Show newest version
package cdc.graphs.core;

import java.util.HashSet;
import java.util.Set;

import cdc.graphs.GraphAdapter;

/**
 * Comparison of 2 graphs.
 * 

* Nodes and edges can be compared using an {@link Informer}.
* All nodes MUST be distinct.
* All edges MUST be distinct.
* The edge constraint could be relaxed someday. *

* {@link Informer} allows to define specific hash code and equality computation. * It may be sometimes necessary to use predefined equals and hashCode for nods and edges, * which is inappropriate for graph comparison. * * @author Damien Carbonne * * @param The node type. * @param The edge type. */ public class GraphEquivalence { private final Informer nodesInformer; private final Informer edgesInformer; public GraphEquivalence(Informer nodesInformer, Informer edgesInformer) { this.nodesInformer = nodesInformer; this.edgesInformer = edgesInformer; } private Set wrapNodes(GraphAdapter adapter) { final Set wrappers = new HashSet<>(); for (final N node : adapter.getNodes()) { wrappers.add(new NodeWrapper(node)); } return wrappers; } private Set wrapEdges(GraphAdapter adapter) { final Set wrappers = new HashSet<>(); for (final E edge : adapter.getEdges()) { wrappers.add(new EdgeWrapper(edge)); } return wrappers; } private static Set added(Set left, Set right) { final Set set = new HashSet<>(right); set.removeAll(left); return set; } private static Set removed(Set left, Set right) { final Set set = new HashSet<>(left); set.removeAll(right); return set; } public GraphDiff compare(GraphAdapter left, GraphAdapter right) { final Set leftNodes = wrapNodes(left); final Set leftEdges = wrapEdges(left); final Set rightNodes = wrapNodes(right); final Set rightEdges = wrapEdges(right); final Set addedNodes = added(leftNodes, rightNodes); final Set removedNodes = removed(leftNodes, rightNodes); final Set addedEdges = added(leftEdges, rightEdges); final Set removedEdges = removed(leftEdges, rightEdges); final GraphDiff diffs = new GraphDiff<>(); for (final NodeWrapper wrapper : addedNodes) { diffs.addAddedNode(wrapper.delegate); } for (final NodeWrapper wrapper : removedNodes) { diffs.addRemovedNode(wrapper.delegate); } for (final EdgeWrapper wrapper : addedEdges) { diffs.addAddedEdge(wrapper.delegate); } for (final EdgeWrapper wrapper : removedEdges) { diffs.addRemovedEdge(wrapper.delegate); } return diffs; } /** * Interface used to extract comparison information on an object. * * @param The object type. */ public static interface Informer { /** * @param object The object. * @return The hash code of {@code object}. It may differ from {@code object.hashCode()}. */ public int hashCode(T object); /** * * @param o1 The first object. * @param o2 The second object. * @return {@code true} if {@code o1} and {@code o2} are equal.
* This may differ from {@code o1.equals(o2)} * or {@code o2.equals(o1)}. */ public boolean areEqual(T o1, T o2); } class NodeWrapper { private final N delegate; NodeWrapper(N delegate) { this.delegate = delegate; } @Override public int hashCode() { return GraphEquivalence.this.nodesInformer.hashCode(delegate); } @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof GraphEquivalence.NodeWrapper)) { return false; } @SuppressWarnings("unchecked") final GraphEquivalence.NodeWrapper other = (GraphEquivalence.NodeWrapper) object; return GraphEquivalence.this.nodesInformer.areEqual(delegate, other.delegate); } } class EdgeWrapper { private final E delegate; EdgeWrapper(E delegate) { this.delegate = delegate; } @Override public int hashCode() { return GraphEquivalence.this.edgesInformer.hashCode(delegate); } @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof GraphEquivalence.NodeWrapper)) { return false; } @SuppressWarnings("unchecked") final GraphEquivalence.EdgeWrapper other = (GraphEquivalence.EdgeWrapper) object; return GraphEquivalence.this.edgesInformer.areEqual(delegate, other.delegate); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy