I could need some help with a Anylogic Model.
Model (short): Manufacturing scenario with orders move in a individual route. The workplaces (WP) are dynamical created by simulation start. Their names, quantity and other parameters are stored in a database (excel Import). Also the orders are created according to an import. The Agent population "order" has a collection routing which contains the Workplaces it has to stop in the specific order.
Target: I want a moveTo block in main which finds the next destination of the agent order. Problem and solution paths:
I set the destination Type to agent and in the Agent field I typed a function agent.getDestination()
. This function is in order which returns the next entry of the collection WP destinationName = routing.get(i)
. With this I get a Datatype error (while run not compiling). I quess it's because the database does not save the entrys as WP Type but only String.
Is there a possiblity to create a collection with agents from an Excel?
After this I tried to use the same getDestination as String an so find via findFirst the WP matching the returned name and return it as WP. WP targetWP = findFirst(wps, w->w.name == destinationName);
Of corse wps (the population of Workplaces) couldn't be found.
How can I search the population?
Maybe with an Agentlink?
I think it is not that difficult but can't find an answer or a solution. As you can tell I'm a beginner... Hope the description is good an someone can help me or give me a hint :) Thanks
Is there a possiblity to create a collection with agents from an Excel?
Not directly using the collection's properties and, as you've seen, you can't have database (DB) column types which are agent types.1
But this is relatively simple to do directly via Java code (and you can use the Insert Database Query wizard to construct the skeleton code for you).
After this I tried to use the same getDestination as String an so find via findFirst the WP matching the returned name and return it as WP
Yes, this is one approach. If your order details are in Excel/the database, they are presumably referring to workplaces via some String ID (which will be a parameter of the workplace agents you've created from a separate Excel worksheet/database table). You need to use the Java equals
method to compare strings though, not ==
(which is for comparing numbers or whether two objects are the same object).
I want a moveTo block in main which finds the next destination of the agent order
So the general overall solution is
Create a population of Workplace
agents (let's say called workplaces
in Main) from the DB, each with a String parameter id
or similar mapped from a DB column.
Create a population of Order
agents (let's say called orders
in Main) from the DB and then, in their on-startup action, set up their collection of workplace IDs (type ArrayList
, element class String
; let's say called workplaceIDsList
) using data from another DB table.
Order
probably also needs a working variable storing the next index in the list that it needs to go to (so let's say an int
variable nextWorkplaceIndex
which starts at 0).
Write a function in Main called getWorkplaceByID
that has a single String
argument id
and returns a Workplace
. This gets the workplace from the population that matches the ID; a one-line way similar to yours is findFirst(workplaces, w -> w.id.equals(id))
.
The MoveTo block (which I presume is in Main) needs to move the Order
to an agent defined by getWorkplaceByID(agent.workplaceIDsList.get(nextWorkplaceIndex++))
. (The ++
bit increments the index after evaluating the expression so it is ready for the next workplace to go to.)
For populating the collection, you'd have two tables, something like the below (assuming using strings as IDs for workplaces and orders):
orders
table: columns for parameters of your orders (including some String id
column) other than the workplace-list. (Create one Order
agent per row.)
order_workplaces
table: columns order_id
, sequence_num
and workplace_id
(so with multiple rows specifying the sequence of workplace IDs for an order ID).
In the On startup action of Order
, set up the skeleton query code via the Insert Database Query wizard as below (where we want to loop through all rows for this order's ID and do something --- we'll change the skeleton code to add entries to the collection instead of just printing stuff via traceln
like the skeleton code does).
Then we edit the skeleton code to look like the below. (Note we add an orderBy
clause to the initial query so we ensure we get the rows in ascending sequence number order.)
List<Tuple> rows = selectFrom(order_workplaces)
.where(order_workplaces.order_id.eq(id))
.orderBy(order_workplaces.sequence_num.asc())
.list();
for (Tuple row : rows) {
workplaceIDsList.add(row.get(order_workplaces.workplace_id));
}
1 The AnyLogic database is a normal relational database --- HSQLDB in fact --- and databases only understand their own specific data types like VARCHAR
, with AnyLogic and the libraries it uses translating these to Java types like String
. In the user interface, AnyLogic makes it look like you set the column types as int
, String
, etc. but these are really the Java types that the columns' contents will ultimately be translated into.
AnyLogic does support columns which have option list types (and the special Code
type column for columns containing executable Java code) but these are special cases using special logic under the covers to translate the column data (which is ultimately still a string of characters) into the appropriate option list instance or (for Code
columns) into compiled-on-the-fly-and-then-executed Java).