Anylogic: Measuring process time without considering waiting time during evening - simulation

I have created a discrete simulation model for our production processes in which the capacity, output, etc. should be simulated for the coming year. The model works, but I have a problem with measuring the process time. Our production only works from 7 a.m. to 3 p.m. Is there a way to set the TimeMeasureStart and TimeMeasureEnd block so that the time is only measured during the shift?
As a simplified example with a TimeMeasureStart, a service and a TimeMeasureEnd block:
The agent passes TimeMeasureStart at 2:30 p.m. and immediately enters the service block. The service time is 2 hours. The worker starts the service and goes home at 3:00 p.m. The agent waits in the service block from 3:00 p.m. to 7:00 a.m. At 7 a.m. the worker continues the service (until 8:30 a.m.). As soon as it is finished, the agent passes the TimeMeasureEnd block. The result is currently a process time of 18 hours. However, I only want to measure the time that is worked, so that I get 2 hours as the process time.
Is there a possibility to set / program the TimeMeasureStart / TimeMeasureEnd blocks accordingly so that the waiting time is not included?

My first suggestion would be to ensure that you really need calendar time, why not just run the model in hours and every hour is a working hour... then you don't need to shift schedule.
But often for reporting or having different shift patterns within your model requires you to need calendar time as the basis.
Here is a simple solution: Simply record the time a resource was seized through your own local variables.
You need to add two double variables to your agent 1 for last start and 1 for the cumulative time
previousServiceStart and cummServiceTime
and then save the times in the resource pool using the On seize and On release code
I casted the agent to my custom agent using the (MyAgent)agent code, so that I can access the variables

Related

suspend(agent) is not working in AnyLogic

I have a SERVICE block which i want to stop working for two hours when 10th agent enter the service.
So I used agent suspend and resume function for that. The image of implementation is given below.
MyDynamicEvent Properties section:
Now when i run the model and 10th agent enter the SERVICE, traceln("reparing") gets print on console but MyDynamicEvent does not work which means SERVICE block does not stop working and agents keep passing the SERVICE block. It suppose to stop for 2 hours when 10th agent enters the service.
You understand Dynamic Events wrong. In your code, you are creating the DE when the 10th agent enters, but you schedule it to start 2 hrs later. So it will trigger, but 2 hrs after the 10th agent arrived.
So the problem does not lie with the DE, but with the self.suspend(), imo

Can interarrival time be used with anylogic schedule block?

I'm trying to model a production sequence in anylogic where orders should come in with an interarrival time of normal(8,105) seconds. These orders should come in every week day between 11 am and 2 pm (3 hour window).
I tried to implement this with the Schedule block in anylogic but this only allows me to define a rate per hour. Is there a way to do this with interarrival time?
Also the agents that arrive at 1:59 pm should also be processed even if it takes until after 2 pm. Is there a way to calculate the mean working time per day (the time from the generation of the first agent by the source block until the last generated agent enters the sink block)?
Thank you all in advance!
I would use the getHour() function and dispose of the agents if hour is not between 11 and 14. And inside the source you don't need to do anything special. If it even arrives at 11.59 pm it will be processed.

Remove stop times from ResourcePool for OEE calculations [duplicate]

I am working on production model where the the input of raw material is on hourly bases and i am running the model for 8 hours ( 1 shift ) so basically for 16 hour the resources are idle. When i was not using the schedule part and running the model for 8 *7 hours ( 56 hours) then the time measurement for each job is fine but now when i schedule the output it include the idle time also. So How can i only calculate the busy time to see the average time spent by a job in a workshop ( from raw material to finish good.
This the time spent by a job in a process it should be 34-16= approx 18
Firstly, one note: although you state that you run 8 hour shifts, the 8 AM to 6 PM time period is actually 10 hours so I will ignore it in this solution and instead assume that the shifts are actually 8 hours and run from 9:00 to 17:00.
Here is a simple model that was used to test (model time unit is SECONDS):
There are 4 elements to make this work:
Service must be configure to allow pre-emption of tasks with recovery this is done by using Priorities / preemption options as below:
ResourcePool must be configure for 'End of Shift' preemption as shown below:
Calculations of true time (excluding dead time between shifts) is done in f_calcTATsec function:
// get 'Service' enter time for that agent
double startTime = col_startTimesSec.get(_agent);
// calculate time spent
double timeSpent = time() - startTime;
traceln("%.2f: agent spent %.2f in service", time(), timeSpent);
traceln("%.2f: 8hrs is %.2f, 16hrs is %.2f",
time(), (8 * hour()), (16 * hour()));
// below is a ternary statement which says:
// if 'timeSpent' is less than 8 hrs then use it
// otherwise
// exclude whole 16 hr periods (can be more than 1)
// and use the remainder
double trueTimeSpent = timeSpent <= (8 * hour()) ?
timeSpent :
timeSpent % (16 * hour());
// return time spent
traceln("%.2f: returning %.2f", time(), trueTimeSpent);
return trueTimeSpent;
Service object needs to be configured to record entry time for each Agent in col_startTimeSec collection and then call f_calcTATsec() function on exit, i.e. On enter = col_startTimesSec.put(agent, time()); and On exit = double trueTimeSpentSec = f_calcTATsec(agent);
When i was not using the schedule part and running the model for 8 *7 hours ( 56 hours) then the time measurement for each job is fine but now when i schedule the output it include the idle time also
So I assume you were using TimeMeasureStart/End blocks to do the time-in-system measurement. They just calculate the elapsed time from the start block to the end block, and so can never account for 'time that shouldn't count'. You don't have to use these blocks to calculate timings; typically you store relevant start times in the (custom) agent type flowing through the process and then calculate the relevant elapsed times as needed (e.g., at on-exit of a Service block, pseudo-code is "current time - time-on-entry = elapsed time in block").
Firstly though, you need to be clearer about what metric you're calculating and why. You want to exclude time where an in-progress (presumably pre-empted) job waits for the resource to return on-shift. But what about jobs which are queueing for a resource which then goes off-shift? What about if there are multiple possible resources that can be used with different shift patterns? What about the more general waiting of jobs for resources (when resources are on-shift)?
It sounds like what you may really want is both
The elapsed time spent working on a job (cf. waiting for anything).
The elapsed time jobs spend waiting for something (typically resources in a Seize/Service block — not just when tasks are pre-empted by shift-end — but could be other wait mechanisms, such as using Wait blocks).
The latter is just the total elapsed time minus the former.
So there are multiple ways to tackle this. Probably the easiest is to retain your overall elapsed time (via TimeMeasureStart/End blocks) and then calculate the working time separately: store it as a variable in the job agent and add to it in each block where it has 'work done to it' (e.g., for Service blocks without pre-emption use duration from on-seize to on-exit, for Delay blocks use duration from on-enter to on-exit).
To handle where a shift-end-pre-empted task waits for a resource to return on-shift you can use the Service block's "On task suspended" and "On task resumed" actions which trigger when a task is suspended (due to pre-emption) or resumed (when the original resource becomes available if that's the preemption option you chose).
This requires an extra variable to store the "current duration start time".
To be explicit:
Type double Variable cumulativeWorkingTimeMins in your Job agent type
Type double Vriable currentWorkStartTimeMins in your Job agent type
...and for a Service block (handling the pre-emption case)
'On seize unit' (or 'On enter delay') action of agent.currentWorkStartTimeMins = time(MINUTE);
'On task suspended' action of agent.cumulativeWorkingTimeMins += (time(MINUTE) - agent.currentWorkStartTimeMins);
'On task resumed' action of agent.currentWorkStartTimeMins = time(MINUTE);
'On exit' action of agent.cumulativeWorkingTimeMins += (time(MINUTE) - agent.currentWorkStartTimeMins);
[Note units specified in variable names to be clear, and explicit specification of units when getting the current time; this ensures the code is robust to changing your model time unit.]
NB: If you really wanted to just subtract the time pre-empted jobs are waiting for off-shift resources to return (and no other waiting time) — which doesn't seem to make sense as a metric — you can still do that using a variant of the above which just captures that waiting time.
(You'll also need to store the relevant final numbers in some HistogramData element or similar when the job finishes to be able to then show this data in charts: the TimeMeasureEnd blocks automatically capture this histogram data in their distribution variable but, when calculating timings yourself, you need to store data yourself for charts.)

Time Distribution and time spent in process in anylogic

I am working on production model where the the input of raw material is on hourly bases and i am running the model for 8 hours ( 1 shift ) so basically for 16 hour the resources are idle. When i was not using the schedule part and running the model for 8 *7 hours ( 56 hours) then the time measurement for each job is fine but now when i schedule the output it include the idle time also. So How can i only calculate the busy time to see the average time spent by a job in a workshop ( from raw material to finish good.
This the time spent by a job in a process it should be 34-16= approx 18
Firstly, one note: although you state that you run 8 hour shifts, the 8 AM to 6 PM time period is actually 10 hours so I will ignore it in this solution and instead assume that the shifts are actually 8 hours and run from 9:00 to 17:00.
Here is a simple model that was used to test (model time unit is SECONDS):
There are 4 elements to make this work:
Service must be configure to allow pre-emption of tasks with recovery this is done by using Priorities / preemption options as below:
ResourcePool must be configure for 'End of Shift' preemption as shown below:
Calculations of true time (excluding dead time between shifts) is done in f_calcTATsec function:
// get 'Service' enter time for that agent
double startTime = col_startTimesSec.get(_agent);
// calculate time spent
double timeSpent = time() - startTime;
traceln("%.2f: agent spent %.2f in service", time(), timeSpent);
traceln("%.2f: 8hrs is %.2f, 16hrs is %.2f",
time(), (8 * hour()), (16 * hour()));
// below is a ternary statement which says:
// if 'timeSpent' is less than 8 hrs then use it
// otherwise
// exclude whole 16 hr periods (can be more than 1)
// and use the remainder
double trueTimeSpent = timeSpent <= (8 * hour()) ?
timeSpent :
timeSpent % (16 * hour());
// return time spent
traceln("%.2f: returning %.2f", time(), trueTimeSpent);
return trueTimeSpent;
Service object needs to be configured to record entry time for each Agent in col_startTimeSec collection and then call f_calcTATsec() function on exit, i.e. On enter = col_startTimesSec.put(agent, time()); and On exit = double trueTimeSpentSec = f_calcTATsec(agent);
When i was not using the schedule part and running the model for 8 *7 hours ( 56 hours) then the time measurement for each job is fine but now when i schedule the output it include the idle time also
So I assume you were using TimeMeasureStart/End blocks to do the time-in-system measurement. They just calculate the elapsed time from the start block to the end block, and so can never account for 'time that shouldn't count'. You don't have to use these blocks to calculate timings; typically you store relevant start times in the (custom) agent type flowing through the process and then calculate the relevant elapsed times as needed (e.g., at on-exit of a Service block, pseudo-code is "current time - time-on-entry = elapsed time in block").
Firstly though, you need to be clearer about what metric you're calculating and why. You want to exclude time where an in-progress (presumably pre-empted) job waits for the resource to return on-shift. But what about jobs which are queueing for a resource which then goes off-shift? What about if there are multiple possible resources that can be used with different shift patterns? What about the more general waiting of jobs for resources (when resources are on-shift)?
It sounds like what you may really want is both
The elapsed time spent working on a job (cf. waiting for anything).
The elapsed time jobs spend waiting for something (typically resources in a Seize/Service block — not just when tasks are pre-empted by shift-end — but could be other wait mechanisms, such as using Wait blocks).
The latter is just the total elapsed time minus the former.
So there are multiple ways to tackle this. Probably the easiest is to retain your overall elapsed time (via TimeMeasureStart/End blocks) and then calculate the working time separately: store it as a variable in the job agent and add to it in each block where it has 'work done to it' (e.g., for Service blocks without pre-emption use duration from on-seize to on-exit, for Delay blocks use duration from on-enter to on-exit).
To handle where a shift-end-pre-empted task waits for a resource to return on-shift you can use the Service block's "On task suspended" and "On task resumed" actions which trigger when a task is suspended (due to pre-emption) or resumed (when the original resource becomes available if that's the preemption option you chose).
This requires an extra variable to store the "current duration start time".
To be explicit:
Type double Variable cumulativeWorkingTimeMins in your Job agent type
Type double Vriable currentWorkStartTimeMins in your Job agent type
...and for a Service block (handling the pre-emption case)
'On seize unit' (or 'On enter delay') action of agent.currentWorkStartTimeMins = time(MINUTE);
'On task suspended' action of agent.cumulativeWorkingTimeMins += (time(MINUTE) - agent.currentWorkStartTimeMins);
'On task resumed' action of agent.currentWorkStartTimeMins = time(MINUTE);
'On exit' action of agent.cumulativeWorkingTimeMins += (time(MINUTE) - agent.currentWorkStartTimeMins);
[Note units specified in variable names to be clear, and explicit specification of units when getting the current time; this ensures the code is robust to changing your model time unit.]
NB: If you really wanted to just subtract the time pre-empted jobs are waiting for off-shift resources to return (and no other waiting time) — which doesn't seem to make sense as a metric — you can still do that using a variant of the above which just captures that waiting time.
(You'll also need to store the relevant final numbers in some HistogramData element or similar when the job finishes to be able to then show this data in charts: the TimeMeasureEnd blocks automatically capture this histogram data in their distribution variable but, when calculating timings yourself, you need to store data yourself for charts.)

Getting END_MISS notification when my Job Status - WAITING state

I have set sla-nominal time as ${coord:nominalTime()}, so my sla starts calculating taking coordinator triggering time as the start time for sla calculations.
But the problem is I have many workflows running on my cluster and my workflow goes to waiting state if no memory on the cluster.
eg: for a particular workflow my coordinator start time is 2.00 pm but due to memory issue it goes to waiting state and workflow get triggered at say 5 pm, and if my sla duration is 2 hrs. this condition is already crossed so I get end_miss notification when my job is in still waiting state.
So is there any way I can give actual workflow triggering time as sla nominal time instead of coordinator nominal-time. so that sla starts calculating when my process actually started running and not when in waiting state.