|
Species14
Species(Modeling Guide)
IntroductionThe agents' species are defined in the entities section. A model can contain any number of species. Species are used to specify the structure and behaviors of agents. Although the definitions below apply to all the species, some of them require specific declarations: the species of the world and the species of the environmental places. Species declarationThe simplest way to declare a species is the following: species a_name {
[variable declarations]
[action declarations]
[behaviors]
}for example: species foo{} //it is also possible to directly write: species foo;The agents that will belong to this species will only be provided with some built-in attributes and actions, a basic behavioral structure and nothing more. So, for instance, it is possible (somewhere else in the model) to write something like: let foo_agents type: list of: foo value:[];
create species: foo number: 10 return: foo_agents;
ask target:foo_agents {
do action: write {
arg message value: 'my name is: ' + name;
}
}Which will result in the 10 agents writing their name, in turn, on the console. If the species declare variables, the structure of the agents is modified consequently. For instance: species foo {
var energy type: float init: rnd (100) min: 0 max: 100 value: energy - 0.001;
}Will give each agent an amount of energy (between 0 and 100), which will decrease over time until it reaches 0. The species can also declare actions that will supplement the built-in ones and extends the possibilities of the agents. Here, we provide two possible actions for agents of species foo, eating and stealing energy: species foo {
var energy type: float init: rnd (100) min: 0 max: 100 value: energy - 0.001;
action eat {
set energy value: energy + rnd (2);
}
action steal {
let another_agent type:foo value: any ((foo as list) - self);
if condition: (another_agent != nil) and ((another_agent.energy) > 0){
set another_agent.energy value: another_agent.energy - 0.01;
set energy value: energy + 0.01;
}
}
}Of course, these actions do nothing unless they are called either by behaviors or by other agents. One might for example extend the previous example like: let foo_agents type: list of: foo value: [];
create species: foo number: 1000 return: foo_agents;
ask target:100 among (foo) {
do action: eat;
}
ask target: 100 among (foo) {
do action: steal;
}In this example, we create 1000 foos, ask 100 of them to eat, and another 100 of them to steal energy. If these commands are done repetitively (for example, every turn in the world), they will result in a somewhat complex dynamic distribution of the energy between the foos. Of course, the dynamics of foos can also be declared from within their species. If we change slightly the declaration of foo like this: species foo {
var energy type: float init: rnd (100) min: 0 max: 100 value: energy - 0.001;
action eat {
set energy value: energy + rnd (2);
}
action steal {
let another_agent type:foo value: any ((foo as list) - self);
if condition: (another_agent != nil) and ((another_agent.energy) > 0){
set another_agent.energy value: another_agent.energy - 0.01;
set energy value: energy + 0.01;
}
}
reflex {
if condition:flip (0.1) {
do action:eat;
}
if condition: flip (0.1) {
do action: steal;
}
}
}We obtain agents that execute the reflex every turn and decide independently to eat or steal energy. Once they are created using create species:foo number:1000; they behave by their own. Skills: behavioral plug-insBasic agents like the previous ones cannot, however, do many things. That's what skills are for. Example: species foo skills: [moving]{
...
}makes foos benefit from a set of variables and behaviors declared by the situated skill. Skills are like plug-ins written in Java and can provide a lot of new functionality to the agents. Aspects: display propertiesThe aspect section allows to define the display of of the agents. it is possible to define different displays (i.e. different aspect sections) for a same species. In this context, the user will be able to change the display drawn during the simulation execution. The command draw allows to draw a shape (line, circle or square), a icon, a text or the agent geometry. this command has several facets:
For example, the following model allows to define three displays for the agent: one named "info", another named "icon" and the last one named "default". aspect info {
draw shape: square at: location size: 2 rotate: heading;
draw geometry: square(2) rotated_by heading;
draw shape: line at: location to:destination + (destination - location) color:'white';
draw shape: circle at: location size:4 empty:true color:'white';
draw text: heading color: 'white' size:1;
draw text: state color: 'white' size:1 at:my location + {1,1};
}
aspect icon {
draw image: shape at: location size: 2 rotate: heading;
}
aspect default {
draw shape: square at: location empty: !hasFood color:'yellow' size: 2 rotate: heading;
}Parent: inheritance of speciesA species can be declared as a child of another species, using the parent property. For instance : species foo skills:[moving] parent:bar {
...
}will make foo "inherit" from the definition of bar. What does "inherit" precisely mean in this context ?
Scheduling descriptionThe modeler can specify the scheduling information of a species. The scheduling information composes of the execution frequency and the list of agent to be scheduled.
species foo skills:[moving] parent:bar frequency: 2 schedules: (list (foo)) where (each.energy > 50) {
var energy type: float init: rnd (100) min: 0 max: 100 value: energy - 0.001;
...
}
Hence, every 2 simulation step, "foo" agents having energy greater than 50 are scheduled. Topology descriptionThe topology describes the spatial organization of the species. This imposes constraint on the movement and perception (neighborhood) of the species' agents. GAMA supports three types of topology: continuous, grid and graph. species foo skills:[moving] parent:bar topology: (square (10)) at_location {50, 50} {
...
}Topology of the "foo" species is a square of 10 meters each side at location {50, 50}. Nesting speciesA species can be defined inside another species. The enclosing species is the macro-species. The enclosed species is the micro-species. A model has "world" species as top-level species. The "world" species has one special agent ("world" agent) playing the role of the global context. The possibility to establish micro-macro relationship, to specify the scheduling description and the topology description enable the modeler to develop multi-scale model. species A {
...
}
species B {
species C parent: A {
...
}
species D {
...
}
}
Control: behavioral architectureBy default, species are created with a minimal behavioral architecture : they only allow the definition of reflexes as a way to define the agents' behaviors. As reflex-based agents are somewhat limited when it comes to maintaining a state between two steps or enabling the selection of behaviors, GAML provides the modeler with two possible behavioral architectures, EMF (for Etho-Modeling Framework) and FSM (Finite State Machines). Each of them gives the possibility to define new elements in addition to reflexes : respectively tasks and states. Base: Java foundationThe corresponding class used to initialize agent. An advance feature of the GAMA platform allowing the third party developer to develop their own agent architecture using the Java programming language. | |