Optaplanner - How to model a timeslot pattern scheduling problem if certain type of tasks require less resource when they're scheduled in same slot? - optaplanner

I'm developing a daily timeslot pattern scheduling problem with task precedence and daily shifts resource constaint.
Each product has several batches and each batch consists of sequential tasks (like prepare\mix\process etc.) to be scheduled.
Tasks consume shift units and there are daily shift limits for each type of tasks.
If two prepare tasks of same product are schedued on the same day, they consume 1 units of shift together, while each of them still use 1 shift unit if they are scheduled apart.
Succeeding tasks (like mix or process) of same products won't benefit from scheduling together on the same day. If one mix task use 1 shift unit, then two mix tasks scheduled on the same day would consume 2 shift unit in total.
This senario differs from project job scheduling problem, where task durations variation depend on machines, not other tasks.
I've implemented a simple model without changeable resource requirement and it works. I came up with a dummy idea: manually combine each two prepare tasks together and consider it as one task. But this would make the model less versatile and harder to write drool rules.
Any hint or help is appreciated. Thanks.

I solved this by using a shadow variable "modifiedProcessTime" in planning entity and updated by a Custom VariableListener when two or more tasks from same product same type are scheduled on the same day. The first task remains its original processing time, while other task are set to be zero.

Related

What kind of problem is this? Is feasible with optaplanner?

I have to solve a problem on a manufacturing environment where:
A number of processes with subtasks needs to be scheduled.
Each subtask need N resources that can be, raw material, workers or machines.
Some subtasks need a worker with certain skills or from a department.
Workers are organized in shifts, so it may happen that on a shift certain skill may not be available. *
A machine can fit N pieces, depending on the piece size and the capacity of the machine. *
A machine may accept pieces of different types. *
Machines can be not available on a period as maintenances can happen.
If the next piece going to the machine is different from the previous one, a new task for maintenance needs to be inserted. *
If there is no raw material of certain category it can be manufactured, so a new process to manufacture that raw material needs to be inserted before the one that needs it. *
The processes can have a deadline.
Some raw materials can be partially consumed, so for example if we have 2L of painting, a subtask require 1L of that painting.
Is this a Job Shop or any variant problem? Is it possible to do with optaplanner? Are there too many constraints for the solver?
I know that the tasks scheduling and the requirements of each subtasks can be done, my biggest concern is with the ones that I have marked with *
Thank you in advance.
In the OptaPlanner docs, look for the Design Patterns chapter and read the section on how to design a good model and also the section on assigning to time (timeslot vs time grain vs chained).
These are 2 related video's:
https://www.youtube.com/watch?v=0uAoWU8m0pE
https://www.youtube.com/watch?v=Ew6pq9nJKog

Is it possible to treat tasks with controllable processing time?

I am wondering if it's possible to treat scheduling problems with tasks with the following property using Optaplanner. Instead of have a fixed duration of 1 hour we have a 1 hour-man, i.e if there is two employees working on that task, it could be done in 1/2 hour.
Otherwise, what are the other solvers that could be used ?
Model wise, the easy approach is to split up that 1 task into 2 smaller tasks that get individually assigned. (When they're both assigned to the same person, sequentially after each other, you can add a soft constraint to reward that.) The downside is that you have to decide in advance for each task into how many pieces they can be split up.
In reality, tasks are rarely arbitrary dividable. Some parts of each task are atomic. For example, taking out the garbage can is a do-or-do-not task. Taking it half the way out, or taking half of it out, and assigning someone else to do the rest, is not allowed because it will increase the time spent on it.
Some tasks need at least 2 persons to execution. For example, someone to hold the ladder while the other is standing on it. In the docs, see the auto delay to last pattern.
Alternatively to the simple model, you can also play with nullable=true and custom moves to allow multiple people to assign to the same tasks, but it's complicated. It can avoid having to tune the number of task pieces in advance too much. Once we support #PlanningVariableCollection, and do so fully, more and better options in this regard will become available.

Optaplanner VRP example, multiple vehicles required per stop in same time window

We are using a customized VRP tutorial example to optimize daily routes for service engineers who travel to customers in order to execute certain repair and installation tasks. We do have time windows and we optimize 1000+ tasks for multiple weeks into the future.
Our (simplified) domain model consists of:
Engineer - the guy doing all the work
Task - a single work assignmet at a certain location
DailyRoute - an Engineer's route for given day, consists of a linked list of Tasks
As a new requirement we must now support two engineers working in parallel on the same task.
Our current plan is to implement this by creating subtasks for the second engineer and implement a rule that their arrival time must be identical to the main task.
However, this is problematic since moving one of the interdependant tasks to a different time (e.g. a different DailyRoute) will mostly violate the above constraint.
So far, we have come up with the following ideas:
Allow single task moves only to a DailyRoute on the same day as the other task's assigned route
can be done via a SelectionFilter
Use CompositeMoves to move both of the parallel tasks at once to different days
Do we need a custom MoveIteratorFactory to select the connected tasks?
Or can this be done with a CartesianProductMoveSelector instead?
Can we use nearby selection for the second move to prefer the same day as the first move's newly assigned day (is move one already done at that time)?
For two engineers working in parallel on the same task, see docs "design patterns" specifically "the delay till last pattern". There is no example, but our support services have helped implemented it a few times - it works.
For the multiple stops at the same location: I've seen users split such visits up into smaller pieces to allow optaplanner to choose which of those pieces to aggregate. It works but it's not perfect: the more fine-grained the pieces, the much bigger the search space - the more that adding a custom move that focusses on moving all pieces together might help (but I won't start out with it). Generally speaking: if the smallest vehicle has a capacity of 100, I 'd run some experiments with splitting up to half that capacity - and they try a quarter too, just to see what works best through benchmarking with optaplanner-benchmark.

How should I handle measurement logging in my Discrete Event Simulation engine?

NOTE: This question has been ported over from Programmers since it appears to be more appropriate here given the limitation of the language I'm using (VBA), the availability of appropriate tags here and the specificity of the problem (on the inference that Programmers addresses more theoretical Computer Science questions).
I'm attempting to build a Discrete Event Simulation library by following this tutorial and fleshing it out. I am limited to using VBA, so "just switch to [insert language here] and it's easy!" is unfortunately not possible. I have specifically chosen to implement this in Access VBA to have a convenient location to store configuration information and metrics.
How should I handle logging metrics in my Discrete Event Simulation engine?
If you don't want/need background, skip to The Design or The Question section below...
Simulation
The goal of a simulation of the type in question is to model a process to perform analysis of it that wouldn't be feasible or cost-effective in reality.
The canonical example of a simulation of this kind is a Bank:
Customers enter the bank and get in line with a statistically distributed frequency
Tellers are available to handle customers from the front of the line one by one taking an amount of time with a modelable distribution
As the line grows longer, the number of tellers available may have to be increased or decreased based on business rules
You can break this down into generic objects:
Entity: These would be the customers
Generator: This object generates Entities according to a distribution
Queue: This object represents the line at the bank. They find much real world use in acting as a buffer between a source of customers and a limited service.
Activity: This is a representation of the work done by a teller. It generally processes Entities from a Queue
Discrete Event Simulation
Instead of a continuous tick by tick simulation such as one might do with physical systems, a "Discrete Event" Simulation is a recognition that in many systems only critical events require process and the rest of the time nothing important to the state of the system is happening.
In the case of the Bank, critical events might be a customer entering the line, a teller becoming available, the manager deciding whether or not to open a new teller window, etc.
In a Discrete Event Simulation, the flow of time is kept by maintaining a Priority Queue of Events instead of an explicit clock. Time is incremented by popping the next event in chronological order (the minimum event time) off the queue and processing as necessary.
The Design
I've got a Priority Queue implemented as a Min Heap for now.
In order for the objects of the simulation to be processed as events, they implement an ISimulationEvent interface that provides an EventTime property and an Execute method. Those together mean the Priority Queue can schedule the events, then Execute them one at a time in the correct order and increment the simulation clock appropriately.
The simulation engine is a basic event loop that pops the next event and Executes it until there are none left. An event can reschedule itself to occur again or allow itself to go idle. For example, when a Generator is Executed it creates an Entity and then reschedules itself for the generation of the next Entity at some point in the future.
The Question
How should I handle logging metrics in my Discrete Event Simulation engine?
In the midst of this simulation, it is necessary to take metrics. How long are Entities waiting in the Queue? How many Acitivity resources are being utilized at any one point? How many Entities were generated since the last metrics were logged?
It follows logically that the metric logging should be scheduled as an event to take place every few units of time in the simulation.
The difficulty is that this ends up being a cross-cutting concern: metrics may need to be taken of Generators or Queues or Activities or even Entities. Consider also that it might be necessary to take derivative calculated metrics: e.g. measure a, b, c, and ((a-c)/100) + Log(b).
I'm thinking there are a few main ways to go:
Have a single, global Stats object that is aware of all of the simulation objects. Have the Generator/Queue/Activity/Entity objects store their properties in an associative array so that they can be referred to at runtime (VBA doesn't support much in the way of reflection). This way the statistics can be attached as needed Stats.AddStats(Object, Properties). This wouldn't support calculated metrics easily unless they are built into each object class as properties somehow.
Have a single, global Stats object that is aware of all of the simulation objects. Create some sort of ISimStats interface for the Generator/Queue/Activity/Entity classes to implement that returns an associative array of the important stats for that particular object. This would also allow runtime attachment, Stats.AddStats(ISimStats). The calculated metrics would have to be hardcoded in the straightforward implementation of this option.
Have multiple Stats objects, one per Generator/Queue/Activity/Entity as a child object. This might make it easier to implement simulation object-specific calculated metrics, but clogs up the Priority Queue a little bit with extra things to schedule. It might also cause tighter coupling, which is bad :(.
Some combination of the above or completely different solution I haven't thought of?
Let me know if I can provide more (or less) detail to clarify my question!
Any and every performance metric is a function of the model's state. The only time the state changes in a discrete event simulation is when an event occurs, so events are the only time you have to update your metrics. If you have enough storage, you can log every event, its time, and the state variables which got updated, and retrospectively construct any performance metric you want. If storage is an issue you can calculate some performance measures within the events that affect those measures. For instance, the appropriate time to calculate delay in queue is when a customer begins service (assuming you tagged each customer object with its arrival time). For delay in system it's when the customer ends service. If you want average delays, you can update the averages in those events. When somebody arrives, the size of the queue gets incremented, then they begin service it gets decremented. Etc., etc., etc.
You'll have to be careful calculating statistics such as average queue length, because you have to weight the queue lengths by the amount of time you were in that state: Avg(queue_length) = (1/T) integral[queue_length(t) dt]. Since the queue_length can only change at events, this actually boils down to summing the queue lengths multiplied by the amount of time you were at that length, then divide by total elapsed time.

Compare Round Robin and Multilevel Feedback Queue in terms of waiting time, response time, turnaround time

I want to make a comparison between RR and MLFQ in terms of waiting time, response time, turnaround time in 3 cases:
a) More CPU-bounded jobs than I/O
jobs
b) More I/O-bounded jobs than
CPU bounded jobs
c) When only a few
jobs need to schedule.
Could you help me to clarify or give me some sources for reference. Thanks a lot
There's some maths for this called "queueing theory", which can give you some equations to use.
Another way is to develop a simulation (software model) of the queue, and measure things (e.g. the distribution of response times) as you change various parameters (e.g. utilization).
The important thing to decide is the distribution of inter-arrival times of the input events (jobs to be processed): if they arrive regularly then there may be typically no queueing delay at all (assuming the system utilization is less than 100%), but if they arrive randomly (e.g. with a Poisson distribution) then there's (on average) a non-zero queue.