Beginner stuck on multicriteria_analyzer, placing agents, passing attribute information between species

91 views
Skip to first unread message

b.car...@gmail.com

unread,
Jun 1, 2014, 1:55:55 PM6/1/14
to gama-p...@googlegroups.com
Greetings from Canada! :)

I am a Masters student working on implementing a suitability analysis of retail development in an agent-based model of spatial resource competition. I am trying to get a brand species to evaluate a random fixed number of parcel species, and then create a store species at a parcel based on a decision of suitability. Store species then gather expenditures from an expenditure species based on their distance from a given store agent.

I began by creating a brand species as a child of the multicriteria_analyzer:
entities {
 species parcel
{
 
int PIN //* unique identifying integer for a parcel/
 
int criteria1; //* values for a criteria/
 
int criteria2;
 
int criteria3;}


species expenditure
{ //* this species is represented as points from a shapefile
 
int ID;
 
float demand;}


species brand parent
: multicriteria_analyzer {
 
string brand_name;
 
float avg_size;
 
 reflex make_store_decision
{ //* I wish to implement a multi-criteria decision based on criteria in parcel species/
 
do make_store (avg_size);
 
}
 
 action make_store
(float store_size){
 create store number
: 1 {
 size
<- store_size;
 
}
 
}
 
}
 species store
{
 
float size;
 
float exp_gathered;
 
float service_area;
 
 reflex query_exp
{
 ask expenditure at_distance service_area
; //* Here a created store agent will ask for expenditure agents within a certain distance
 
}

At this point my model runs and is displayed successfully, but I'm stuck on three things:
(1) I have weights for each criteria as global variables for the brand species to access, but I'm stuck on the brand species implementing a multi-criteria analysis of the  criteria attributes in the parcel species. I know that this built-in agent requires criteria values, but can I pass it the attributes from the parcel species?

(2) Once a parcel is decided upon by the brand agent, how would I place a store agent at that parcel?

(3) How do I get a store agent to gather the attribute "exp" (expenditure) from expenditure species based on the at_distance line? At_distance returns a list, so I think I should loop through the list and add the "exp" attribute from each expenditure species to the attribute "exp_gathered" of the store species.

As you can tell, I am new to GAMA and stuck on writing the actual code. I've attached a copy of my complete model for further reference. Thank you for taking the time to answer my questions,

- Bogdan

RetailSuitability_new.gaml

Patrick Taillandier

unread,
Jun 2, 2014, 4:59:12 AM6/2/14
to gama-p...@googlegroups.com
Hi,

First, just to know: which version of GAMA are you using?

1)I attached a example model showing how to use multi-criteria decision making. For all multi-criteria decision making action, you have to give an map of criteria (for some method, you just have to define weights, for other it is more complex) and the possible candidates. The actions return the index of the best candidate.

2) To place on agent on another agent is quite simple: 
if you want to place your agent on the centroid of your parcel agent: location <- my_parcel.location;
if you want to place it on random point inside the parcel geometry: location <- any_location_in(my_parcel);

3) I am not sure to understand what you want to do. The operator "a_species at_distance dist" returns the list of agents of species a_species at distance dist. From this list, you can build the list of exp with the collect operator, then sum them with the "sum" operator.

For instance:
reflex query_exp {
exp_gathered <- sum((expenditure at_distance service_area) collect (each.exp));
}

Do not hesitate (if it is possible) to send your complete model (with your data) to us (it is easier for us to analyze a model if we can run it).

Cheers,

Patrick




--
You received this message because you are subscribed to the Google Groups "GAMA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gama-platfor...@googlegroups.com.
To post to this group, send email to gama-p...@googlegroups.com.
Visit this group at http://groups.google.com/group/gama-platform.
For more options, visit https://groups.google.com/d/optout.

Multicriteria.gaml

b.car...@gmail.com

unread,
Jun 2, 2014, 4:41:38 PM6/2/14
to gama-p...@googlegroups.com

Hi Patrick,

Thank you for your helpful response, I will incorporate your advice into the model so far. I'm using GAMA 1.6. Unfortunately I cannot share the source data due to privacy reasons, but I can say that the parcel agents all have attributes informed by a shapefile of ~150,000 parcels with attributes that define suitability. A brand species agent (with the MCDM agent as parent) will make a random selection of parcels and evaluate their characteristics (from the shapefile) for suitability. At the moment I'm not sure how to get the multicriteria_analyzer  to be informed by a random selection (of say 250 parcels at a time) of parcel agents and their characteristics from the parcel shapefile. I think that for the reflex "make_store_decision", each brand species would randomly evaluate a number of parcel species and create a store species at a chosen parcel. Hopefully this clarifies what I'm trying to implement.

I will take a closer look at your MCDM example code and post back if I have further questions.

Thanks again,

Bogdan

PS; I'm very impressed with GAMA so far, I'm trying to convince my supervising professor to use it instead of NetLogo, but I have to show him that GAMA can be implemented!
PPS; I attached a copy of my code in the previous response but I'll include it below:

model RetailSuitability

//**------------------------------GLOBAL AGENT--------------------------------------------------*/
global {
// Spatial data
file shp_parcels <- file("../includes/3530_parcels.shp");
file shp_expenditures <- file("../includes/DA_ON_2011_expenditures.shp");
file shp_competitors <- file("../includes/Competitors.shp");
file shp_boundary <- file("../includes/CD_3530.shp");
file shp_buffer <- file("../includes/CD_3530_10k_buffer.shp");
file brand_size <- file(".../includes/BrandSize.txt");
geometry shape <- envelope(shp_buffer);
// Criteria weights
float exp_cw <- 0.4;
float area_cw <- 0.2;
float ramp_cw <- 0.1;
float lc2_cw <- 0.1;
float lc3_cw <- 0.05;
float lc4_cw <- 0.05;
float elev_cw <- 0.01;
float slope_cw <- 0.04;
float d2dc_cw <- 0.05;
// Number of brands, list of parcels, and sample of parcels for brand decisions
//int n_brands <- 10;
list parcelList <- [];
//add PIN to: parcelList;
int n_parcels <- 100;
reflex model_pause when: time = 1000 {
            do pause;
     }

/** -------------------------------INITIALIZATION---------------------------------------------------*/
init {
create parcel from: shp_parcels 
with: [
PIN::int(read("PIN")),
area::float(read("Shape_Area")),
ramp_tt::float(read("TravelTime")),
pLC1::int(read("pLC1")),
pLC2::int(read("pLC2")),
pLC3::int(read("pLC3")),
pLC4::int(read("pLC4")),
pLC5::int(read("pLC5")),
elevation::int(read("elev_mean")),
slope::int(read("slope_mean")),
d2dc::float(read("d2DC"))
];

create expenditure from: shp_expenditures
with: [
DAID::int(read("DAID")),
exp::float(read("EXPM3"))
];

create competitor from: shp_competitors
with: [
size::float(read("Area")),
name::string(read("BrandName"))
];
create brand from: brand_size
with: [
avg_size::float(read("MeanArea")),
brand_name::string(read("BrandName"))
];
}
}

/** --------------------------------ENTITIES------------------------------------------------------- */
entities {
species parcel {
int PIN;
float area;
float ramp_tt;
int pLC1;
int pLC2;
int pLC3;
int pLC4;
int pLC5;
int elevation;
int slope;
float d2dc;
rgb color <- rgb("gray") ;
aspect base {
draw shape color: color ;
}
}
species expenditure {
int DAID;
float exp;
rgb color <- rgb("blue") ;
aspect base {
draw shape color: color ;
}
}
species competitor {
string name;
float size;
rgb color <- rgb("red") ;
aspect base {
draw shape color: color ;
}
}
species brand parent: multicriteria_analyzer {
string brand_name;
float avg_size;
reflex make_store_decision {
do make_store (avg_size);
}
action make_store (float store_size){
create store number: 1 {
size <- store_size;
}
}
}
species store {
float size;
float exp_gathered;
float service_area;
reflex query_exp {
ask expenditure at_distance service_area;
}
reflex gather_exp {
}
reflex die when: exp_gathered <= 0 {
do die;
}
const color type: rgb <- rgb("blue");
aspect base {
draw shape color: color ;
}
}
}

/** ----------------------------EXPERIMENT----------------------------------------------------------*/
experiment RetailSuitability type: gui {
/** Insert here the definition of the input and output of the model */
parameter "Shapefile for parcels:" var: shp_parcels category: "GIS";
parameter "Shapefile for expenditures:" var: shp_expenditures category: "GIS";
parameter "Shapefile for competitors:" var: shp_competitors category: "GIS";

output {
display city_display {
species parcel aspect: base ;
species expenditure aspect: base ;
species competitor aspect: base ;
}
}
}


Patrick Taillandier

unread,
Jun 4, 2014, 4:12:25 AM6/4/14
to gama-p...@googlegroups.com
Ok,
 Note that concerning the confidentiality of the data, you can just create a simple "artificial" dataset with the same structure as your original data but with just few agents (for instance, 10 parcels).

Cheers,

Patrick

b.car...@gmail.com

unread,
Jun 4, 2014, 6:43:19 PM6/4/14
to gama-p...@googlegroups.com
Hi Patrick,

I've attached a copy of my model along with a small subset (~120 parcels) of my data. The option to run an experiment is gone, but I suspect it has something to do with the renamed GAML file.

- Bogdan
ABM_example.zip

Patrick Taillandier

unread,
Jun 5, 2014, 12:13:26 PM6/5/14
to gama-p...@googlegroups.com
Hi,

Ok, for further questions, I will like that be able to answer more precisely.
Just an advice concerning your display, you should use an opengl display (far more optimized than java display, in particular for zooming):

experiment RetailSuitability type: gui {

/** Insert here the definition of the input and output of the model */

parameter "Shapefile for parcels:" var: shp_parcels category: "GIS";

parameter "Shapefile for expenditures:" var: shp_expenditures category: "GIS";


output {

display city_display type: opengl{

species parcel aspect: base refresh: false;

species expenditure aspect: base ;

}

}

}


b.car...@gmail.com

unread,
Jun 5, 2014, 1:43:10 PM6/5/14
to gama-p...@googlegroups.com
Thanks Patrick,

I've set OpenGL as the default display and created a list of criteria in the global agent. I stuck on two things at the moment:
1) how do I inform the criteria with the attributes of the parcel species? I would like the attributes of the parcels shapefile to provide values for the MCE criteria.

2) how would I randomly select, say, 10 parcels at random for input into the multicriteria analyzer? Right now I'm using the weighted_means_DM() function in the make_store_decision reflex of the brand species.

Any help on these two problems would be much appreciated. I've attached an updated and abbreviated copy of my code so far.

- Bogdan
RetailSuitability_example.gaml

Patrick Taillandier

unread,
Jun 7, 2014, 3:13:08 AM6/7/14
to gama-p...@googlegroups.com
Hi,

1) The simplest way: create 

2) you can just a_number among a_list

for instance, in your brand species:

reflex make_store_decision {

list<parcel> possible_parcels <- 10 among parcel;

list<list> cands <- parcels_eval(possible_parcels);

int choice <- weighted_means_DM(cands, criteria_WM);

if (choice >= 0) {

ask possible_parcels[choice] {

write name + " : I am the selected parcel !";

}

}

// list<list> candidates <- ;

// int choice <- weighted_means_DM(candidates, criteria_WM);

do make_store (avg_size);

}

list<list> parcels_eval(list<parcel> parcels) {

list<list> candidates <- [];

loop par over: parcels {

list<float> cand <- [];

cand << par.area// val criterion 1 for parcel "par" 

cand << par.elevation// val criterion 2 for parcel "par" 

//... and so on

candidates << cand;

}

return candidates;

}

Cheers,

Patrick

Patrick Taillandier

unread,
Jun 7, 2014, 3:14:00 AM6/7/14
to gama-p...@googlegroups.com
Oups, for question, I just wanted to say: have a look at the code example that just follow

b.car...@gmail.com

unread,
Jun 9, 2014, 10:11:36 AM6/9/14
to gama-p...@googlegroups.com
Hi Patrick,

Thank you very much for your help and examples. One last thing, for the criteria_WM list in the global section of the model should the criteria names be expressed as strings or without quotations? If I remove the quotations and express them as variables they are highlighted as errors, likely because the attributes specified are being created in a species context (?).

- Bogdan
...

Patrick Taillandier

unread,
Jun 9, 2014, 10:15:54 AM6/9/14
to gama-p...@googlegroups.com
Hi,

As a string (""). 

Cheers,

Patrick
Reply all
Reply to author
Forward
0 new messages