123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package org.insa.graphs.algorithm;
-
- import java.lang.reflect.Constructor;
- import java.util.IdentityHashMap;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import java.util.Set;
- import java.util.TreeSet;
-
- import org.insa.graphs.algorithm.shortestpath.AStarAlgorithm;
- import org.insa.graphs.algorithm.shortestpath.BellmanFordAlgorithm;
- import org.insa.graphs.algorithm.shortestpath.DijkstraAlgorithm;
- import org.insa.graphs.algorithm.shortestpath.ShortestPathAlgorithm;
- import org.insa.graphs.algorithm.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
-
- /**
- * Factory class used to register and retrieve algorithms based on their common
- * ancestor and name.
- *
- */
- public class AlgorithmFactory {
-
- // Map between algorithm names and class.
- private final static Map<Class<? extends AbstractAlgorithm<?>>, Map<String, Class<? extends AbstractAlgorithm<?>>>> ALGORITHMS = new IdentityHashMap<>();
-
- static {
- // Register weakly-connected components algorithm:
- registerAlgorithm(WeaklyConnectedComponentsAlgorithm.class, "WCC basic",
- WeaklyConnectedComponentsAlgorithm.class);
-
- // Register shortest path algorithm:
- registerAlgorithm(ShortestPathAlgorithm.class, "Bellman-Ford", BellmanFordAlgorithm.class);
- registerAlgorithm(ShortestPathAlgorithm.class, "Dijkstra", DijkstraAlgorithm.class);
- registerAlgorithm(ShortestPathAlgorithm.class, "A*", AStarAlgorithm.class);
-
- // Register your algorithms here:
- // registerAlgorithm(CarPoolingAlgorithm.class, "My Awesome Algorithm",
- // MyCarPoolingAlgorithm.class);
- }
-
- /**
- * Register the given algorithm class with the given name as a child class of
- * the given base algorithm.
- *
- * @param baseAlgorithm Base algorithm class that corresponds to the newly
- * registered algorithm class (e.g., generic algorithm
- * class for the problem).
- * @param name Name for the registered algorithm class.
- * @param algoClass Algorithm class to register.
- */
- public static void registerAlgorithm(Class<? extends AbstractAlgorithm<?>> baseAlgorithm,
- String name, Class<? extends AbstractAlgorithm<?>> algoClass) {
- if (!ALGORITHMS.containsKey(baseAlgorithm)) {
- ALGORITHMS.put(baseAlgorithm, new LinkedHashMap<>());
- }
- ALGORITHMS.get(baseAlgorithm).put(name, algoClass);
- }
-
- /**
- * Create an instance of the given algorithm class using the given input data.
- * Assuming algorithm correspond to a class "Algorithm", this function returns
- * an object equivalent to `new Algorithm(data)`.
- *
- * @param algorithm Class of the algorithm to create.
- * @param data Input data for the algorithm.
- *
- * @return A new instance of the given algorithm class using the given data.
- *
- * @throws Exception if something wrong happens when constructing the object,
- * i.e. the given input data does not correspond to the given
- * algorithm and/or no constructor that takes a single
- * parameter of type (data.getClass()) exists.
- */
- public static AbstractAlgorithm<?> createAlgorithm(
- Class<? extends AbstractAlgorithm<?>> algorithm, AbstractInputData data)
- throws Exception {
- // Retrieve the set of constructors for the given algorithm class.
- Constructor<?>[] constructors = algorithm.getDeclaredConstructors();
-
- // Within this set, find the constructor that can be called with "data" (only).
- AbstractAlgorithm<?> constructed = null;
- for (Constructor<?> c: constructors) {
- Class<?>[] params = c.getParameterTypes();
- if (params.length == 1 && params[0].isAssignableFrom(data.getClass())) {
- c.setAccessible(true);
- constructed = (AbstractAlgorithm<?>) c.newInstance(new Object[] { data });
- break;
- }
- }
- return constructed;
- }
-
- /**
- * Return the algorithm class corresponding to the given base algorithm class
- * and name. The algorithm must have been previously registered using
- * registerAlgorithm.
- *
- * @param baseAlgorithm Base algorithm class for the algorithm to retrieve.
- * @param name Name of the algorithm to retrieve.
- *
- * @return Class corresponding to the given name.
- *
- * @see #registerAlgorithm
- */
- public static Class<? extends AbstractAlgorithm<?>> getAlgorithmClass(
- Class<? extends AbstractAlgorithm<?>> baseAlgorithm, String name) {
- return ALGORITHMS.get(baseAlgorithm).get(name);
- }
-
- /**
- * Return the list of names corresponding to the registered algorithm classes
- * for the given base algorithm class.
- *
- * @param baseAlgorithm Base algorithm class for the algorithm class names to
- * retrieve.
- *
- * @return Names of the currently registered algorithms.
- *
- * @see #registerAlgorithm
- */
- public static Set<String> getAlgorithmNames(
- Class<? extends AbstractAlgorithm<?>> baseAlgorithm) {
- if (!ALGORITHMS.containsKey(baseAlgorithm)) {
- return new TreeSet<>();
- }
- return ALGORITHMS.get(baseAlgorithm).keySet();
- }
- }
|