001 /* 002 * Created on Sep 8, 2004 003 * 004 */ 005 package aima.search.uninformed; 006 007 import java.util.ArrayList; 008 import java.util.List; 009 010 import aima.search.framework.Metrics; 011 import aima.search.framework.NodeExpander; 012 import aima.search.framework.Problem; 013 import aima.search.framework.Search; 014 015 /** 016 * Artificial Intelligence A Modern Approach (2nd Edition): Figure 3.14, page 017 * 78. 018 * 019 * <code> 020 * function ITERATIVE-DEEPENING-SEARCH(problem) returns a solution, or failure 021 * inputs: problem, a problem 022 * 023 * for depth <- to infinity do 024 * result <- DEPTH-LIMITED-SEARCH(problem, depth) 025 * if result != cutoff then return result 026 * </code> 027 * Figure 3.14 The iterative deepening search algorithm, which repeatedly 028 * applies depth- limited search with increasing limits. It terminates when a 029 * solution is found or if the depth- limited search returns failure, meaning 030 * that no solution exists. 031 */ 032 033 /** 034 * @author Ravi Mohan 035 * 036 */ 037 public class IterativeDeepeningSearch extends NodeExpander implements Search { 038 private static String PATH_COST = "pathCost"; 039 040 private final int limit; 041 042 private final Metrics iterationMetrics; 043 044 public IterativeDeepeningSearch() { 045 this.limit = Integer.MAX_VALUE; 046 iterationMetrics = new Metrics(); 047 iterationMetrics.set(NODES_EXPANDED, 0); 048 iterationMetrics.set(PATH_COST, 0); 049 } 050 051 // function ITERATIVE-DEEPENING-SEARCH(problem) returns a solution, or 052 // failure 053 // inputs: problem, a problem 054 public List search(Problem p) throws Exception { 055 iterationMetrics.set(NODES_EXPANDED, 0); 056 iterationMetrics.set(PATH_COST, 0); 057 // for depth <- to infinity do 058 for (int i = 1; i <= limit; i++) { 059 // result <- DEPTH-LIMITED-SEARCH(problem, depth) 060 DepthLimitedSearch dls = new DepthLimitedSearch(i); 061 List result = dls.search(p); 062 iterationMetrics.set(NODES_EXPANDED, iterationMetrics 063 .getInt(NODES_EXPANDED) 064 + dls.getMetrics().getInt(NODES_EXPANDED)); 065 // if result != cutoff then return result 066 if (!cutOffResult(result)) { 067 iterationMetrics.set(PATH_COST, dls.getPathCost()); 068 return result; 069 } 070 } 071 return new ArrayList();// failure 072 } 073 074 private boolean cutOffResult(List result) { // TODO remove this duplication 075 076 return result.size() == 1 && result.get(0).equals("cutoff"); 077 } 078 079 @Override 080 public Metrics getMetrics() { 081 return iterationMetrics; 082 } 083 084 }