I'm migrating from Arena to AnyLogic and have a question about distributions. I need to use different distributions based on some agent parameters. I have seen the suggestion here but the number of distributions is too large and I prefer not to hard code them.
How to associate a probability distribution to Agents - Anylogic
In Arena it was possible to create expression arrays and link them to a database (e.g. excel) and use those parameters to obtain distributions from expression arrays. I tried to use collections in AnyLogic to do the same but could not convert the strings (e.g. "uniform(100,120)") to distributions.
Thanks
Everything you say is possible.. there are at least 4 ways of doing it: creating agents with the distribution, creating a collection of distribution classes, executing the string expression you mentioned and reading and calculating directly from the database. In this particular case, I like the option with classes and the expression one will be the simpler for you, but I may write down all the other options too later:
Using ExecuteExpression
If you managed to create a collection with strings that represent your distributions, you can do this:
executeExpression("uniform(100,200)");
or in your case with a collection (whatever you choose "i" to be)
executeExpression(collection.get(i));
But this is ugly, so I will do the complicated and cool way
Using Databases
The first thing obviously is to create a database with your information. I will assume since that is what seems to be your case, that you want to have a collection of distributions that are all uniform. So the database will look like this:
Where cum_probability is the cumulative probability for that distribution to be chosen and maximum and minimum will represent the parameters of your uniform(minimum, maximum) distribution.
Collection of Distributions using a Class
Now we will create a class with all that information:
public class Distribution implements Serializable {
public double probability;
public double min;
public double max;
/**
* Default constructor
*/
public Distribution(double probability,double min,double max) {
this.probability=probability;
this.min=min;
this.max=max;
}
public double getDistributionResult() {
return uniform(this.min,this.max,new Random());
}
}
You will also create a collection:
And you will initialize your collection in Main - on startup
List <Tuple> theList=selectFrom(distributions).list();
for(Tuple t : theList){
distributionsArray.add(
new Distribution(t.get(distributions.cum_probability),
t.get(distributions.minimum),
t.get(distributions.maximum))
);
}
Ok, now you have a collection of distributions. Great. The only thing remaining is to create a function that will return the random collection distribution result:
double rand=uniform();
List <Distribution> filtered=filter(distributionsArray,d->d.probability>=rand);
return top(filtered,d->-d.probability).getDistributionResult();