001 package aima.search.framework; 002 003 import java.util.List; 004 005 import aima.util.AbstractQueue; 006 007 /** 008 * @author Ravi Mohan 009 * 010 */ 011 012 /** 013 * Artificial Intelligence A Modern Approach (2nd Edition): page 69. 014 * 015 * There are many ways to represent nodes, but we will assume that a node is a 016 * data structure with five components: 017 * 018 * STATE: the state in the state space to which the node corresponds; 019 * PARENT-NODE: the node in the search tree that generated this node; ACTION: 020 * the action that was applied to the parent to generate the node; PATH-COST: 021 * the cost, traditionally denoted by g(n), of the path from the initial state 022 * to the node, as indicated by the parent pointers; and DEPTH: the number of 023 * steps along the path from the initial state. 024 */ 025 026 public class Node { 027 028 // STATE: the state in the state space to which the node corresponds; 029 private Object state; 030 031 // PARENT-NODE: the node in the search tree that generated this node; 032 private Node parent; 033 034 // ACTION: the action that was applied to the parent to generate the node; 035 private String action; 036 037 // PATH-COST: the cost, traditionally denoted by g(n), of the path from the 038 // initial state to 039 // the node, as indicated by the parent pointers; 040 Double pathCost; 041 042 // DEPTH: the number of steps along the path from the initial state. 043 private int depth; 044 045 private Double stepCost; 046 047 public Node(Object state) { 048 this.state = state; 049 this.depth = 0; 050 this.stepCost = new Double(0); 051 this.pathCost = new Double(0); 052 } 053 054 public Node(Node parent, Object state) { 055 this(state); 056 this.parent = parent; 057 this.depth = parent.getDepth() + 1; 058 } 059 060 public int getDepth() { 061 return depth; 062 } 063 064 public boolean isRootNode() { 065 return parent == null; 066 } 067 068 public Node getParent() { 069 return parent; 070 } 071 072 public List<Node> getPathFromRoot() { 073 Node current = this; 074 AbstractQueue queue = new AbstractQueue(); 075 while (!(current.isRootNode())) { 076 queue.addToFront(current); 077 current = current.getParent(); 078 } 079 queue.addToFront(current); // take care of root node 080 return queue.asList(); 081 } 082 083 public Object getState() { 084 return state; 085 } 086 087 public void setAction(String action) { 088 this.action = action; 089 } 090 091 public String getAction() { 092 return action; 093 } 094 095 public void setStepCost(Double stepCost) { 096 this.stepCost = stepCost; 097 } 098 099 public void addToPathCost(Double stepCost) { 100 this.pathCost = new Double(parent.pathCost.doubleValue() 101 + stepCost.doubleValue()); 102 } 103 104 /** 105 * @return Returns the pathCost. 106 */ 107 public double getPathCost() { 108 return pathCost.doubleValue(); 109 } 110 111 /** 112 * @return Returns the stepCost. 113 */ 114 public double getStepCost() { 115 return stepCost.doubleValue(); 116 } 117 118 @Override 119 public String toString() { 120 return getState().toString(); 121 } 122 }