/* ========================================== * JGraphT : a free Java graph-theory library * ========================================== * * Project Info: http://jgrapht.sourceforge.net/ * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh) * * (C) Copyright 2003-2008, by Barak Naveh and Contributors. * * This program and the accompanying materials are dual-licensed under * either * * (a) the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation, or (at your option) any * later version. * * or (per the licensee's choosing) * * (b) the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation. */ /* ----------------- * AdaptiveIsomorphismInspectorFactory.java * ----------------- * (C) Copyright 2005-2008, by Assaf Lehr and Contributors. * * Original Author: Assaf Lehr * Contributor(s): - * * $Id: AdaptiveIsomorphismInspectorFactory.java 485 2006-06-26 09:12:14Z * perfecthash $ * * Changes * ------- */ package org.jgrapht.experimental.isomorphism; import org.jgrapht.*; import org.jgrapht.experimental.equivalence.*; import org.jgrapht.graph.*; /** * This class serves as a factory for GraphIsomorphismInspector concrete * implementations. It can be used in two ways: * <li>You can can let this class to determine what is the most efficient * algorithm for your graph. * <li>You can specify the type of your graph (planar / tree / other) and save * this class the graph-checking time. * * <p>Note that the concrete implementations are package-private and should not * be created directly. If you are the maintainer of the package, you can add * new implementation classes, and add them to the "check-list". The current * algorithms do not support graphs with multiple edges (Multigraph / * Pseudograph) * * @author Assaf * @see GraphIsomorphismInspector * @since Jul 17, 2005 */ public class AdaptiveIsomorphismInspectorFactory { public static final int GRAPH_TYPE_ARBITRARY = 0; public static final int GRAPH_TYPE_PLANAR = 1; public static final int GRAPH_TYPE_TREE = 2; public static final int GRAPH_TYPE_MULTIGRAPH = 3; /** * Creates a new inspector, letting this class determine what is the most * efficient algorithm. * * @param graph1 * @param graph2 * @param vertexChecker may be null * @param edgeChecker may be null */ public static <V, E> GraphIsomorphismInspector createIsomorphismInspector( Graph<V, E> graph1, Graph<V, E> graph2, EquivalenceComparator<V, Graph<V, E>> vertexChecker, EquivalenceComparator<E, Graph<V, E>> edgeChecker) { int graphType = checkGraphsType(graph1, graph2); return createAppropriateConcreteInspector( graphType, graph1, graph2, vertexChecker, edgeChecker); } /** * Creates a new inspector, letting this class determine what is the most * efficient algorithm and using default equivalence comparators. * * <p>same as calling createIsomorphismInspector(graph1,graph2,null,null); * * @param graph1 * @param graph2 */ public static <V, E> GraphIsomorphismInspector createIsomorphismInspector( Graph<V, E> graph1, Graph<V, E> graph2) { return createIsomorphismInspector(graph1, graph2, null, null); } /** * Creates a new inspector for a particular graph type (planar / tree / * other). * * @param type - AdaptiveIsomorphismInspectorFactory.GRAPH_TYPE_XXX * @param graph1 * @param graph2 * @param vertexChecker - can be null * @param edgeChecker - can be null */ public static <V, E> GraphIsomorphismInspector createIsomorphismInspectorByType( int type, Graph<V, E> graph1, Graph<V, E> graph2, EquivalenceComparator<V, Graph<V, E>> vertexChecker, EquivalenceComparator<E, Graph<V, E>> edgeChecker) { return createAppropriateConcreteInspector( type, graph1, graph2, vertexChecker, edgeChecker); } /** * Creates a new inspector for a particular graph type (planar / tree / * other) using default equivalence comparators. * * <p>same as calling * createAppropriateConcreteInspector(graph1,graph2,null,null); * * @param type - AdaptiveIsomorphismInspectorFactory.GRAPH_TYPE_XXX * @param graph1 * @param graph2 */ public static <V, E> GraphIsomorphismInspector createIsomorphismInspectorByType( int type, Graph<V, E> graph1, Graph<V, E> graph2) { return createAppropriateConcreteInspector( type, graph1, graph2, null, null); } /** * Checks the graph type, and accordingly decides which type of concrete * inspector class to create. This implementation creates an exhaustive * inspector without further tests, because no other implementations are * available yet. * * @param graph1 * @param graph2 * @param vertexChecker * @param edgeChecker */ protected static <V, E> GraphIsomorphismInspector createAppropriateConcreteInspector( int graphType, Graph<V, E> graph1, Graph<V, E> graph2, EquivalenceComparator<V, Graph<V, E>> vertexChecker, EquivalenceComparator<E, Graph<V, E>> edgeChecker) { assertUnsupportedGraphTypes(graph1); assertUnsupportedGraphTypes(graph2); GraphIsomorphismInspector currentInspector = null; switch (graphType) { case GRAPH_TYPE_PLANAR: case GRAPH_TYPE_TREE: case GRAPH_TYPE_ARBITRARY: currentInspector = createTopologicalExhaustiveInspector( graph1, graph2, vertexChecker, edgeChecker); break; default: throw new IllegalArgumentException( "The type was not one of the supported types."); } return currentInspector; } /** * Checks if one of the graphs is from unsupported graph type and throws * IllegalArgumentException if it is. The current unsupported types are * graphs with multiple-edges. * * @param g * * @throws IllegalArgumentException */ protected static void assertUnsupportedGraphTypes(Graph g) throws IllegalArgumentException { if ((g instanceof Multigraph<?, ?>) || (g instanceof DirectedMultigraph<?, ?>) || (g instanceof Pseudograph<?, ?>)) { throw new IllegalArgumentException( "graph type not supported for the graph" + g); } } protected static int checkGraphsType(Graph graph1, Graph graph2) { return GRAPH_TYPE_ARBITRARY; } /** * @return ExhaustiveInspector, where the equivalence comparator is chained * with a topological comparator. This implementation uses: * <li>vertex degree size comparator */ @SuppressWarnings("unchecked") protected static <V, E> GraphIsomorphismInspector createTopologicalExhaustiveInspector( Graph<V, E> graph1, Graph<V, E> graph2, EquivalenceComparator<V, Graph<V, E>> vertexChecker, EquivalenceComparator<E, Graph<V, E>> edgeChecker) { VertexDegreeEquivalenceComparator<V, E> degreeComparator = new VertexDegreeEquivalenceComparator<V, E>(); EquivalenceComparatorChain<V, Graph<V, E>> vertexChainedChecker = new EquivalenceComparatorChainBase<V, Graph<V, E>>( degreeComparator); vertexChainedChecker.appendComparator(vertexChecker); GraphIsomorphismInspector inspector = // FIXME hb060208 I don't understand how to generify this, yet new EquivalenceIsomorphismInspector( graph1, graph2, vertexChainedChecker, edgeChecker); return inspector; } } // End AdaptiveIsomorphismInspectorFactory.java