AnyLogic Model- Patient Scheduling Project - anylogic

I am currently working on a project to model outpatient appointment scheduling for a local hospital. The goal of this project is to model their current situation and then adjust different factors to reduce the wait time until the next available appointment. We are using AnyLogic to create the model. At this hospital the current system is as follows:
A patient calls and schedules an appointment with one of the hospitals 19 sub-specialties.
         - appointment will either be a first time consultation lasting 1 hour or a follow up appointment lasting 15 minutes.
Patient waits 1 week-6 months until their appointment date (based on sub-specialty)
Patient is seen by a doctor and then exits the system
We have approached the problem in two ways, the first was to attach the schedule to the resource pool which consists of the doctors for a single sub specialty. This would allow the schedule to change as the number of doctors change. The second approach was to attach the schedule to the source which consists of the patients entering the system. This better controls the flow of individuals into the system.
We are having difficulties figuring out how to configure the model so that it accurately shows the result of adding more doctors while still allowing the flexibility we need in scheduling different length appointments in multiple sub-specialties.
If anyone has experience with AnyLogic Scheduling, has dealt with a similar problem, or has any advice on how to proceed, I would appreciate the input.
Thanks!

If I understand correctly, you want to change the number of resources you have according to a certain schedule...
In the schedule you need to you use integer type and then create your schedule based however you want. In the action you can use "value" as a variable that corresponds to the value of the current schedule value. The action in the schedule is activated everytime the schedule changes... so you can simply do resourcePool.set_capacity(value);
With this you have the flexibility to use different length appointments... You can use one different schedule for each sub-specialty

Related

AnyLogic - modeling large number of different ResourcePools

I would like to model a larger number of employees (about 30) as a resource pool. Each employee is given parameters before the model starts, which the simulation end user can enter manually. Each employee has different working hours (shift work, different on each day of the week), different duration of the shift and different tasks assigned to them.
My first thought was to model each employee individually as a resource with their own shift schedule. That would be easiest, but I bet there is a nicer solution - anyone have any ideas?
If your workers have different settings such as different shift hours, they will not belong to the same ResourcePool.
You must build an agent that contains a ResourcePool (so that you can use it as a resource) with its another parameters such as capacity etc.
In my opinion, the most correct thing is to build a Population of them. Each item in the population is an amount of workers with identical parameters.

Anylogic ‘how to’ questions

I am using Anylogic for a simulation-modeling class, and I am not anylogic or coding smart. My last and only coding class was MatLab based about 16 yrs ago. I have a few questions about how to implement modeling concepts in a discrete model with anylogic.
How can I add/inject agents directly into a queue downstream from a source? I have tried adding an additional source to use the “Calls of inject() function,” but I am not sure how to implement it after selecting it ( example: what do I do after selecting the Calls of inject() function). I have the new source feeding directly into the queue where I want the inject.
How can I set the release of an agent to a defined schedule instead of a rate? Currently, I have my working model set to interarrival time. But I would like to set the agent release to a defined schedule. (example: agent-1 released at 120 seconds, agent-2 released at 150 seconds, agent-3 released at 270 seconds)
Any help would be greatly appreciated, especially if it can be written in a “explain to me like I am 5yrs old” format.
Question 1:
If you have a source connected directly to a queue, then when you call source.inject() an agent will be created at the source block and go to the queue. If you have 1 source with multiple possible destinations, then you will have to use select output blocks and some criteria to go from the source to the desired queue.
Since you mentioned not being a strong programmer, this probably wouldn't be for you, but I often find myself creating agents via add_population and then just adding them to an ArrayList until I am ready to pull them into the DES flow. Really, there are near infinite ways to control agent flow within AnyLogic.
Question 2:
Option a: Arrivals by "Arrival Table in Database" You can link an AnyLogic database table to Excel, and then the source block will just have an agent arrive based on that table.
Option b: Arrival Schedule - you could set this up manually within the development environment or load your schedule from a database. I prefer option a over option b given your brief description.
Option c: Read in data to variable and then write code to release based on next arrival time. 1,000s of ways to do this, but one example could be a list of doubles (your arrival times), set an event to delay until next arrival, call inject function, remove that arrival from the list. I think option a would be best for you, but given that AnyLogic allows you to add java code, there are no limits to how sophisticated you could make your arrival logic.
For 2) You could also use an event or a dynamic event. The action could be source.inject(1); and you can schedule them to your preferences with variables. Just be vigilant that you re-start the events if necessary.
There is a demo-model from AnyLogic for dynamic events.

Using the same service block for different tasks in anylogic

I am currently busy with a project at a hospital. I need to create a simulation model replicating the processes at the hospital. I have a problem with regards to one counter or service desk at the hospital. The staff member at the service desk needs to perform two different tasks, depending on the type of patient. How do I programme the service block to perform two different tasks?. For now,enter image description here I have split the block into two different blocks using the same staff member. Is there another way that I can go about this?
The staff member at the service desk needs to perform two different tasks, depending on the type of patient.
If the task only differs in duration, you can easily adjust the task duration by patient type in the Service delay property (assuming your patients are agents of types PatientType1 and PatientType2):
For more complex tasks, you can create a function that returns the duration and takes your requesting patient as an input argument, for example f_getDelayByPatient(MyPatientType patient)
Then, the service block can use that function in the "Delay time" code section to compute it for each arriving patient using f_getDelayByPatient(agent)

How to programmatically manage startWatch and stopWatch in an AnyLogic model

I'm building a model with AnyLogic using the Process Model Library (PML).
In my network I have 4 "source" elements that emits agents, they are all of the same type but with a different "category" string ID inside them (saved as a variable) to differentiate them; they are purchase order from different departments. I have also inserted blocks to measure the time the agents spend to exit from the assembler elements (you will see in the picture inside the red circles). This is the time that I will want to plot in a graph to show how fast they are.
After some test and reading the documentation I have see that when an agent pass under the start photocell (agent of any department) a timer is activated and the opposite when an agent (agent of any department) pass under the stop photocell the timer is stopped. Also in case of agent with different category IDs.
How can I synchronize the timers to measure time of object with the same category ID? I want that if the first source element "Category Nilo&Salmoni" produce an agent the stopWatch measure the time of this one and not of another one, emitted from another category, that reach the stopwatch first.

Reactive systems - Reacting to time passing

Let's say we have a reactive sales forecasting system.
Every time we make a sale we re-calculate our Forecast for future sales.
This works beautifully if there are lots of sales triggering our re-forecasting.
What happens however if sales go from 100 events per second, to 0. And stay 0 for a long time?
The forecast we published back when sales were good stays being the most up to date forecast.
How would you model in this situation an event that represents 'No sales happening' without falling back to some batch hourly/minutely/arbitrary time segment event that says 'X time has passed'.
This is a specific case of a generic question - How do you model time passing with nothing happening in an event based system - without using a ticking clock style event which would wake everyone up to reconsider their current values [an implementation which would not scale].
The only option I have considered that makes sense:
Every time we take a sale, we also schedule a deferred event 2 hours in the future that asks us to reconsider our assessment of that sale.
In handling that deferred event we may then choose to schedule further deferred events for re-considering.
Considering this is a very generic scenario, you've made a rather large assumption that it's not possible to come up with a design for re-evaluating past sales in a scalable way unless it's done one sale at a time.
There are many different scale related numbers in the scenario, and you're only looking at the one whereby a single scheduled forecast updater may attempt to process a very large number of past sales at the same time.
Other scalability issues I can think of:
Reevaluating the forecast for every single new sale doesn't sound great if you're expecting 100s of sales per second. If you're talking about a financial forecasting model for accounting, it's unlikely it needs to be updated every single time the organisation makes a sale, if the organisation is making hundreds of sales a second.
If you're talking about a short term predictive engine to be used for financial markets (ie predicting how much cash you'll need in the next 10 seconds, or energy, or other resources), then it sounds like you have constant volatility and you're not really likely to have a situation where nothing happens for hours. And if you do need forecasts updated very frequently, waiting a couple of hours before triggering a re-update is not likely to get you the kind of information you need in the way you need it.
With your approach, you will end up with one future scheduled event per product (which could be large), and every time you make a sale, you'll be dropping the old scheduled event and scheduling a new one. So for frequently selling products, you'll be doing repetitive work to constantly kick the can down the road a bit further, when you're not likely to ever get there.
What constitutes a good design is going to be based on the real scenario. The generic case is interesting to think about, but good designs need to be shaped to their circumstances.
Here are a few ideas I have that might be appropriate:
If you want an updated forecast per product when that product has a sale, but some products can sell very frequently, then a good approach may be to throttle or buffer the sales on a per product basis. If a product is selling 50 times a second, you can probably afford to wait 1 second, 10 seconds, 2 hours, whatever and evaluate all those sales at once, rather than re-forecasting 50 times a second. Especially if your forecasting process is heavy, doing it for every sale is likely to cause high load for low value, as the information will be outdated almost straight away by the next sale.
You could also have a generic timer that updates forecasts for all products that haven't sold in the last window, but handle the products in buffers. For example, every hour you could pick the 10 products with the oldest forecasts and update them. This prevents the single timer from taking on re-forecasting the entire product set in one hit.
You could use only the single timer approach above and forget the forecast updates on every sale if you want something dead simple.
If you're worried about load from batch forecasting, this kind of work should be done on different hardware from the ones handling sales.