Chapter 2
Intelligent Agents  

powered by FreeFind

Modified: 

Outline

Definitions

2.1 AGENTS AND ENVIRONMENTS

Vacuum-cleaner world

Percept Sequence        Action   
   [A, Clean]
   [A, Dirty]
   [B, Clean]
   [B, Dirty]
   [A, Clean], [A, Clean]   
   [A, Clean], [A, Dirty]
    :
   [A, Clean], [A, Clean], [A, Clean]    
   [A, Clean], [A, Clean], [A, Dirty]   
    :
        Right
        Suck
        Left
        Suck
        Right
        Suck
        :
        Right
        Suck
        :

 

Agent definition
  • Complete agent definition by filling in all possible percept sequences and corresponding actions.
  • Can the table be completed? How many table entries are needed for percept sequences of length 2? of length 3? of length n?
  • Can you give examples of table entries that make the agent good? or bad? smart or dumb?

2.2 GOOD BEHAVIOR: THE CONCEPT OF RATIONALITY

Vacuum agent
  • Performance measure might maximize cleaning and minimize travel.
  • By the above measure, does the table define a rational agent?
  • Give an example where changing the table defines a less rational agent.

2.3 THE NATURE OF ENVIRONMENTS

Specifying the task environment - PEAS

To design a rational agent must specify task environment

Design of an automated taxi

Design of an Internet shopping agent
  • Performance measure?
  • Environment?
  • Actuators?
  • Sensors?

Environment types

Real world is partially observable, stochastic, sequential, dynamic, continuous and multi-agent 

  Solitaire Internet shopping Taxi
Observerable? Yes No No
Deterministic?      
Episodic?      
Static?      
Discrete      
Single agent      

2.4 THE STRUCTURE OF AGENTS

Four basic types in order of increasing generality:

All above can also be learning agents that analyze experience to select action.

TABLE-DRIVEN-AGENT (Figure 2.7)

function TABLE-DRIVEN-AGENT( percept ) returns  an action
   static: percepts, a sequence, initially empty
            table, a table of actions, indexed by percept sequences, initially fully specified
  
   append percept to the end of percepts
   action = LOOKUP( percepts, table)
    return action
def TABLE_DRIVEN_AGENT(percept): # Determine action based on table and percepts
    percepts.append(percept)              # Append percept 
    action = LOOKUP(percepts, table)  # Lookup appropriate action for percepts
    return action

 

#   Figure 2.7 page 45

A='A'
B='B'
percepts = []        
table = {((A, 'Clean'),): 'Right',    # [Fig. 2.3]
             ((A, 'Dirty'),): 'Suck',
             ((B, 'Clean'),): 'Left',
             ((B, 'Dirty'),): 'Suck',
             ((A, 'Clean'), (A, 'Clean')): 'Right',
             ((A, 'Clean'), (A, 'Dirty')): 'Suck',
             # ...
             ((A, 'Clean'), (A, 'Clean'), (A, 'Clean')): 'Right',
             ((A, 'Clean'), (A, 'Clean'), (A, 'Dirty')): 'Suck',
             # ...
          }
def LOOKUP(percepts, table):            # Lookup appropriate action for percepts
    action = table.get(tuple(percepts))
    return action 
def TABLE_DRIVEN_AGENT(percept): # Determine action based on table and percepts
    percepts.append(percept)              # Add percept 
    action = LOOKUP(percepts, table)  # Lookup appropriate action for percepts
    return action
def run() :                                        # run agent on several sequential percepts
    print 'Action\tPercepts'
    print TABLE_DRIVEN_AGENT((A, 'Clean')),'\t', percepts
    print TABLE_DRIVEN_AGENT((A, 'Dirty')),'\t', percepts
    print TABLE_DRIVEN_AGENT((B, 'Clean')),'\t', percepts

 

Try
  1. Copy and paste the above program into Python editor.
  2. Save as f2-7.py
  3. Run the module:
    • Press F5
    • Enter: run()
    •  
  4. The percepts should now be: [('A', 'Clean'), ('A', 'Dirty'), ('B', 'Clean')].
    • The table contains all possible percept sequences to match with the percept history.
    • Enter:
      • print TABLE_DRIVEN_AGENT((B, 'Clean'))
      • percepts
    • Explain the results.
  5. How many table entries would be required if only the current percept was used to select an action rather than the percept history?
  6. How many table entries are required for an agent lifetime of T steps?

REFLEX-VACUUM-AGENT (Figure 2.8)

function REFLEX-VACUUM-AGENT( [location, status] ) returns  an action
   if status = Dirty then return Suck
  
else if location = A then return Right
  
else if location = B then return Left
def REFLEX_VACUUM_AGENT((location, status)): # Determine action
    if status == 'Dirty': return 'Suck'
    elif location == A: return 'Right'
    elif location == B: return 'Left'

 

# Figure 2.8 page 46

A='A'
B='B'
Environment = { A:'Dirty', B:'Dirty', 'Current': A }

def REFLEX_VACUUM_AGENT((location, status)):    # Determine action
    if status == 'Dirty': return 'Suck'
    if location == A: return 'Right'
    if location == B: return 'Left'

def Sensors() :                                                   # Sense Environment
    location = Environment['Current']
    return (location, Environment[location])

def Actuators(action) : # Modify Environment
    location = Environment['Current']
    if action == 'Suck' : Environment[location] = 'Clean'
    elif action == 'Right' and location == A : Environment['Current'] = B
    elif action == 'Left' and location == B : Environment['Current'] = A

def run(n):                                                         # run the agent through n steps
    print '\tCurrent\t\t\t\tNew'
    print 'location\tstatus\taction\tlocation\tstatus'
    for i in range(1,n):
        (location, status) = Sensors()                       # Sense Environment before action
        print location + '\t\t'+ status + '\t' ,
        action = REFLEX_VACUUM_AGENT(Sensors())
        Actuators(action)
        (location, status) = Sensors() # Sense Environment after action
        print action + '\t' + location + '\t\t'+ status
 

 

Try
  1. Copy and paste the above program into Python editor.
  2. Save as f2-8.py
  3. Run the module:
    • Press F5
    • Enter: run(10)

     

  4. Should bogus actions be able to corrupt the environment?
  5. Change the REFLEX_VACUUM_AGENT to return bogus actions, such as Left when should go Right, etc. Run the agent. Do the Actuators allow bogus actions?

 

Simple reflex agents
 

 

SIMPLE-REFLEX-AGENT (Figure 2.9)

function SIMPLE-REFLEX-AGENT( percept ) returns  an action
   static: rules, a sequence, a set of condition-action rules
  
   state = INTERPRET-INPUT( percept )
   rule
 = RULE-MATCH( state, rules )
   action =
RULE-ACTION[ rule ]
    return action
def SIMPLE_REFLEX_AGENT(percept):                  # Determine action
    state = INTERPRET_INPUT(percept)
    rule = RULE_MATCH(state, rules)
    action = RULE_ACTION[rule]
    return action

Condition-action

Defines action for each rule, such as: rule 1 produces action 'Suck'

# Figure 2.9 page 47

A='A'
B='B'

RULE_ACTION = { 1:'Suck', 2:'Right', 3:'Left', 4:'NoOp' }

rules = { (A,'Dirty'):1, (B,'Dirty'):1, (A,'Clean'):2, (B,'Clean'):3, (A, B, 'Clean'):4 }
#     Ex. rule (if location == A && Dirty then rule 1)

def INTERPRET_INPUT(input) :                           # No interpretation
    return input

def RULE_MATCH(state, rules) :                         # Match rule for a given state
    rule = rules.get(tuple(state))
    return rule

def SIMPLE_REFLEX_AGENT(percept):                  # Determine action
    state = INTERPRET_INPUT(percept)
    rule = RULE_MATCH(state, rules)
    action = RULE_ACTION[ rule ]
    return action

# ----------------------------- Same below this line --------------------------------

Environment = { A:'Dirty', B:'Dirty', 'Current': A }

def Sensors() :                                                  # Sense Environment
    location = Environment['Current']
    return (location, Environment[location])

def Actuators(action) :                                       # Modify Environment
    location = Environment['Current']
    if action == 'Suck' : Environment[location] = 'Clean'
    elif action == 'Right' and location == A : Environment['Current'] = B
    elif action == 'Left' and location == B : Environment['Current'] = A

def run(n):                                                         # run the agent through n steps
    print '\tCurrent\t\t\t\tNew'
    print 'location\tstatus\taction\tlocation\tstatus'
    for i in range(1,n):
        (location, status) = Sensors()                       # Sense Environment before action
        print location + '\t\t'+ status + '\t' ,
        action = SIMPLE_REFLEX_AGENT(Sensors())
        Actuators(action)
        (location, status) = Sensors() # Sense Environment after action
        print action + '\t' + location + '\t\t'+ status
 

 

Try
  1. Copy and paste the above program into Python editor.
  2. Save as f2-9.py
  3. Run the module:
    • Press F5
    • Enter: run(10)

     

  4. Change the SIMPLE_REFLEX_AGENT condition-action rules to return bogus actions, such as Left when should go Right, or Crash, etc. Rerun the agent. Do the Actuators allow bogus actions?

 

REFLEX-AGENT-WITH-STATE (Figure 2.11)

Reflex agent only responded to current percepts, no history or knowledge.

Model-based reflex agents

 

function REFLEX-AGENT-WITH-STATE( percept ) returns  an action
   static: state, a description of the current world state
             rules, a sequence, a set of condition-action rules
             action, the most recent action, initially none
  
   state = UPDATE-STATE( state, action, percept )
   rule
 = RULE-MATCH( state, rules )
   action =
RULE-ACTION[ rule ]
   return action
def REFLEX_AGENT_WITH_STATE(percept):
    global state, action

    state = UPDATE_STATE(state, action, percept)
    rule = RULE_MATCH(state, rules)
    action = RULE_ACTION[ rule ]
    return action

Model - Used to update history.

model = {A: None, B: None}

    if model[A] == model[B] == 'Clean' : state = (A, B, 'Clean')      

# Figure 2.11 page 49

A='A'
B='B'

state = {}
action = None
model = {A: None, B: None}     # Initially ignorant

def UPDATE_STATE(state, action, percept) :
    (location, status) = percept
    state = percept                   
    if model[A] == model[B] == 'Clean' :
        state = (A, B, 'Clean')       # Model consulted only for A and B Clean
    model[location] = status       # Update the model state
    return state

def REFLEX_AGENT_WITH_STATE(percept):
    global state, action

    state = UPDATE_STATE(state, action, percept)
    rule = RULE_MATCH(state, rules)
    action = RULE_ACTION[rule]
    return action

# ----------------------------- Same below this line --------------------------------

Environment = { A:'Dirty', B:'Dirty', 'Current': A }
RULE_ACTION = { 1:'Suck', 2:'Right', 3:'Left', 4:'NoOp' }
rules = { (A,'Dirty'):1, (B,'Dirty'):1, (A,'Clean'):2, (B,'Clean'):3, (A, B, 'Clean'):4 }

def RULE_MATCH(state, rules) :                         # Match rule for a given state
    rule = rules.get(tuple(state))
    return rule

def Sensors() :                                                  # Sense Environment
    location = Environment['Current']
    return (location, Environment[location])

def Actuators(action) :                                        # Modify Environment
    location = Environment['Current']
    if action == 'Suck' : Environment[location] = 'Clean'
    elif action == 'Right' and location == A : Environment['Current'] = B
    elif action == 'Left' and location == B : Environment['Current'] = A

def run(n):                                                         # run the agent through n steps
    print '\tCurrent\t\t\t\tNew'
    print 'location\tstatus\taction\tlocation\tstatus'
    for i in range(1,n):
        (location, status) = Sensors()                       # Sense Environment before action
        print location + '\t\t'+ status + '\t' ,
        action = REFLEX_AGENT_WITH_STATE(Sensors())
        Actuators(action)
        (location, status) = Sensors() # Sense Environment after action
        print action + '\t' + location + '\t\t'+ status
 

 

Consider
  1. What changes are necessary to add a C square?

 

Goal-based agents
MODEL-BASED, GOAL-BASED AGENT Figure 2.13

 

Utility-based agents
MODEL-BASED, UTILITY-BASED AGENT Figure 2.14

 

LEARNING AGENT  Figure 2.15