@@ -402,9 +402,49 @@ def and_search(states, problem, path):
402402 return or_search (problem .initial , problem , [])
403403
404404
405- def online_dfs_agent (s1 ):
406- "[Fig. 4.21]"
407- unimplemented ()
405+ class OnlineDFSAgent :
406+
407+ """The abstract class for an OnlineDFSAgent. Override update_state
408+ method to convert percept to state. While initilizing the subclass
409+ a problem needs to be provided which is an instance of a subclass
410+ of the Problem Class. [Fig. 4.21] """
411+
412+ def __init__ (self , problem ):
413+ self .problem = problem
414+ self .s = None
415+ self .a = None
416+ self .untried = defaultdict (list )
417+ self .unbacktracked = defaultdict (list )
418+ self .result = {}
419+
420+ def update_state (self , percept ):
421+ raise NotImplementedError
422+
423+ def run (self , percept ):
424+ current_state = self .update_state (percept )
425+ if self .problem .goal_test (current_state ):
426+ self .a = None
427+ else :
428+ if current_state not in self .untried .keys ():
429+ self .untried [current_state ] = self .problem .actions (current_state )
430+ if self .s is not None :
431+ if current_state != self .result [(self .s , self .a )]:
432+ self .result [(self .s , self .a )] = current_state
433+ unbacktracked [current_state ].insert (0 , self .s )
434+ if len (self .untried [current_state ]) == 0 :
435+ if len (self .unbacktracked [current_state ]) == 0 :
436+ self .a = None
437+ else :
438+ # else a <- an action b such that result[s', b] = POP(unbacktracked[s'])
439+ unbacktracked_pop = self .unbacktracked [current_state ].pop (0 )
440+ for (s ,b ) in self .result .keys ():
441+ if self .result [(s ,b )] == unbacktracked_pop :
442+ self .a = b
443+ break
444+ else :
445+ self .a = self .untried [current_state ].pop (0 )
446+ self .s = current_state
447+ return self .a
408448
409449
410450def lrta_star_agent (s1 ):
0 commit comments