views:

71

answers:

1

I'm currently building a library to allow a wide variety of different minority games to be simulated. This involves agents choosing between two choices, say, A and B so the primary functionality of an agent is to choose. An agent wins a point for a turn in the game if it ends up in the minority group after all agents have chosen.

There is obviously an infinite number of different ways that an agent can make their choice and the game investigates the effect of different choice making tactics on the overall wealth of the system. Some ways in which I need agents to be able to choose are:

  • completely at random
  • by being supplied with a memory so that they can remember the past m minority choices with this memory being used as input into a strategy mapping to a prediction for the minority choice
  • by making a prediction and publicising it to a number of other agents who are that agent's 'friends' and then each agents chooses based on some condition about whether or not it trusts its friends.

Now for the programming problem. I currently have an AbstractAgent that encapsulates all this functionality. The thing is some types of agents wont have a list of friends, a set of strategies or a memory etc. At the moment all these abilities are clogging up the base class. I could use an inheritance hierarchy but I think there will be crossover between different classes in the hierarchy i.e., sometimes an agent may have friends and strategies, other times just friends or strategies. Similarly, I could have a collection of interfaces and each different agent implements whatever interfaces it needs, i.e.,

public enum Choice {
    A, B
}

public interface Decidable {
    private Choice choice;
    public Choice getChoice();
    public void choose();
}

public interface Strategic {
    private StrategyManager strategies;
    public StrategyManager getStrategyManager;
    public void setStrategyManager(StrategyManager strategyManager);
}

public class CleverAgent implements Decidable, Strategic {
    // decides more intelligently using the strategies
}

public class StupidAgent implements Decidable{
    public void choose() {
        if(Math.random < 0.5) {
            return Choice.A
        } else {
            return Choice.B
        }
    }
}

Now if I take this route, I can already see numerous interfaces such as Strategic, Decidable, Scorable, Stateful, Memorable and Befriendable. I feel like the actual solution should be a mix between an inheritance hierarchy (I know at least that all agents are Decidable so that should go in a base class) couple with pluggable behaviour.

My question is what is the best approach in this case? Are there any design patterns that I should look into? What are the advantages and disadvantages of each approach especially in terms of how it affects other code in the library as agent state needs to be investigated throughout the game for experimentation purposes?

Any help would be greatly appreciated.

+1  A: 
sateesh
Yes I think the strategy pattern would work but the other code that collects results about the state of the game needs to probe the agent for things like its network of friends (which can change through the course of the game) or its strategies so I need a type that exposes these attributes for the data collectors to use.
tobyclemson
What triggers the data collection from agents ? For the data collection part I think Observer pattern could be helpful. The agent can maintain a list of listeners and notify them when there is a change in its state.
sateesh
Yeah I'm using the Observer pattern for data collection. A MinorityGame has many Agents through an AgentManager and each DataCollector (or a subclass thereof) is notified at the end of each step in the game, and is supplied with the minority game which it can probe to collect the data it needs. This requires the agent to expose things like its network of friends (if it has one) so that a NetworkDataCollector for instance can store the friend network at each step of the game. As I said above, this requires the agent to have a network attribute if it uses that in its choice making.
tobyclemson
Upvoting for a nice discussion and detailed answer but unfortunately my question remains unanswered.This just moves the problem out of the agent class - not all agents need the strategic behaviour, for instance the random choice agent doesn't need any strategies whatsoever.Here, I would have interfaces and a class hierarchy but I'd still end up with redundant fields in the base class for some agents.
tobyclemson