3
votes

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.

  1. Is there any way in AnyLogic to store distributions in collections?
  2. Is there any way in AnyLogic to read distributions from a database?

Thanks

1

1 Answers

4
votes

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:

database 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: 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();