diff --git a/src/zutil/algo/path/BreadthFirstSearch.java b/src/zutil/algo/path/BreadthFirstSearch.java new file mode 100644 index 0000000..cb5d4eb --- /dev/null +++ b/src/zutil/algo/path/BreadthFirstSearch.java @@ -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 find(PathNode start, PathNode stop){ + Queue queue = new LinkedList(); + HashSet visited = new HashSet(); + + 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(); + } +} diff --git a/src/zutil/algo/path/DepthFirstSearch.java b/src/zutil/algo/path/DepthFirstSearch.java new file mode 100644 index 0000000..4ffeaba --- /dev/null +++ b/src/zutil/algo/path/DepthFirstSearch.java @@ -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 visited = new HashSet(); + + /** + * Returns the first path to the destination + * + * @param start Start Node + * @param stop Stop Node + * @return A list with the path + */ + public LinkedList 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; + } + +} diff --git a/src/zutil/algo/path/PathFinder.java b/src/zutil/algo/path/PathFinder.java new file mode 100644 index 0000000..cb31787 --- /dev/null +++ b/src/zutil/algo/path/PathFinder.java @@ -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 find(PathNode start, PathNode goal); +} diff --git a/src/zutil/algo/path/PathNode.java b/src/zutil/algo/path/PathNode.java index 0ac6ad0..08d7317 100644 --- a/src/zutil/algo/path/PathNode.java +++ b/src/zutil/algo/path/PathNode.java @@ -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 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 traversTo(PathNode goal); } \ No newline at end of file diff --git a/src/zutil/algo/path/PathNodeDefault.java b/src/zutil/algo/path/PathNodeDefault.java deleted file mode 100644 index 0a88be3..0000000 --- a/src/zutil/algo/path/PathNodeDefault.java +++ /dev/null @@ -1,38 +0,0 @@ -package zutil.algo.path; - -import java.util.HashMap; - -public class PathNodeDefault implements PathNode{ - private HashMap neighbors; - private PathNode neighbor; - private boolean visited; - - public PathNodeDefault(){ - neighbors = new HashMap(); - visited = false; - } - - public void setVisited(boolean b){ - visited = b; - } - - public int getNeighborCost(PathNode neighbor) { - return neighbors.get(neighbor); - } - - public Iterable getNeighbors() { - return neighbors.keySet(); - } - - public boolean visited() { - return visited; - } - - public void setSourceNeighbor(PathNode n) { - neighbor = n; - } - - public PathNode getSourceNeighbor() { - return neighbor; - } -} diff --git a/src/zutil/algo/path/SimplePathFinder.java b/src/zutil/algo/path/SimplePathFinder.java deleted file mode 100644 index 592dade..0000000 --- a/src/zutil/algo/path/SimplePathFinder.java +++ /dev/null @@ -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 BreadthFirstSearch(PathNode start, PathNode stop){ - Queue queue = new LinkedList(); - - 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 path = new LinkedList(); - for(PathNode current=stop; !current.equals(start) ;current = current.getSourceNeighbor()){ - path.addFirst(current); - } - path.addFirst(start); - return path; - } - } - } - } - - return new LinkedList(); - } - - /** - * Returns the first path to the destination - * - * @param start Start Node - * @param stop Stop Node - * @return A list with the path - */ - public LinkedList DepthFirstSearch(PathNode start, PathNode stop){ - LinkedList path = new LinkedList(); - 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; - } - -} diff --git a/src/zutil/algo/path/StandardPathNode.java b/src/zutil/algo/path/StandardPathNode.java new file mode 100644 index 0000000..bc5b12b --- /dev/null +++ b/src/zutil/algo/path/StandardPathNode.java @@ -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 neighbors; + private PathNode parent; + + public StandardPathNode(){ + neighbors = new HashMap(); + } + + public int getNeighborCost(PathNode neighbor) { + return neighbors.get(neighbor); + } + + public Iterable getNeighbors() { + return neighbors.keySet(); + } + + public PathNode getParentNeighbor() { + return parent; + } + + public void setParentNeighbor(PathNode parent) { + this.parent = parent; + } + + public LinkedList traversTo(PathNode goal) { + LinkedList path = new LinkedList(); + PathNode current = this; + while(current != null){ + path.addFirst(current); + current = current.getParentNeighbor(); + if(goal.equals( current )){ + path.addFirst( goal ); + return path; + } + } + return new LinkedList(); + } + +} diff --git a/src/zutil/algo/search/QuickSelect.java b/src/zutil/algo/search/QuickSelect.java index 07c1d27..960611a 100644 --- a/src/zutil/algo/search/QuickSelect.java +++ b/src/zutil/algo/search/QuickSelect.java @@ -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 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){ - j--; - } - if (i<=j) - { - h=a[i]; a[i]=a[j]; a[j]=h; - i++; j--; - } - } while (i<=j); - - // recursion - if (lo array[i]){ + error = i; + } + } + + if(error >= 0){ + System.out.println("\nArray not sorted!! ("+array[error-1]+" > "+array[error]+")"); + } + System.out.println("\nTime: "+time+" ms"); + } +} \ No newline at end of file