Skip to content

Commit

Permalink
Bellman-Ford implemented and test added. AStarNode classes changed to
Browse files Browse the repository at this point in the history
deprecated. Close #28
  • Loading branch information
Pablo Rodríguez Mier committed Apr 6, 2013
1 parent 4af1a17 commit 8a258be
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 22 deletions.
49 changes: 27 additions & 22 deletions src/main/java/es/usc/citius/lab/hipster/algorithm/BellmanFord.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

package es.usc.citius.lab.hipster.algorithm;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;

import es.usc.citius.lab.hipster.function.TransitionFunction;
import es.usc.citius.lab.hipster.node.AStarNode;
import es.usc.citius.lab.hipster.node.Node;
import es.usc.citius.lab.hipster.node.NodeBuilder;
import es.usc.citius.lab.hipster.node.Transition;
Expand All @@ -33,60 +34,64 @@
* the shortest path from a source node to all reachable nodes. This is
* the preferred algorithm when negative weights are allowed.
*
*
* @author Pablo Rodríguez Mier
*
* @param <S>
*/
public class BellmanFord<S> implements Iterator<Node<S>> {

private TransitionFunction<S> transition;
private NodeBuilder<S, Node<S>> builder;
private Queue<Node<S>> queue;
private Map<S, Node<S>> open;
private NodeBuilder<S, AStarNode<S>> builder;
private Queue<AStarNode<S>> queue;
private Map<S, AStarNode<S>> open;
private Comparator<AStarNode<S>> comparator;
private boolean improvement = true;

public BellmanFord(){
this.queue = new LinkedList<Node<S>>();
public BellmanFord(S initialState, TransitionFunction<S> transition, NodeBuilder<S, AStarNode<S>> builder, Comparator<Node<S>> comparator){
this.builder = builder;
this.transition = transition;
this.queue = new LinkedList<AStarNode<S>>();
this.open = new HashMap<S, AStarNode<S>>();
AStarNode<S> initialNode = builder.node(null, new Transition<S>(initialState));
this.queue.add(initialNode);
this.open.put(initialState, initialNode);
}

public boolean hasNext() {
return !this.queue.isEmpty() || !improvement;
}

public Node<S> next() {
improvement = false;
// Take the smallest node
Node<S> current = this.queue.poll();
AStarNode<S> current = this.queue.poll();
// Calculate distances to each neighbor
S currentState = current.transition().to();
for(Transition<S> successor : this.transition.from(currentState)){
// Create the successor node
Node<S> successorNode = this.builder.node(current, successor);
AStarNode<S> successorNode = this.builder.node(current, successor);
// Check if there is any improvement in the old cost
Node<S> previousNode = this.open.get(successor.to());
AStarNode<S> previousNode = this.open.get(successor.to());
if (previousNode != null){
// Check both paths. If the new path is better than the previous
// path, update and enqueue. Else, discard this node.
if (successorNode.compareTo(previousNode) <= 0){
// Update and enqueue again
improvement = true;
this.queue.add(successorNode);
//if (comparator.compare(successorNode, previousNode) <= 0){
if (successorNode.compareByCost(previousNode) < 0){
// Replace previousNode
this.open.put(successor.to(), successorNode);
}
improvement = true;
}
} else {
this.queue.add(successorNode);
this.open.put(successor.to(), successorNode);
improvement = true;
}


// After check all transitions, stop if there
// is no improvement of any cost
}
return current;
}

public void remove() {
// TODO Auto-generated method stub

throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* @since 26/03/2013
* @version 1.0
*/
@Deprecated
public class AStarDoubleNode<S> extends AbstractNode<S> implements AStarNode<S>{

protected final double cost; // In A*: g(n)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* @since 26/03/2013
* @version 1.0
*/
@Deprecated
public class AStarDoubleNodeBuilder<S> implements NodeBuilder<S, AStarNode<S>> {

private CostFunction<S, Double> cost;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* @since 26/03/2013
* @version 1.0
*/
@Deprecated
public interface AStarNode<S> extends Node<S>, Comparable<AStarNode<S>> {
public int compareByCost(AStarNode<S> node);
public int compareByScore(AStarNode<S> node);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2013 Centro de Investigación en Tecnoloxías da Información (CITIUS).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package es.usc.citius.lab.hipster.algorithm;

import es.usc.citius.lab.hipster.testutils.JungEdge;
import edu.uci.ics.jung.graph.DirectedGraph;
import es.usc.citius.lab.hipster.testutils.AlgorithmIteratorFromMazeCreator;
import es.usc.citius.lab.hipster.testutils.JungDirectedGraphFromMazeCreator;
import es.usc.citius.lab.hipster.testutils.MazeSearch;
import es.usc.citius.lab.hipster.util.maze.Maze2D;
import java.awt.Point;
import org.junit.Test;
import static org.junit.Assert.*;

/**
* Executes tests over predefined maze strings, comparing the results between
* Jung and AD* iterator.
*
* @author Adrián González Sieira <[email protected]>
* @author Pablo Rodríguez Mier <[email protected]>
* @since 26/03/2013
* @version 1.0
*/
public class BellmanFordTest {

public BellmanFordTest() {
}



@Test
public void BF_Maze1() throws InterruptedException {
Maze2D maze = new Maze2D(MazeSearch.getTestMaze1());
execute(maze, false);
}

@Test
public void BF_Maze2() throws InterruptedException {
Maze2D maze = new Maze2D(MazeSearch.getTestMaze2());
execute(maze, false);
}

@Test
public void BF_Maze3() throws InterruptedException {
Maze2D maze = new Maze2D(MazeSearch.getTestMaze3());
execute(maze, false);
}

@Test
public void BF_Maze4() throws InterruptedException {
Maze2D maze = new Maze2D(MazeSearch.getTestMaze4());
execute(maze, false);
}

@Test
public void BF_Maze5() throws InterruptedException {
Maze2D maze = new Maze2D(MazeSearch.getTestMaze5());
execute(maze, false);
}

private void execute(Maze2D maze, boolean heuristic) throws InterruptedException {
BellmanFord<Point> it = AlgorithmIteratorFromMazeCreator.bellmanFord(maze, heuristic);
DirectedGraph<Point, JungEdge> graph = JungDirectedGraphFromMazeCreator.create(maze);
MazeSearch.Result resultJung = MazeSearch.executeJungSearch(graph, maze);
MazeSearch.Result resultIterator = MazeSearch.executePrintIteratorSearch(it, maze);
assertEquals(resultIterator.getCost(), resultJung.getCost(), 0.001);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import es.usc.citius.lab.hipster.algorithm.ADStar;
import es.usc.citius.lab.hipster.algorithm.AStar;
import es.usc.citius.lab.hipster.algorithm.BellmanFord;
import es.usc.citius.lab.hipster.function.CostFunction;
import es.usc.citius.lab.hipster.function.HeuristicFunction;
import es.usc.citius.lab.hipster.function.TransitionFunction;
Expand Down Expand Up @@ -75,6 +76,18 @@ public static ADStar<Point> adstar(final Maze2D maze) {
defaultBuilder,
updater);
}

public static BellmanFord<Point> bellmanFord(final Maze2D maze, boolean useHeuristic) {
CostFunction<Point, Double> cost = defaultCostFunction();

TransitionFunction<Point> transition = defaultTransitionFunction(maze);

BellmanFord<Point> it;

it = new BellmanFord<Point>(maze.getInitialLoc(), transition, new AStarDoubleNodeBuilder<Point>(cost), null);

return it;
}

public static HeuristicFunction<Point, Double> defaultHeuristicFunction(final Maze2D maze) {
return new HeuristicFunction<Point, Double>() {
Expand Down

0 comments on commit 8a258be

Please sign in to comment.