Collections

Agent can contain variables. Variables are generally used to store the results of model simulation, to model some data or object characteristics, changing over time. 

AnyLogic supports two types of variables – variables and collections.  

Variable is a simple variable of an arbitrary scalar type or Java class. 

A collection represents a group of objects, known as its elements. Some collections allow duplicate elements and others do not. Some are ordered and others unordered. Collections are used for defining data objects that group multiple elements into a single unit. Collections are used to store, retrieve and manipulate aggregate data. Typically, they represent data items that form a natural group, such as a queue (in this case elements represent people waiting in a queue), or an autopark (elements are trucks), or a telephone directory (a collection performs mapping of names to phone numbers).

Alike other AnyLogic variables, collections are accessible from code throughout the model simulation, so you can simply access and modify their contents via the collection API.

Collections. Use cases:

In an agent based model, a collection can be used to store a set of agents - e.g., neighbors or colleagues of a given agent.

In discrete event models, you can use collections to control the agents being held in a Queue or a Service object by adding agents into the collection in the object's On enter action and removing them from there in On exit.

Creating a collection

 To create a collection

  1. Drag the  Collection element from the  Agent palette onto the graphical diagram of agent type or experiment.
  2. Go to the Properties view.
  3. Type the name of the collection in the Name edit box. The name is used to identify and access the variable from code.
  4. Specify the class of the collection. You can choose one of the most-used classes from the Collection class combo box or specify any other collection class you wish. 
  5. If your collection is a list, or a set (collection class is ArrayListLinkedList, LinkedHashSet, or TreeSet), specify the class of the collection elements here. You can choose one of the most-used classes from the Elements class combo box or specify any other Java class. Choosing Object you allow the collection to store elements of any Java class.
  6. The collection can be initialized containing the set of elements, which you you specify in its Initial contents section. To add elements, click the button to select the elements from the drop-down list or click this button first and then select the elements in the graphical editor. Only the elements corresponding to the collection's Elements class can be selected.

    If no elements are selected in the Initial contents section, the collection will be initialized empty. You can modify the collection's contents dynamically at a later point using the collection API.

  7. If your collection is a map (collection class is either TreeMap, or LinkedHashMap), specify the type of keys maintained by this map in the Key elements class field and the type of mapped values in the Value elements class property.

Properties

General

Name – The name of the collection. The name is used to identify and access the collection from code.

Show name – If selected, the name of the collection is displayed on a presentation diagram.

Ignore – If selected, the collection is excluded from the model.

Visible – If selected, the collection is visible on a presentation at runtime.

Collection class – Class of the collection, see the details below. You can choose from the provided set of most-used collection types (ArrayList, LinkedListLinkedHashSet, TreeSetTreeMap, LinkedHashMap), or specify some other collection class here.

Elements class – [Visible if ArrayListLinkedList, LinkedHashSet, or TreeSet is chosen as Collection class] Class of collection elements. Choose one of the most-used classes or specify any other Java class you wish. Specifying the class here, you restrict the collection to have the elements of the specified class only. Choosing Object you allow collection to store elements of any Java class.

Key elements class – [Visible if TreeMap or LinkedHashMap is chosen as Collection class] The type of keys maintained by this map.

Value elements class – [Visible if TreeMap or LinkedHashMap is chosen as Collection class] The type of mapped values.

Initial contents – [Visible if ArrayListLinkedList, LinkedHashSet, or TreeSet is chosen as Collection class] The control allows you to explicitly select the elements to be included in the collection. You can select the elements either from the list or by clicking them in the graphical editor. Note that only the elements of the type corresponding to the collection's Elements class can be selected.

Advanced

Access – The collection’s access type. There are four access types:
    public - a collection can be accessed from anywhere 
    private – a collection can be accessed from this agent class only
    protected - a collection can be accessed from this agent class and its subclasses
    default - a collection can be accessed anywhere within this model.

Save in snapshot – If selected, the collection will be saved in model snapshot.

Static – If selected, the collection is static, i.e. it will have the same value for all instances of this class in the model (e.g. for all agents inside the population).

Do not use static collections, if you plan to run iterations of complex experiments (optimization, parameter variation, etc.) in parallel on different processor cores (this is set by the experiment's Allow parallel evaluations advanced option).

Static collections are not saved into a snaphot file when you save/restore a state of a running model. If you do not alter the contents of a static collection in your model, the state of the restored model will be exactly the same as you saved it into the snapshot. However, if you somehow change the contents of a static collection (e.g. in agent's On startup code), the modified contents won't be saved into a snapshot, and the restored state of the model will differ from the state you have previously saved.

Collection types

There are multiple collection implementations. They differ in the way how the data items are stored and in the way you can retrieve and manipulate them. 

Operation ArrayList LinkedList LinkedHashSet TreeSet TreeMap LinkedHashMap
Obtain size Constant Constant Constant
Constant Constant Constant
Add element Constant Constant Constant Logarithmic Logarithmic Constant
Remove given item Linear Linear Constant
Logarithmic Logarithmic Constant
Remove by index Linear Linear - - - -
Get element by index Constant Linear - - - -
Find out if contains Linear Linear Constant Logarithmic Logarithmic Constant

AnyLogic supports all collection implementations defined in the Java Collections Framework. The following collection implementations are most frequently used and therefore provided as options in the Collection class field:

Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides functions to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is unsynchronized.)

The size, isEmpty, get, set, iterator, and listIterator operations run in constant time. The add operation runs in amortized constant time, that is, adding n elements requires O(n) time. All other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.

Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.

An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)

Doubly-linked list implementation of the List and Deque interfaces. Implements all optional list operations, and permits all elements (including null). All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.

Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements; merely setting the value of an element is not a structural modification.)

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)

This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet.

This class provides all of the optional Set operations, and permits null elements. Like HashSet, it provides constant-time performance for the basic operations (add, contains and remove), assuming the hash function disperses elements properly among the buckets. Performance is likely to be just slightly below that of HashSet, due to the added expense of maintaining the linked list, with one exception: Iteration over a LinkedHashSet requires time proportional to the size of the set, regardless of its capacity. Iteration over a HashSet is likely to be more expensive, requiring time proportional to its capacity.

A linked hash set has two parameters that affect its performance: initial capacity and load factor. They are defined precisely as for HashSet. Note, however, that the penalty for choosing an excessively high value for initial capacity is less severe for this class than for HashSet, as iteration times for this class are unaffected by capacity.

Note that this implementation is not synchronized. If multiple threads access a linked hash set concurrently, and at least one of the threads modifies the set, it must be synchronized externally.

A NavigableSet implementation based on a TreeMap. The elements are ordered using their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used.

This implementation provides guaranteed log(n) time cost for the basic operations (add, remove and contains).

Note that this implementation is not synchronized. If multiple threads access a tree set concurrently, and at least one of the threads modifies the set, it must be synchronized externally.

A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

This implementation provides guaranteed log(n) time cost for the containsKey, get, put and remove operations. Algorithms are adaptations of those in Cormen, Leiserson, and Rivest's Introduction to Algorithms.

Note that the ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with equals if this sorted map is to correctly implement the Map interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, but a sorted map performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a sorted map is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Map interface.

A hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which can be the order in which keys were inserted into the map (insertion-order) or the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order).

Note that this implementation is not synchronized. If multiple threads access a linked hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. A structural modification is any operation that adds or deletes one or more mappings or, in the case of access-ordered linked hash maps, affects iteration order. In access-ordered linked hash maps, merely querying the map with get is a structural modification. In insertion-ordered linked hash maps, merely changing the value associated with a key that is already contained in the map is not a structural modification.