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>();
}
}

View file

@ -33,7 +33,7 @@ public class QuickSelect {
int pivot = right/2;
int newPivot = partition(list, left, right, pivot);
if(k == newPivot)
return list.getIndex(k);
return list.get(k);
else if(k < newPivot)
return find(list, k, left, newPivot-1);
else
@ -53,7 +53,7 @@ public class QuickSelect {
return storeIndex
*/
private static int partition(SortableDataList list, int left, int right, int pivot){
Object pivotValue = list.getIndex(pivot);
Object pivotValue = list.get(pivot);
list.swap(pivot, right);
int storeIndex = left;
for(int i=left; i<right ;i++){

View file

@ -138,7 +138,7 @@ public class MedianFilter extends ImageFilterProcessor{
return ((Integer)data[ getY(a) ][ getX(a) ][ channel ]).compareTo(b);
}
public Integer getIndex(int i) {
public Integer get(int i) {
return data[ getY(i) ][ getX(i) ][ channel ];
}

View file

@ -1,63 +0,0 @@
package zutil.test;
import zutil.algo.sort.QuickSort;
import zutil.algo.sort.sortable.SortableIntArray;
import junit.framework.*;
public class QuickSortTestSimple extends TestCase {
public static void main(String[] args){
int[] array = new int[1000];
for(int i=0; i<array.length ;i++){
array[i] = (int)(Math.random()*10000);
}
for(int i=0; i<array.length ;i++){
System.out.println(array[i]);
}
//quicksort(array, 0, array.length-1);
QuickSort.sort(new SortableIntArray(array));
System.out.println("----------------------------------");
for(int i=0; i<array.length ;i++){
System.out.println(array[i]);
}
System.out.println("----------------------------------");
for(int i=1; i<array.length ; i++){
if(array[i-1] > array[i]){
System.out.println("Array not sorted!! ("+array[i-1]+" > "+array[i]+")");
}
}
}
static void quicksort (int[] a, int lo, int hi) {
// lo is the lower index, hi is the upper index
// of the region of array a that is to be sorted
int i=lo, j=hi, h;
int x=a[(lo+hi)/2];
// partition
do
{
while (a[i]<x){
i++;
}
while (a[j]>x){
j--;
}
if (i<=j)
{
h=a[i]; a[i]=a[j]; a[j]=h;
i++; j--;
}
} while (i<=j);
// recursion
if (lo<j) quicksort(a, lo, j);
if (i<hi) quicksort(a, i, hi);
}
}

View file

@ -0,0 +1,44 @@
package zutil.test;
import zutil.algo.sort.QuickSort;
import zutil.algo.sort.SimpleSort;
import zutil.algo.sort.sortable.SortableIntArray;
import junit.framework.*;
public class SortTestSimple extends TestCase {
public static final int SIZE = 10000;
public static final int MAX_INT = 10000;
public static void main(String[] args){
int[] array = new int[SIZE];
for(int i=0; i<array.length ;i++){
array[i] = (int)(Math.random()*MAX_INT);
}
for(int i=0; i<array.length ;i++){
System.out.print(array[i]+", ");
}
long time = System.currentTimeMillis();
//SimpleSort.bubbleSort(new SortableIntArray(array));
//SimpleSort.selectionSort(new SortableIntArray(array));
SimpleSort.insertionSort(new SortableIntArray(array));
//QuickSort.sort(new SortableIntArray(array));
time = System.currentTimeMillis() - time;
System.out.println("\n--------------------------------------------");
System.out.print(array[0]+", ");
int error = -1;
for(int i=1; i<array.length ;i++){
System.out.print(array[i]+", ");
if(array[i-1] > array[i]){
error = i;
}
}
if(error >= 0){
System.out.println("\nArray not sorted!! ("+array[error-1]+" > "+array[error]+")");
}
System.out.println("\nTime: "+time+" ms");
}
}