/**
* Name: Spatial Operators
* Author: Patrick Taillandier
* Description: A model which shows how to use spatial operator, allowing the user to change the parameter operator in the
* experiment to test the different operators and see the results
* Tags: topology, grid
*/
model gridfilter
global {
map> theDummies;
map> theCells;
string parameter_operator <-"closest_to" among:["closest_to","at_distance","neighbors_at","distance_to","path_to","cluster_distance","cluster_hierarchical"];
init {
//Create the agents
do create_dummy_agents;
//Different actions to test the operators
do test_agents_at_distance;
do test_distance_to;
do test_neighbors_at;
do test_path_to;
do test_simple_clustering_by_distance;
do test_hierarchical_clustering;
do test_agent_closest_to;
}
action test_agent_closest_to {
//It is possible to use the topology of the world (default), the graph or the grid
add [dummy(8)::#yellow] at:"closest_to" to:theDummies;
add #red at:dummy closest_to (dummy(8)) to:theDummies["closest_to"];
add [cell(40)::#yellow] at:"closest_to" to:theCells;
add #red at:cell closest_to (cell(40)) to:theCells["closest_to"];
}
action test_agents_at_distance {
//It is possible to use the topology of the world (default), the graph or the grid
ask dummy(8)
{
add [self::#yellow] at:"at_distance" to:theDummies;
loop a_dummy over: agents_at_distance(30) of_species dummy
{
add #red at:a_dummy to:theDummies["at_distance"];
}
}
ask cell(40)
{
add [self::#yellow] at:"at_distance" to:theCells;
loop a_cell over: agents_at_distance(10) of_species cell
{
add #red at:a_cell to:theCells["at_distance"];
}
}
}
action test_neighbors_at {
//It is possible to use the topology of the world (default), the graph or the grid
//The operator neighbors_at gives the same results that neighbors_of( an_agent, a_distance )
add [dummy(8)::#yellow] at:"neighbors_at" to:theDummies;
loop a_dummy over: dummy(8) neighbors_at 30
{
add #red at:a_dummy to:theDummies["neighbors_at"];
}
add [cell(40)::#yellow] at:"neighbors_at" to:theCells;
loop a_cell over: cell(40) neighbors_at 20
{
add #red at:a_cell to:theCells["neighbors_at"];
}
}
action test_distance_to {
//It is possible to use the topology of the world (default), the graph or the grid
//The operator distance_to gives the same results that the operator topology distance_between[an_agent_A,an_agent_B]
add [dummy(8)::#yellow] at:"distance_to" to:theDummies;
add #red at:dummy(5) to:theDummies["distance_to"];
add [cell(40)::#yellow] at:"distance_to" to:theCells;
add #red at:cell(27) to:theCells["distance_to"];
}
action test_path_to {
//It is possible to use the topology of the world (default), the graph or the grid
//The operator distance_to gives the same results that the operator topology path_between[an_agent_A,an_agent_B]
add [dummy(8)::#yellow] at:"path_to" to:theDummies;
add #red at:dummy(9) to:theDummies["path_to"];
add [cell(40)::#yellow] at:"path_to" to:theCells;
add #red at:cell(28) to:theCells["path_to"];
}
action test_simple_clustering_by_distance
{
//Can be used for other topologies by adding using(topology(cell)) for example
list> clusteredDummies <- list>(dummy simple_clustering_by_distance 30);
loop a_list over: clusteredDummies
{
rgb colorList <- rgb(rnd(255),rnd(255),rnd(255));
loop a_dummy over: a_list
{
if(!(theDummies contains_key "cluster_distance") or length(theDummies["cluster_distance"])=0)
{
add map([a_dummy::colorList]) at:"cluster_distance" to:theDummies;
}
else
{
add colorList at:a_dummy to:theDummies["cluster_distance"];
}
}
}
}
action test_hierarchical_clustering {
//Can be used for other topologies by adding using(topology(cell)) for example
list> clusteredDummies <- list>(dummy hierarchical_clustering 10);
loop a_list over: clusteredDummies
{
rgb colorList <- rgb(rnd(255),rnd(255),rnd(255));
loop a_dummy over: a_list
{
if(!(theDummies contains_key "cluster_hierarchical") or length(theDummies["cluster_hierarchical"])=0)
{
add map([a_dummy::colorList]) at:"cluster_hierarchical" to:theDummies;
}
else
{
add colorList at:a_dummy to:theDummies["cluster_hierarchical"];
}
}
}
}
action create_dummy_agents {
create dummy with: [location :: {5,5}];
create dummy with: [location :: {8,9}];
create dummy with: [location :: {14,6}];
create dummy with: [location :: {35,55}];
create dummy with: [location :: {25,75}];
create dummy with: [location :: {56,80}];
create dummy with: [location :: {10,70}];
create dummy with: [location :: {80,8}];
create dummy with: [location :: {34,78}];
create dummy with: [location :: {67,32}];
loop i from: 0 to: length(dummy) - 1 {
ask dummy[i] {id <- string(i);}
}
}
}
grid cell width: 10 height: 10 neighbors: 4{
rgb color <- #green;
}
species dummy {
string id;
aspect default {
draw circle(2) color: #yellow;
draw id size: 6 color: #black;
}
}
experiment topology_test type: gui {
/** Insert here the definition of the input and output of the model */
parameter "Operator" var: parameter_operator;
output {
display Continuous_Environment
{
graphics cell
{
loop a_key over: theCells[parameter_operator].pairs {
draw a_key.key at:a_key.key.location color: theCells[parameter_operator][a_key.key] ;
}
loop a_cell over: cell-theCells[parameter_operator].keys
{
draw a_cell at:a_cell.location color: #green ;
}
//Display a line between the two chosen cell for the distance_to operator
if(parameter_operator="distance_to")
{
geometry aLine <- line([theCells[parameter_operator].keys[0].location,theCells[parameter_operator].keys[1].location]) +1.2;
draw (aLine) color:#silver;
draw string(distance_to (theCells[parameter_operator].keys[0].location,theCells[parameter_operator].keys[1].location)) at:aLine.location size: 6 color: #silver;
}
else
{
//Display a path between the two chosen cell for the path_to operator
if(parameter_operator="path_to")
{
path aPath <- theCells[parameter_operator].keys[0] path_to theCells[parameter_operator].keys[1].location;
loop eg over: aPath.edges
{
draw (geometry(eg)+1.2) color:#silver;
}
}
}
}
graphics dummy
{
loop a_key over: theDummies[parameter_operator].pairs {
draw circle(2) at:a_key.key.location color: theDummies[parameter_operator][a_key.key] ;
draw a_key.key.id at:a_key.key.location size: 6 color: #black;
}
loop a_dummy over: dummy-theDummies[parameter_operator].keys
{
draw circle(2) at:a_dummy.location color: #grey ;
draw a_dummy.id at:a_dummy.location size: 6 color: #black;
}
//Display a line between the two chosen dummies for the distance_to operator
if(parameter_operator="distance_to")
{
geometry aLine <- line([theDummies[parameter_operator].keys[0].location,theDummies[parameter_operator].keys[1].location]) +1.2;
draw (aLine) color:#pink;
draw string(distance_to (theDummies[parameter_operator].keys[0].location,theDummies[parameter_operator].keys[1].location)) at:aLine.location size: 6 color: #pink;
}
else
{
//Display a path between the two chosen dummies for the path_to operator
if(parameter_operator="path_to")
{
path aPath <- theDummies[parameter_operator].keys[0] path_to theDummies[parameter_operator].keys[1].location;
loop eg over: aPath.edges
{
draw (geometry(eg)+1.2) color:#pink;
}
}
}
}
}
}
}