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;
|
package zutil.algo.path;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
|
||||||
public interface PathNode {
|
public interface PathNode {
|
||||||
|
|
||||||
public void setVisited(boolean b);
|
/**
|
||||||
|
* @return an Iterator with all its neighbors
|
||||||
public boolean visited();
|
*/
|
||||||
|
|
||||||
public Iterable<PathNode> getNeighbors();
|
public Iterable<PathNode> getNeighbors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param neighbor is the neighbor
|
||||||
|
* @return the cost to the neighbor
|
||||||
|
*/
|
||||||
public int getNeighborCost(PathNode 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 pivot = right/2;
|
||||||
int newPivot = partition(list, left, right, pivot);
|
int newPivot = partition(list, left, right, pivot);
|
||||||
if(k == newPivot)
|
if(k == newPivot)
|
||||||
return list.getIndex(k);
|
return list.get(k);
|
||||||
else if(k < newPivot)
|
else if(k < newPivot)
|
||||||
return find(list, k, left, newPivot-1);
|
return find(list, k, left, newPivot-1);
|
||||||
else
|
else
|
||||||
|
|
@ -53,7 +53,7 @@ public class QuickSelect {
|
||||||
return storeIndex
|
return storeIndex
|
||||||
*/
|
*/
|
||||||
private static int partition(SortableDataList list, int left, int right, int pivot){
|
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);
|
list.swap(pivot, right);
|
||||||
int storeIndex = left;
|
int storeIndex = left;
|
||||||
for(int i=left; i<right ;i++){
|
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);
|
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 ];
|
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