0
votes

I am trying to model population density in AnyLogic. To that end, I've inserted an image of a country in Main, and used polyline to draw areas (called pl_[areaname], provinces in this case. Then using a function (SetHomeLocation) in Main, I am placing agents (patients in this case) in these areas, if a condition is met. For brevity, part of the code is shown below.

double x;
double y;
if(uniform(1) <=  0.0343995) /// province 1
do {
    x = uniform( image.getX(), image.getX() + image.getWidth() );
    y = uniform( image.getY(), image.getY() + image.getHeight() );
} while( ! pl_Groningen.contains( x, y ) );
else if(uniform(1) > 0.0343995 && uniform(1) <= 0.0725446) /// province 2
do {
    x = uniform( image.getX(), image.getX() + image.getWidth() );
    y = uniform( image.getY(), image.getY() + image.getHeight() );
} while( ! pl_Friesland.contains( x, y ) );
else
do {
    x = uniform( image.getX(), image.getX() + image.getWidth() );
    y = uniform( image.getY(), image.getY() + image.getHeight() );
} while( ! countrybounds.contains( x, y ) );
agent.setXY( x, y );

In Patient, I've created two variables XHome and YHome, and in the 'on startup' field I've entered:

//setup home location (within the country bounds that are defined in Main)
main.setHomeLocation( this );
XHome = getX();
YHome = getY();

Now it seems that the code in SetHomeLocation function is not working as it supposed to be. I am getting fewer agents in some areas than I would expect.

I also believe that

if(uniform(1) > x && uniform(y) <= y)

is faulty, as I believe that statement would evaluate two different draws from the uniform distribution, instead of one.

For full disclosure, the following link lets you download the complete model. https://www.mediafire.com/file/eaq65mgpqi9qlld/TestModelKaart.zip/file

To be clear, this post contains two questions. First, what could be the cause that the model shows unexpected behavior, i.e. placing too few agents in some areas? Second, how do I let AnyLogic evaluate one draw from the uniform distribution, if I want x > uniform(1) <= y?

Any other tips that are related to modeling population density are of course very welcome!

2
Hi UTq, welcome to SOF. Thanks for sharing lots of details, certainly useful. Could you also, in the future, split up several questions? Will happen replies and also future users that might search for one of them :-)Benjamin
Thanks, Benjamin. Will do that in future questions!UTq

2 Answers

1
votes

To answer at least one of your questions, you have to create a variable in the beginning and use it in the rest of your function:

double rand=uniform();
if(rand <=  0.0343995) /// province 1
//your code
else if(rand > 0.0343995 && rand <= 0.0725446) /// province 2
//your code
else //rand>0.0725446
//your code

Check first if this solves your other problem or not.

1
votes

First of all, about your second question, and generally your code, you'd better save generated random number in a local variable, something like double rand = uniform(); and then use the local variable in following parts of your code. This way you can evaluate if(rand > x && rand <= y) properly. Also it may solve your first problem because your second if statement in its previous form (as you've mentioned) won't function properly.

Second, if you've drawn your provinces as polyLines, there is no need to use a do while to find a point inside your polyLine. You can use pl_[areaname].randomPointInside() to find a random point inside `pl_[areaname]'.