Parallel activities for one agent - simulation

Is there a way to have parallel services and/or delays to occur per agent and move on with the activity that takes the longest. For example if I have an agent that can be painted and serviced at the same time, each requiring a different resource pool with different processing times but the agent will move forward when the process that took the longest is over.

Use a Split block to split your agent into two for the two parallel tasks (Service blocks) and then use a Combine to combine them back again afterwards (with the Combine block outputting the original agent 1).
You can also use RestrictedAreaStart and RestrictedAreaEnd blocks (capacity 1) around the split/combine area to ensure that other agents can't 'jump in' whilst the longest parallel process is still running (but the shorter one has already finished).
Something like the below (with resource pools).

Probably easiest to dynamically setup delay duration and resources needed from within 1 Service element:
calculate the duration your agent will use in each case (painting = 5 mins, servicing = 10 mins) --> use the longer value as the service delay
Also, make the agent require 1 painter and 1 service-engineer as resources.
Only drawback: Your painter will stay for 10 mins as well.
Alternative approach would likely involve creating your own, purely agent-based setup with seizing& releasing

Related

How to send agents to sink block if aging higher than threshold

I am building a model where at any point in time if any agent is in system beyond threshold it has to go to Sink block. Is it possible to do it based on Agent time in system ?
If agents spent 180 days and beyond I want to send it to write-off block
what you need to do first is to create an enter block that connects to your sink block
With that done, most of the blocks have a remove method associated, so you can do this, with any agent a:
a.currentBlock().remove(a);
enter.take(a);
Nevertheless, this is not good practice in my opinion, removing an agent from any block at any time will almost certainly mess up your flow logic in some way...

Work shift scheduling with break times for specific agents

I am building a simulation model for a production line. There are two shifts (morning and night shift, 12 hours each) daily. Within each shift, the workers are split into 4 groups and each group goes for meal breaks at a staggered timing (eg. 4 workers in morning shift, first worker goes for break at 9am, second goes at 10am, etc.). These workers will also take ad-hoc breaks at random occurrences during their shift.
Not sure which method would work:
Creating an individual schedule within the agent and let it change states according to the schedule?
Use a common schedule for the entire resource pool, but will it be possible to pick which agent goes for break at the break time? Or will the agent be picked at random? Caus my concern is that i'll need the agents to take breaks but at staggered intervals.
Or should I generate this in a different approach?
Good question!
On option 2)
If you use the resource pool you will not be able to choose a specific agent as shifts and breaks are created for the entire pool.
What you can do is to define the capacity of the resource pool using, multiple schedules
This can help you artificially define the staggered. nature of the break-taking for resources.
Refer to the help for more details - https://anylogic.help/library-reference-guides/process-modeling-library/resourcepool.html
I believe this answers your question already but here are my notes on the other option.
Option 1)
If you require more advanced flexibility and control over the breaks and you do have the required Java skills (and time!) you can create custom code that controls when to send agents on a break and when to to return. You can use StateCharts inside your agents to build this logic. But then this will not be compatible with the resource pool since the resource pool will be oblivious to the state of the agents inside the pool and it will seize units that are taking a break...
So in this case your size delay and release will also be custom.
This is a lot of work and should only be attempted if you have the time, skills and require a level of flexibility and customization not offered by the resource pool.

Service block reduce delay time using resource pool workers

I have a resource pool and a service block. The number of the operator in the resource pool is 5 which is linked to the service block. I would like to setup the service in a way that the more workers work on the service the delay time decreases. (ex: if 1 worker works the delay time is 10 min - if 2 workers work the delay time is 5 min. - if 3 workers work the delay time is 3.33 min). I would like up to 5 operators to be working at the same time in the service block based on their availability.
Service Block and Resource Pool
How can I achieve this?
So you're trying to do two things with your Service block:
Seize a dynamic number of units (in the simplest case, seize all available units).
Have the delay time dependent on the number of units seized (in the simplest case, just decreasing multiplicatively according to the number of resources).
For the former, assuming you're seizing from a single pool, just enter a dynamic expression in the "Number of units" property. In the simplest case (seize all available) it would just be pool.idle() (for a resource pool called pool) but that's problematic if the next agent arrives whilst the first is being processed (because it will be treated as needing zero resources) so, depending what you want, you might need to do something like put RestrictedAreaStart / End blocks around your Service block so only one agent can be in the Service block at once.
NB: AnyLogic currently has a bug/limitation that the resource pool's idle/busy counts (from its idle() and busy() functions) are not guaranteed to be correct unless you are at a later simulation time than when seizes/releases occurred. (This is due to how things are resolved in hidden events under-the-covers.) So, if you want to use them in your determination of the number of resources to seize you need to work round this; e.g., by
tracking the number of busy/idle units via your own counts;
using the isIdle() function on individual resources in the pool instead (which typically requires ensuring the resource pool agents are in a custom population, not the hidden default one, so you can explicitly reference/loop through them);
something horrible and hacky like adding a very-small-timeout Delay block before entering a Service block (possibly within RestrictedAreaStart / Ends to ensure that agents don't make it into the Delay, and hence the Service block's seize mechanism, until you want them to).
In general, it makes sense to put the resources-needed calculation in a function (which returns an int and takes the agent as an argument) which you call in the "Number of units" expression. That way you can make the calculation as complex as you like; it would seem you might need a more complex consideration than just "grab everyone" (e.g., perhaps depending on the stream of to-arrive agents if you have knowledge of them, etc.). Maybe, for example, you'd also want to hold your arriving agents in a Wait block beforehand and only release them when the number of resources you want are available. (You'd need to give more precise detail about your requirements to be any more definite here.)
For the variable delay time, have an appropriate dynamic expression for the delay time; you can use the resourceUnits() function to get a list of the resource units seized by your agent. So, in the simplest case (decreases multiplicatively according to the number of resources) it would be something like 10.0 / agent.resourceUnits().size() (for a base delay of 10 time units).

How to use resources dynamically in anylogic?

I'm doing a simulation of an industry in Anylogic. It consists of three equal production lines, they all have the same number of processes (in the case services) and each service has a Resource attached (aka. a Machine). The products that are produced in the three lines will only be joined together in the end (at the final stock before delivery).
However, my last process of each line can have an increase or decrease in resources (machines) when needed. For example, line 1 had a machine failure and stopped for some time and now instead of needing 4 machines to complete the order it will need 6.
In addition, if one of this machines placed in this process breaks (because of a failure), I need the service to keep working but with less resources. So, for example, I have 4 machines in the last process of line 1, one of these machines had a break down, I would like the other 3 to keep producing.
Which possible solution can be used for this? I tried to simulate this in the service itself but it doesn't work with less resources then specified.
From what I understood I think you need to model the three lines separately and use three different resourcePools for your machines. Doing this you will have control over the resource capacity on every line and can change them based on any events. If your question is about how to change capacity of one line when another line fails, I suggest using the "send to flowchart" option in resource failure and you can use flowchart blocks to change capacities and execute any other code necessary.
If your 3 lines are identical, you can create a custom flowchart block and pass the resourcePool as a parameter to the custom block.This way you don't have to replicate your logic three times.

Least load scheduler

I'm working on a system that uses several hundreds of workers in parallel (physical devices evaluating small tasks). Some workers are faster than others so I was wondering what the easiest way to load balance tasks on them without a priori knowledge of their speed.
I was thinking about keeping track of the number of tasks a worker is currently working on with a simple counter and then sorting the list to get the worker with the lowest active task count. This way slow workers would get some tasks but not slow down the whole system. The reason I'm asking is that the current round-robin method is causing hold up with some really slow workers (100 times slower than others) that keep accumulating tasks and blocking new tasks.
It should be a simple matter of sorting the list according to the current number of active tasks, but since I would be sorting the list several times a second (average work time per task is below 25ms) I fear that this might be a major bottleneck. So is there a simple version of getting the worker with the lowest task count without having to sort over and over again.
EDIT: The tasks are pushed to the workers via an open TCP connection. Since the dependencies between the tasks are rather complex (exclusive resource usage) let's say that all tasks are assigned to start with. As soon as a task returns from the worker all tasks that are no longer blocked are queued, and a new task is pushed to the worker. The work queue will never be empty.
How about this system:
Worker reaches the end of its task queue
Worker requests more tasks from load balancer
Load balancer assigns N tasks (where N is probably more than 1, perhaps 20 - 50 if these tasks are very small).
In this system, since you are assigning new tasks when the workers are actually done, you don't have to guess at how long the remaining tasks will take.
I think that you need to provide more information about the system:
How do you get a task to a worker? Does the worker request it or does it get pushed?
How do you know if a worker is out of work, or even how much work is it doing?
How are the physical devices modeled?
What you want to do is avoid tracking anything and find a more passive way to distribute the work.