Fixed the path finding algos a bit

This commit is contained in:
Ziver Koc 2010-02-25 23:01:46 +00:00
parent 0f85e1b4dd
commit c161e4bdd8
11 changed files with 240 additions and 205 deletions

View file

@ -0,0 +1,47 @@
package zutil.algo.path;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
/**
* A class that uses BFS to find a path
*
* @author Ziver
*/
public class BreadthFirstSearch implements PathFinder{
/**
* Returns the first path to the destination
*
* @param start is the start Node
* @param stop is the goal Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
Queue<PathNode> queue = new LinkedList<PathNode>();
HashSet<PathNode> visited = new HashSet<PathNode>();
queue.add(start);
visited.add( start );
PathNode tmp;
while(!queue.isEmpty()){
tmp = queue.poll();
for(PathNode next : tmp.getNeighbors()){
if(!visited.contains( next ) && tmp.getNeighborCost(next) > 0){
queue.add(next);
visited.add( next );
next.setParentNeighbor(tmp);
if(next.equals(stop)){
return stop.traversTo(start);
}
}
}
}
return new LinkedList<PathNode>();
}
}

View file

@ -0,0 +1,51 @@
package zutil.algo.path;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
/**
* A PathFinder class implemented with DFS
*
* @author Ziver
*/
public class DepthFirstSearch {
private HashSet<PathNode> visited = new HashSet<PathNode>();
/**
* Returns the first path to the destination
*
* @param start Start Node
* @param stop Stop Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
visited.clear();
PathNode node = dfs(start, stop);
return node.traversTo( start );
}
/**
* The DepthFirstSearch algorithm
* @param node The node to search from
* @return The stop PathNode if a path was found else null
*/
private PathNode dfs(PathNode node, PathNode stop){
visited.add( node );
if(node.equals(stop)){
return node;
}
for(PathNode next : node.getNeighbors()){
if(!visited.contains( next ) && node.getNeighborCost(next) > 0){
next.setParentNeighbor(node);
PathNode tmp = dfs(next, stop);
if(tmp != null){
return tmp;
}
}
}
return null;
}
}

View file

@ -0,0 +1,21 @@
package zutil.algo.path;
import java.util.LinkedList;
/**
* All path finding algorithms should implement this interface
*
* @author Ziver
*/
public interface PathFinder {
/**
* Starts the search for the path from the start
* node to the goal.
*
* @param start is the starting point of the search
* @param goal is the search goal
* @return a LinkedList of the path, empty list if no path was found
*/
public LinkedList<PathNode> find(PathNode start, PathNode goal);
}

View file

@ -1,17 +1,36 @@
package zutil.algo.path;
import java.util.LinkedList;
public interface PathNode {
public void setVisited(boolean b);
public boolean visited();
/**
* @return an Iterator with all its neighbors
*/
public Iterable<PathNode> getNeighbors();
/**
* @param neighbor is the neighbor
* @return the cost to the neighbor
*/
public int getNeighborCost(PathNode neighbor);
public void setSourceNeighbor(PathNode neighbor);
/**
* Sets the parent node to this one
*/
public void setParentNeighbor(PathNode parent);
public PathNode getSourceNeighbor();
/**
* @return the parent node
*/
public PathNode getParentNeighbor();
/**
* Traverses the parent tree and returns the path.
*
* @param goal is the node to reach
* @return the path to the goal, empty list if there is no goal
*/
public LinkedList<PathNode> traversTo(PathNode goal);
}

View file

@ -1,38 +0,0 @@
package zutil.algo.path;
import java.util.HashMap;
public class PathNodeDefault implements PathNode{
private HashMap<PathNode,Integer> neighbors;
private PathNode neighbor;
private boolean visited;
public PathNodeDefault(){
neighbors = new HashMap<PathNode,Integer>();
visited = false;
}
public void setVisited(boolean b){
visited = b;
}
public int getNeighborCost(PathNode neighbor) {
return neighbors.get(neighbor);
}
public Iterable<PathNode> getNeighbors() {
return neighbors.keySet();
}
public boolean visited() {
return visited;
}
public void setSourceNeighbor(PathNode n) {
neighbor = n;
}
public PathNode getSourceNeighbor() {
return neighbor;
}
}

View file

@ -1,95 +0,0 @@
package zutil.algo.path;
import java.util.LinkedList;
import java.util.Queue;
/**
* A class for simple path finding algorithms
*
* @author Ziver
*/
public class SimplePathFinder {
/**
* Returns the first path to the destination
*
* @param start Start Node
* @param stop Stop Node
* @return A list with the path
*/
public LinkedList<PathNode> BreadthFirstSearch(PathNode start, PathNode stop){
Queue<PathNode> queue = new LinkedList<PathNode>();
queue.add(start);
start.setVisited(true);
PathNode tmp;
while(!queue.isEmpty()){
tmp = queue.poll();
for(PathNode next : tmp.getNeighbors()){
if(!next.visited() && tmp.getNeighborCost(next) > 0){
queue.add(next);
next.setVisited(true);
next.setSourceNeighbor(tmp);
if(next.equals(stop)){
LinkedList<PathNode> path = new LinkedList<PathNode>();
for(PathNode current=stop; !current.equals(start) ;current = current.getSourceNeighbor()){
path.addFirst(current);
}
path.addFirst(start);
return path;
}
}
}
}
return new LinkedList<PathNode>();
}
/**
* Returns the first path to the destination
*
* @param start Start Node
* @param stop Stop Node
* @return A list with the path
*/
public LinkedList<PathNode> DepthFirstSearch(PathNode start, PathNode stop){
LinkedList<PathNode> path = new LinkedList<PathNode>();
PathNode current = DepthFirstSearchInternal(start, stop);
while(current != null){
path.addFirst(current);
current = current.getSourceNeighbor();
if(current.equals(start)){
path.addFirst(start);
break;
}
}
return path;
}
/**
* The DepthFirstSearch algorithm
* @param node The node to search from
* @return The stop PathNode if a path was found else null
*/
private PathNode DepthFirstSearchInternal(PathNode node, PathNode stop){
node.setVisited(true);
if(node.equals(stop)){
return node;
}
for(PathNode next : node.getNeighbors()){
if(!next.visited() && node.getNeighborCost(next) > 0){
next.setSourceNeighbor(node);
PathNode tmp = DepthFirstSearchInternal(next, stop);
if(tmp != null){
return tmp;
}
}
}
return null;
}
}

View file

@ -0,0 +1,49 @@
package zutil.algo.path;
import java.util.HashMap;
import java.util.LinkedList;
/**
* An standard implementation of PathNode
* @author Ziver
*
*/
public class StandardPathNode implements PathNode{
private HashMap<PathNode,Integer> neighbors;
private PathNode parent;
public StandardPathNode(){
neighbors = new HashMap<PathNode,Integer>();
}
public int getNeighborCost(PathNode neighbor) {
return neighbors.get(neighbor);
}
public Iterable<PathNode> getNeighbors() {
return neighbors.keySet();
}
public PathNode getParentNeighbor() {
return parent;
}
public void setParentNeighbor(PathNode parent) {
this.parent = parent;
}
public LinkedList<PathNode> traversTo(PathNode goal) {
LinkedList<PathNode> path = new LinkedList<PathNode>();
PathNode current = this;
while(current != null){
path.addFirst(current);
current = current.getParentNeighbor();
if(goal.equals( current )){
path.addFirst( goal );
return path;
}
}
return new LinkedList<PathNode>();
}
}