Fixed the path finding algos a bit
This commit is contained in:
parent
0f85e1b4dd
commit
c161e4bdd8
11 changed files with 240 additions and 205 deletions
47
src/zutil/algo/path/BreadthFirstSearch.java
Normal file
47
src/zutil/algo/path/BreadthFirstSearch.java
Normal 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>();
|
||||
}
|
||||
}
|
||||
51
src/zutil/algo/path/DepthFirstSearch.java
Normal file
51
src/zutil/algo/path/DepthFirstSearch.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
21
src/zutil/algo/path/PathFinder.java
Normal file
21
src/zutil/algo/path/PathFinder.java
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
49
src/zutil/algo/path/StandardPathNode.java
Normal file
49
src/zutil/algo/path/StandardPathNode.java
Normal 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>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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++){
|
||||
|
|
|
|||
|
|
@ -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 ];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
44
src/zutil/test/SortTestSimple.java
Normal file
44
src/zutil/test/SortTestSimple.java
Normal 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");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue