|
From: Nick C. <nic...@ve...> - 2003-02-25 13:50:34
|
I think Andy's point is an excellent one here. In the non-toy simulations I have written an agent's access to its "raw topology" is almost always mediated by some "referee." Sometimes this is a one shot class with no design for extensibility. In other cases, I use a "referee" interface, and the actual "referee" is produced via a factory class. The specific type of the "referee" is usually dependent on some parameter in the model. The referee might have a method getNeighbor() and specific implementations might return a random neighbor, a "max" neighbor, the "most alike" neighbor or whatever. The point being that the referee in these cases uses the raw topology but filters it in someway. I've cc'd this to repast-interest as I think others would be interested in this discussion. Please keep the thread going there. Nick On Mon, 2003-02-24 at 21:16, Andy Cleary wrote: > At 05:50 PM 2/24/2003 -0800, you wrote: > > >On the subject of "ABM design patterns", this matches one that I have > >internally been calling the "Referee" design pattern. The idea in this > >pattern is to separate the decision of what agents want to do from the > >determination of what actually happens. The "Referee" is an object that > >sits between the agents and other agents and the environment that > >determines resolution of conflicts if you will. Here, the Landscape seems > >to play this role almost exactly, and Mark's reasons for the Landscape > >match my own thinking pretty much exactly (I'll leave it to Mark to decide > >if resembling my thinking is a good thing or not... ;-) > > > >A canonical example to me is conservation: if agent A and agent B > >simultaneously do something that would result in an exchange of something > >between them and that exchange must not violate conservation (e.g. one > >gets 20 bucks but the other gives 10 is a bad thing), a referee may be a > >nice way to ensure (insure?) conservation. Instead of either A or B > >determining unilaterally what they think happens in the transfer, they > >"submit their case" to the referee, who then informs them of the results, > >thus guaranteeing that they both "see" the same amount being transferred. > > > >As Mark says, the pattern works well to separate the decision making of > >agents from the "resolution" of the physics or other rules of interaction > >that the simulation is interested in. I submit that this is one step > >towards making agents more interchangeable from simulation to simulation > >(IOW, making it more likely that agents created by one team may be plugged > >into a simulation created by another): the agents just make decisions, but > >the choice of what those decisions actually *do* is encapsulated in the > >referee. Within broad limits, agents may be able to function reasonably > >well in a variety of different but somewhat related simulations. > > Oh, I forgot something along the lines of making agents that can be dropped > into different simulations... Since there has been discussion of the spaces > and in particular generalizing things like "getNeighbors", I thought I'd > mention that the Referee pattern is another way to approach this. Instead > of having the space itself expose common functionality like GetNeighbor, > this could actually be exposed in the Referee. Instead of the agents > directly querying the space, it could be argued that essentially they are > trying to "see" what is around them; and that the result of that action > should be dictated by the Referee. In this pattern, the agents pretty much > interact directly only with the Referee. The Referee in turn has access to > the other agents, the environment, the space that the agents are > interacting with, etc. The Referee could then expose a GetNeighbors > function and then choose to implement it as dictated by the conditions of > the simulation. The implementation of the Agents doesn't change. Now, > there's a sense in which this just pushes the logic for dealing with > different underlying spaces from one point in the code to another, but, at > least it is in *one* point, the implementation of the Referee, instead of > in N points, each of the agents (which, again, ideally could be mixed and > matched from different developers, hence more code to change). > > Perhaps more thought provoking, thinking about "GetNeighbors" more as some > sort of "see" function creates scenarios that lend themselves more to the > Referee concept. What if there is a "wall" in between you and one of your > neighbors? Your simulation might not want you to "see" that neighbor. One > way to implement this is to extend the particular space you are working > with to include the logic of "walls", but there are a lot of reasons to > prefer composition to extension here. I prefer to have the Referee "have a" > space as they are currently implemented, and then encode extra logic > internally to track these "walls". Again, the Agent implementation doesn't > change: it gets some representation of what it "sees" (e.g. a list of other > agents), and if one of its physical neighbors isn't included because the > Referee determines they don't see it, so be it. Where composition really > shines vs extension is in more dynamic situations: say, for example, that > the presence of one agent may "block" sight of other agents. Here, the > GetNeighbors function in the referee has to encode logic looking at the > location of other agents to even compute what the agent sees. To try to get > this effect by extension of the spaces is to start having the spaces > themselves encode knowledge of simulation specifics like the kinds of > agents, etc., which seems fairly obviously to be the wrong path. > > In general, the Referee is a useful pattern in cases where what an agent > *intends* to do does not always happen, or in which the agent cannot > unilaterally decide what happens to it because it requires calculations > involving interaction with other agents or the environment. Underlying > something like "GetMooreNeighborhood" is the assumption that if an agent > *wants* to get its neighborhood, it necessarily *can*. Obviously, for many > applications, this is fine. But the interesting thing about the Referee is > that it doesn't preclude this: one could always have a "no-op" referee in > essence, one that allows agents to dictate what they want to do. But by > using the pattern, if something comes up where you go "shoot, I don't > really want the agents to be able to do that", having the the Referee in > place is convenient. Again, if the same development team is writing the > simulation *and* the agents, this probably doesn't come up very much. But > when you start trying to decouple their implementation to some extent, it > becomes more attractive. The Referee can make sure the entities follow the > "rules" for this simulation, just in case they were written in a way that > might otherwise violate the rules. > > Cheers, > Andy > > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Repast-developer mailing list > Rep...@li... > https://lists.sourceforge.net/lists/listinfo/repast-developer -- Nick Collier Social Science Research Computing University of Chicago http://repast.sourceforge.net |