Skip to content

Commit

Permalink
TestUtils completely rewritten. Now it's possible to test all the
Browse files Browse the repository at this point in the history
algorithms using the Maze2D or the jung-graph. Close citiususc#44
  • Loading branch information
Pablo Rodríguez Mier committed Apr 21, 2013
1 parent 6ef9863 commit 898e3ce
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public void Dijkstra_Maze5() throws InterruptedException {
private void execute(Maze2D maze, boolean heuristic) throws InterruptedException {
ADStar<Point, DoubleOperable> it = AlgorithmIteratorFromMazeCreator.adstar(maze, heuristic);
DirectedGraph<Point, JungEdge<Point>> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private void execute(Maze2D maze, boolean heuristic) throws InterruptedException
//AStar<Point> it = AStarIteratorFromMazeCreator.create(maze, heuristic);
AStar<Point,DoubleOperable> it = AlgorithmIteratorFromMazeCreator.astar(maze, heuristic);
DirectedGraph<Point, JungEdge<Point>> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ private void execute(Maze2D maze, boolean heuristic)
DirectedGraph<Point, JungEdge<Point>> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -102,6 +107,11 @@ Map<String, Score> run(Maze2D maze){
return results;
}
}

private static SearchComponentFactory<Point,DoubleOperable> createComponentFactory(Maze2D maze){
//return new MazeSearchComponentFactory(maze,false);
return new JungMazeGraphComponentFactory(maze, false);
}

@Test
public void benchmark() throws InterruptedException {
Expand All @@ -112,46 +122,47 @@ public void benchmark() throws InterruptedException {
Maze2D maze;DirectedGraph<Point, JungEdge<Point>> 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<Point, DoubleOperable> it; Maze2D maze;
Iterator<? extends CostNode<Point, DoubleOperable>> 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<Point, DoubleOperable> it; Maze2D maze;
Iterator<? extends CostNode<Point, DoubleOperable>> 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<Point, DoubleOperable> it; Maze2D maze;
Iterator<? extends CostNode<Point, DoubleOperable>> 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);
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -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<S, T extends Scalable<T>> implements
AlgorithmIteratorFactory<S, T> {
private final SearchComponentFactory<S, T> f;

public ADStarIteratorFactory(SearchComponentFactory<S, T> componentFactory) {
this.f = componentFactory;
}

public Iterator<? extends CostNode<S, T>> buildIteratorSearch() {

NodeFactory<S, ADStarNode<S, T>> defaultBuilder = new ADStarNodeBuilder<S, T>(
f.getDefaultValue(), f.getMaxValue());

ADStarNodeUpdater<S, T> updater = new ADStarNodeUpdater<S, T>(
f.getCostFunction(), f.getHeuristicFunction(), 1.0,
f.getMaxValue());

return new ADStar<S, T>(f.getInitialState(), f.getGoalState(),
f.getTransitionFunction(), f.getTransitionFunction(),
defaultBuilder, updater);
}

}
Original file line number Diff line number Diff line change
@@ -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<S, T extends Operable<T>> implements
AlgorithmIteratorFactory<S, T> {
private final SearchComponentFactory<S, T> f;

public AStarIteratorFactory(
SearchComponentFactory<S, T> componentFactory) {
this.f = componentFactory;
}

public Iterator<? extends CostNode<S, T>> buildIteratorSearch() {
NodeFactory<S, HeuristicNode<S, T>> factory = new InformedNodeFactory<S, T>(
f.getCostFunction(),
f.getHeuristicFunction(),
f.getDefaultValue());

return new AStar<S, T>(f.getInitialState(), f.getTransitionFunction(), factory);
}

}
Original file line number Diff line number Diff line change
@@ -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<S, T extends Operable<T>> {

Iterator<? extends CostNode<S,T>> buildIteratorSearch();

}
Original file line number Diff line number Diff line change
@@ -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<S, T extends Operable<T>> implements
AlgorithmIteratorFactory<S, T> {
private final SearchComponentFactory<S, T> componentFactory;

public BellmanFordIteratorFactory(
SearchComponentFactory<S, T> componentFactory) {
this.componentFactory = componentFactory;
}

public Iterator<? extends CostNode<S, T>> buildIteratorSearch() {
NodeFactory<S, CostNode<S, T>> factory = new InformedNodeFactory<S, T>(
componentFactory.getCostFunction(), componentFactory.getDefaultValue())
.toCostNodeFactory();

return new BellmanFord<S, T>(
componentFactory.getInitialState(),
componentFactory.getTransitionFunction(), factory);

}

}
Original file line number Diff line number Diff line change
@@ -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<Point, DoubleOperable> {
private final DirectedGraph<Point, JungEdge<Point>> 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<Point> getTransitionFunction() {
return new TransitionFunction<Point>() {
public Iterable<Transition<Point>> from(Point current) {
return Transition.map(current, graph.getNeighbors(current));
}
};
}

public CostFunction<Point, DoubleOperable> getCostFunction() {
return new CostFunction<Point, DoubleOperable>() {
public DoubleOperable evaluate(Transition<Point> transition) {
return new DoubleOperable(graph.findEdge(transition.from(), transition.to()).getCost());
}
};
}

public HeuristicFunction<Point, DoubleOperable> getHeuristicFunction() {
return new HeuristicFunction<Point, DoubleOperable>() {
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<Point, JungEdge<Point>> createGraphFrom(Maze2D maze) {
// Create a graph from maze
DirectedGraph<Point, JungEdge<Point>> graph = new DirectedSparseGraph<Point, JungEdge<Point>>();
// 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<Point> e = new JungEdge<Point>(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;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ public static String getMazeStringSolution(Maze2D maze, Collection<Point> explor

//public static Result executeIteratorSearch(AStar<Point> it, StringMaze maze) {

public static Result executeIteratorSearch(Iterator<? extends CostNode<Point, DoubleOperable>> it, Maze2D maze) {
public static Result executeIteratorSearch(Iterator<? extends CostNode<Point, DoubleOperable>> it, Point goal) {
int steps = 0;
while (it.hasNext()) {
CostNode<Point, DoubleOperable> currentNode = it.next();
steps++;
if (currentNode.transition().to().equals(maze.getGoalLoc())) {
if (currentNode.transition().to().equals(goal)) {
List<Node<Point>> nodePath = currentNode.path();
Double cost = currentNode.getCost().getValue();//new DoubleCostEvaluator<Point>().evaluate(nodePath, AlgorithmIteratorFromMazeCreator.defaultCostFunction());
List<Point> statePath = new NodeToStateListConverter<Point>().convert(nodePath);
Expand All @@ -245,15 +245,14 @@ public static Result executeIteratorSearch(Iterator<? extends CostNode<Point, Do
return null;
}

public static Result executeJungSearch(DirectedGraph<Point, JungEdge<Point>> jungGraph, Maze2D maze) {
public static Result executeJungSearch(DirectedGraph<Point, JungEdge<Point>> jungGraph, Point initial, Point goal) {
DijkstraShortestPath<Point, JungEdge<Point>> dijkstra = new DijkstraShortestPath<Point, JungEdge<Point>>(
jungGraph, new Transformer<JungEdge<Point>, Double>() {
public Double transform(JungEdge<Point> input) {
return input.getCost();
}
}, true);
List<JungEdge<Point>> path = dijkstra.getPath(maze.getInitialLoc(),
maze.getGoalLoc());
List<JungEdge<Point>> path = dijkstra.getPath(initial,goal);
Double cost = 0.0;
List<Point> statePath = new ArrayList<Point>();
if(path.isEmpty()){
Expand All @@ -264,7 +263,7 @@ public Double transform(JungEdge<Point> input) {
statePath.add(current.getSource());
cost += current.getCost();
}
statePath.add(maze.getGoalLoc());
statePath.add(goal);
return new Result(statePath, cost);
}

Expand Down
Loading

0 comments on commit 898e3ce

Please sign in to comment.