diff --git a/src/test/java/es/usc/citius/lab/hipster/algorithm/ADStarMazeTest.java b/src/test/java/es/usc/citius/lab/hipster/algorithm/ADStarMazeTest.java index ed5e130..597a89a 100644 --- a/src/test/java/es/usc/citius/lab/hipster/algorithm/ADStarMazeTest.java +++ b/src/test/java/es/usc/citius/lab/hipster/algorithm/ADStarMazeTest.java @@ -99,7 +99,7 @@ public void Dijkstra_Maze5() throws InterruptedException { private void execute(Maze2D maze, boolean heuristic) throws InterruptedException { ADStar it = AlgorithmIteratorFromMazeCreator.adstar(maze, heuristic); DirectedGraph> graph = JungDirectedGraphFromMazeCreator.create(maze); - MazeSearch.Result resultJung = MazeSearch.executeJungSearch(graph, maze); + MazeSearch.Result resultJung = MazeSearch.executeJungSearch(graph, maze.getInitialLoc(), maze.getGoalLoc()); //MazeSearch.Result resultIterator = MazeSearch.executePrintIteratorSearch(it, maze); //assertEquals(resultJung.getCost(), resultIterator.getCost(), 0.001); } diff --git a/src/test/java/es/usc/citius/lab/hipster/algorithm/AStarMazeTest.java b/src/test/java/es/usc/citius/lab/hipster/algorithm/AStarMazeTest.java index 84faab2..a8b81a6 100644 --- a/src/test/java/es/usc/citius/lab/hipster/algorithm/AStarMazeTest.java +++ b/src/test/java/es/usc/citius/lab/hipster/algorithm/AStarMazeTest.java @@ -106,7 +106,7 @@ private void execute(Maze2D maze, boolean heuristic) throws InterruptedException //AStar it = AStarIteratorFromMazeCreator.create(maze, heuristic); AStar it = AlgorithmIteratorFromMazeCreator.astar(maze, heuristic); DirectedGraph> graph = JungDirectedGraphFromMazeCreator.create(maze); - MazeSearch.Result resultJung = MazeSearch.executeJungSearch(graph, maze); + MazeSearch.Result resultJung = MazeSearch.executeJungSearch(graph, maze.getInitialLoc(), maze.getGoalLoc()); MazeSearch.Result resultIterator = MazeSearch.executePrintIteratorSearch(it, maze); assertEquals(resultIterator.getCost(), resultJung.getCost(), 0.001); } diff --git a/src/test/java/es/usc/citius/lab/hipster/algorithm/BellmanFordTest.java b/src/test/java/es/usc/citius/lab/hipster/algorithm/BellmanFordTest.java index 3f57274..f7f48cb 100644 --- a/src/test/java/es/usc/citius/lab/hipster/algorithm/BellmanFordTest.java +++ b/src/test/java/es/usc/citius/lab/hipster/algorithm/BellmanFordTest.java @@ -160,7 +160,7 @@ private void execute(Maze2D maze, boolean heuristic) DirectedGraph> graph = JungDirectedGraphFromMazeCreator .create(maze); MazeSearch.Result resultJung = MazeSearch - .executeJungSearch(graph, maze); + .executeJungSearch(graph, maze.getInitialLoc(), maze.getGoalLoc()); MazeSearch.Result resultIterator = MazeSearch .executePrintIteratorSearch(it, maze, false); assertEquals(resultIterator.getCost(), resultJung.getCost(), 0.001); diff --git a/src/test/java/es/usc/citius/lab/hipster/algorithm/BenchmarkTest.java b/src/test/java/es/usc/citius/lab/hipster/algorithm/BenchmarkTest.java index 7f6fa00..0418e33 100644 --- a/src/test/java/es/usc/citius/lab/hipster/algorithm/BenchmarkTest.java +++ b/src/test/java/es/usc/citius/lab/hipster/algorithm/BenchmarkTest.java @@ -20,6 +20,7 @@ import java.awt.Point; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.TimeUnit; @@ -29,11 +30,15 @@ import com.google.common.base.Stopwatch; import edu.uci.ics.jung.graph.DirectedGraph; +import es.usc.citius.lab.hipster.node.informed.CostNode; import es.usc.citius.lab.hipster.testutils.AlgorithmIteratorFromMazeCreator; -import es.usc.citius.lab.hipster.testutils.JungDirectedGraphFromMazeCreator; import es.usc.citius.lab.hipster.testutils.JungEdge; +import es.usc.citius.lab.hipster.testutils.JungMazeGraphComponentFactory; import es.usc.citius.lab.hipster.testutils.MazeSearch; +import es.usc.citius.lab.hipster.testutils.SearchComponentFactory; import es.usc.citius.lab.hipster.testutils.MazeSearch.Result; +import es.usc.citius.lab.hipster.testutils.MazeSearchComponentFactory; +import es.usc.citius.lab.hipster.testutils.SearchIterators; import es.usc.citius.lab.hipster.util.DoubleOperable; import es.usc.citius.lab.hipster.util.maze.Maze2D; @@ -102,6 +107,11 @@ Map run(Maze2D maze){ return results; } } + + private static SearchComponentFactory createComponentFactory(Maze2D maze){ + //return new MazeSearchComponentFactory(maze,false); + return new JungMazeGraphComponentFactory(maze, false); + } @Test public void benchmark() throws InterruptedException { @@ -112,46 +122,47 @@ public void benchmark() throws InterruptedException { Maze2D maze;DirectedGraph> graph; public void initialize(Maze2D maze) { this.maze = maze; - this.graph = JungDirectedGraphFromMazeCreator.create(maze); + this.graph = JungMazeGraphComponentFactory.createGraphFrom(maze); } public Result evaluate() { - return MazeSearch.executeJungSearch(graph, maze); + return MazeSearch.executeJungSearch(graph, maze.getInitialLoc(), maze.getGoalLoc()); } }); // Hipster-Dijkstra bench.add("Hipster-Dijkstra", new Algorithm() { - AStar it; Maze2D maze; + Iterator> it; Point goal; public void initialize(Maze2D maze) { - it= AlgorithmIteratorFromMazeCreator.astar(maze, false); - this.maze = maze; + it= SearchIterators.createAStar(createComponentFactory(maze)); + goal = maze.getGoalLoc(); } public Result evaluate() { - return MazeSearch.executeIteratorSearch(it, maze); + return MazeSearch.executeIteratorSearch(it, goal); } }); // Bellman-Ford bench.add("Hipster-Bellman-Ford", new Algorithm() { - BellmanFord it; Maze2D maze; + Iterator> it; Point goal; public void initialize(Maze2D maze) { - it= AlgorithmIteratorFromMazeCreator.bellmanFord(maze, false); - this.maze = maze; + it = SearchIterators.createBellmanFord(createComponentFactory(maze)); + goal = maze.getGoalLoc(); } public Result evaluate() { - return MazeSearch.executeIteratorSearch(it, maze); + return MazeSearch.executeIteratorSearch(it, goal); } }); // ADStar bench.add("Hipster-ADStar", new Algorithm() { - ADStar it; Maze2D maze; + Iterator> it; Point goal; public void initialize(Maze2D maze) { - it= AlgorithmIteratorFromMazeCreator.adstar(maze, false); - this.maze = maze; + it = SearchIterators.createADStar(createComponentFactory(maze)); + //it= AlgorithmIteratorFromMazeCreator.adstar(maze, false); + goal = maze.getGoalLoc(); } public Result evaluate() { - return MazeSearch.executeIteratorSearch(it, maze); + return MazeSearch.executeIteratorSearch(it, goal); } }); diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/ADStarIteratorFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/ADStarIteratorFactory.java new file mode 100644 index 0000000..e0d2273 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/ADStarIteratorFactory.java @@ -0,0 +1,36 @@ +package es.usc.citius.lab.hipster.testutils; + + +import java.util.Iterator; + +import es.usc.citius.lab.hipster.algorithm.ADStar; +import es.usc.citius.lab.hipster.node.NodeFactory; +import es.usc.citius.lab.hipster.node.adstar.ADStarNode; +import es.usc.citius.lab.hipster.node.adstar.ADStarNodeBuilder; +import es.usc.citius.lab.hipster.node.adstar.ADStarNodeUpdater; +import es.usc.citius.lab.hipster.node.informed.CostNode; +import es.usc.citius.lab.hipster.util.Scalable; + +public class ADStarIteratorFactory> implements + AlgorithmIteratorFactory { + private final SearchComponentFactory f; + + public ADStarIteratorFactory(SearchComponentFactory componentFactory) { + this.f = componentFactory; + } + + public Iterator> buildIteratorSearch() { + + NodeFactory> defaultBuilder = new ADStarNodeBuilder( + f.getDefaultValue(), f.getMaxValue()); + + ADStarNodeUpdater updater = new ADStarNodeUpdater( + f.getCostFunction(), f.getHeuristicFunction(), 1.0, + f.getMaxValue()); + + return new ADStar(f.getInitialState(), f.getGoalState(), + f.getTransitionFunction(), f.getTransitionFunction(), + defaultBuilder, updater); + } + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/AStarIteratorFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/AStarIteratorFactory.java new file mode 100644 index 0000000..b0d9e83 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/AStarIteratorFactory.java @@ -0,0 +1,30 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.util.Iterator; + +import es.usc.citius.lab.hipster.algorithm.AStar; +import es.usc.citius.lab.hipster.node.NodeFactory; +import es.usc.citius.lab.hipster.node.astar.InformedNodeFactory; +import es.usc.citius.lab.hipster.node.informed.CostNode; +import es.usc.citius.lab.hipster.node.informed.HeuristicNode; +import es.usc.citius.lab.hipster.util.Operable; + +public class AStarIteratorFactory> implements + AlgorithmIteratorFactory { + private final SearchComponentFactory f; + + public AStarIteratorFactory( + SearchComponentFactory componentFactory) { + this.f = componentFactory; + } + + public Iterator> buildIteratorSearch() { + NodeFactory> factory = new InformedNodeFactory( + f.getCostFunction(), + f.getHeuristicFunction(), + f.getDefaultValue()); + + return new AStar(f.getInitialState(), f.getTransitionFunction(), factory); + } + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/AlgorithmIteratorFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/AlgorithmIteratorFactory.java new file mode 100644 index 0000000..f4cfd06 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/AlgorithmIteratorFactory.java @@ -0,0 +1,14 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.util.Iterator; + +import es.usc.citius.lab.hipster.node.informed.CostNode; +import es.usc.citius.lab.hipster.util.Operable; + + + +public interface AlgorithmIteratorFactory> { + + Iterator> buildIteratorSearch(); + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/BellmanFordIteratorFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/BellmanFordIteratorFactory.java new file mode 100644 index 0000000..a5d2d7f --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/BellmanFordIteratorFactory.java @@ -0,0 +1,31 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.util.Iterator; + +import es.usc.citius.lab.hipster.algorithm.BellmanFord; +import es.usc.citius.lab.hipster.node.NodeFactory; +import es.usc.citius.lab.hipster.node.astar.InformedNodeFactory; +import es.usc.citius.lab.hipster.node.informed.CostNode; +import es.usc.citius.lab.hipster.util.Operable; + +public class BellmanFordIteratorFactory> implements + AlgorithmIteratorFactory { + private final SearchComponentFactory componentFactory; + + public BellmanFordIteratorFactory( + SearchComponentFactory componentFactory) { + this.componentFactory = componentFactory; + } + + public Iterator> buildIteratorSearch() { + NodeFactory> factory = new InformedNodeFactory( + componentFactory.getCostFunction(), componentFactory.getDefaultValue()) + .toCostNodeFactory(); + + return new BellmanFord( + componentFactory.getInitialState(), + componentFactory.getTransitionFunction(), factory); + + } + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/JungMazeGraphComponentFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/JungMazeGraphComponentFactory.java new file mode 100644 index 0000000..9d42898 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/JungMazeGraphComponentFactory.java @@ -0,0 +1,96 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.awt.Point; + +import edu.uci.ics.jung.graph.DirectedGraph; +import edu.uci.ics.jung.graph.DirectedSparseGraph; +import es.usc.citius.lab.hipster.function.CostFunction; +import es.usc.citius.lab.hipster.function.HeuristicFunction; +import es.usc.citius.lab.hipster.function.TransitionFunction; +import es.usc.citius.lab.hipster.node.Transition; +import es.usc.citius.lab.hipster.util.DoubleOperable; +import es.usc.citius.lab.hipster.util.maze.Maze2D; + +public class JungMazeGraphComponentFactory implements SearchComponentFactory { + private final DirectedGraph> graph; + private final Maze2D maze; + private boolean useHeuristic; + + public JungMazeGraphComponentFactory(Maze2D maze, boolean useHeuristic){ + this.maze = maze; + this.graph = createGraphFrom(maze); + this.useHeuristic = useHeuristic; + } + + public TransitionFunction getTransitionFunction() { + return new TransitionFunction() { + public Iterable> from(Point current) { + return Transition.map(current, graph.getNeighbors(current)); + } + }; + } + + public CostFunction getCostFunction() { + return new CostFunction() { + public DoubleOperable evaluate(Transition transition) { + return new DoubleOperable(graph.findEdge(transition.from(), transition.to()).getCost()); + } + }; + } + + public HeuristicFunction getHeuristicFunction() { + return new HeuristicFunction() { + public DoubleOperable estimate(Point state) { + if (useHeuristic){ + return new DoubleOperable(state.distance(maze.getGoalLoc())); + } else { + return DoubleOperable.MIN; + } + } + }; + } + + public Point getInitialState() { + return maze.getInitialLoc(); + } + + public Point getGoalState() { + return maze.getGoalLoc(); + } + + public static DirectedGraph> createGraphFrom(Maze2D maze) { + // Create a graph from maze + DirectedGraph> graph = new DirectedSparseGraph>(); + // Convert maze to graph. For each cell, add all valid neighbors with + // their costs + for (Point source : maze.getMazePoints()) { + if (!graph.containsVertex(source)) { + graph.addVertex(source); + } + for (Point dest : maze.validLocationsFrom(source)) { + if (!graph.containsVertex(dest)) { + graph.addVertex(dest); + } + double edgeCost = Math.sqrt((source.x - dest.x) + * (source.x - dest.x) + (source.y - dest.y) + * (source.y - dest.y)); + JungEdge e = new JungEdge(source, dest, edgeCost); + if (!graph.containsEdge(e)) { + graph.addEdge(e, source, dest); + } + } + } + return graph; + } + + public DoubleOperable getDefaultValue() { + return DoubleOperable.MIN; + } + + public DoubleOperable getMaxValue() { + return DoubleOperable.MAX; + } + + + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearch.java b/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearch.java index 2e26a1a..c841108 100644 --- a/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearch.java +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearch.java @@ -229,12 +229,12 @@ public static String getMazeStringSolution(Maze2D maze, Collection explor //public static Result executeIteratorSearch(AStar it, StringMaze maze) { - public static Result executeIteratorSearch(Iterator> it, Maze2D maze) { + public static Result executeIteratorSearch(Iterator> it, Point goal) { int steps = 0; while (it.hasNext()) { CostNode currentNode = it.next(); steps++; - if (currentNode.transition().to().equals(maze.getGoalLoc())) { + if (currentNode.transition().to().equals(goal)) { List> nodePath = currentNode.path(); Double cost = currentNode.getCost().getValue();//new DoubleCostEvaluator().evaluate(nodePath, AlgorithmIteratorFromMazeCreator.defaultCostFunction()); List statePath = new NodeToStateListConverter().convert(nodePath); @@ -245,15 +245,14 @@ public static Result executeIteratorSearch(Iterator> jungGraph, Maze2D maze) { + public static Result executeJungSearch(DirectedGraph> jungGraph, Point initial, Point goal) { DijkstraShortestPath> dijkstra = new DijkstraShortestPath>( jungGraph, new Transformer, Double>() { public Double transform(JungEdge input) { return input.getCost(); } }, true); - List> path = dijkstra.getPath(maze.getInitialLoc(), - maze.getGoalLoc()); + List> path = dijkstra.getPath(initial,goal); Double cost = 0.0; List statePath = new ArrayList(); if(path.isEmpty()){ @@ -264,7 +263,7 @@ public Double transform(JungEdge input) { statePath.add(current.getSource()); cost += current.getCost(); } - statePath.add(maze.getGoalLoc()); + statePath.add(goal); return new Result(statePath, cost); } diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearchComponentFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearchComponentFactory.java new file mode 100644 index 0000000..1f91286 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/MazeSearchComponentFactory.java @@ -0,0 +1,66 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.awt.Point; + +import es.usc.citius.lab.hipster.function.CostFunction; +import es.usc.citius.lab.hipster.function.HeuristicFunction; +import es.usc.citius.lab.hipster.function.TransitionFunction; +import es.usc.citius.lab.hipster.node.Transition; +import es.usc.citius.lab.hipster.util.DoubleOperable; +import es.usc.citius.lab.hipster.util.maze.Maze2D; + +public class MazeSearchComponentFactory implements SearchComponentFactory { + private final Maze2D maze; + private boolean useHeuristic; + + public MazeSearchComponentFactory(Maze2D maze, boolean useHeuristic){ + this.maze = maze; + this.useHeuristic = useHeuristic; + } + + public TransitionFunction getTransitionFunction() { + return new TransitionFunction() { + public Iterable> from(Point current) { + return Transition.map(current, maze.validLocationsFrom(current)); + } + }; + } + + public CostFunction getCostFunction() { + return new CostFunction() { + public DoubleOperable evaluate(Transition transition) { + return new DoubleOperable(transition.from().distance(transition.to())); + } + }; + } + + public HeuristicFunction getHeuristicFunction() { + return new HeuristicFunction() { + public DoubleOperable estimate(Point state) { + if (useHeuristic){ + return new DoubleOperable(state.distance(maze.getGoalLoc())); + } else { + return DoubleOperable.MIN; + } + } + }; + } + + public Point getInitialState() { + return maze.getInitialLoc(); + } + + public Point getGoalState() { + return maze.getGoalLoc(); + } + + public DoubleOperable getDefaultValue() { + return DoubleOperable.MIN; + } + + public DoubleOperable getMaxValue() { + return DoubleOperable.MAX; + } + + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/SearchComponentFactory.java b/src/test/java/es/usc/citius/lab/hipster/testutils/SearchComponentFactory.java new file mode 100644 index 0000000..0f81d0d --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/SearchComponentFactory.java @@ -0,0 +1,19 @@ +package es.usc.citius.lab.hipster.testutils; + + +import es.usc.citius.lab.hipster.function.CostFunction; +import es.usc.citius.lab.hipster.function.HeuristicFunction; +import es.usc.citius.lab.hipster.function.TransitionFunction; +import es.usc.citius.lab.hipster.util.Operable; + +public interface SearchComponentFactory> { + + TransitionFunction getTransitionFunction(); + CostFunction getCostFunction(); + HeuristicFunction getHeuristicFunction(); + S getInitialState(); + S getGoalState(); + T getDefaultValue(); + T getMaxValue(); + +} diff --git a/src/test/java/es/usc/citius/lab/hipster/testutils/SearchIterators.java b/src/test/java/es/usc/citius/lab/hipster/testutils/SearchIterators.java new file mode 100644 index 0000000..7634632 --- /dev/null +++ b/src/test/java/es/usc/citius/lab/hipster/testutils/SearchIterators.java @@ -0,0 +1,25 @@ +package es.usc.citius.lab.hipster.testutils; + +import java.util.Iterator; + +import es.usc.citius.lab.hipster.node.informed.CostNode; +import es.usc.citius.lab.hipster.util.Operable; +import es.usc.citius.lab.hipster.util.Scalable; + +public final class SearchIterators { + + private SearchIterators(){}; + + public static > Iterator> createAStar(SearchComponentFactory componentFactory){ + return new AStarIteratorFactory(componentFactory).buildIteratorSearch(); + } + + public static > Iterator> createBellmanFord(SearchComponentFactory componentFactory){ + return new BellmanFordIteratorFactory(componentFactory).buildIteratorSearch(); + } + + public static > Iterator> createADStar(SearchComponentFactory componentFactory){ + return new ADStarIteratorFactory(componentFactory).buildIteratorSearch(); + } + +}