Staff Scheduling: Missing Blocked Days/Shifts In Output

by Alex Johnson 56 views

When dealing with staff scheduling, accurately representing employee availability is crucial. This article addresses a bug in the process-solution command of a staff scheduling system where blocked_days and blocked_shifts information is lost during the solution processing, impacting the accuracy and usability of the final output. Let's dive into the details of this issue, how to reproduce it, and the expected behavior for a robust staff scheduling system.

Description

The process-solution command in question is designed to take the output from a staff scheduling solver and transform it into a usable format, typically a JSON file. Ideally, this JSON would contain all relevant information about the solution, including employee assignments, shift details, and any constraints that were considered during the optimization process. However, a critical flaw exists: the command doesn't propagate information about blocked days and blocked shifts from the initial input configuration to the final solution output file. This means that information about employee unavailability due to health reasons, family obligations, or other personal restrictions is lost during processing. While soft constraints like wish_days and wish_shifts are correctly mapped to the wishes object in the output, the corresponding "blocked" parameters, which represent hard constraints, are dropped. This discrepancy leads to an incomplete and potentially inaccurate representation of the schedule, hindering effective staff management and resource allocation.

Data Structures

To understand the scope of the problem, let's examine the relevant data structures involved in the staff scheduling process:

1. Input (whishes_and_blocked.json)

The input file, typically named whishes_and_blocked.json, serves as the foundation for the staff scheduling solution. It contains comprehensive information about employees, their preferences, and their availability. Crucially, it includes both desired days/shifts off (wish_days, wish_shifts) and unavailable days/shifts (blocked_days, blocked_shifts).

{
  "employees": [               // List of all employees
    {
      "key": "int",            // Internal primary key ID
      "firstname": "string",   // First name of the employee
      "name": "string",        // Last name of the employee
      "blocked_days": ["int"], // Unavailable days due to health reasons, family-related restrictions or personal unavailability
      "blocked_shifts": [      // Unavailable shifts due to health reasons, family-related
        ["int", "string"]      // restrictions or personal unavailability
      ],
      "wish_days": ["int"],    // Days that employee wishes to get off or avoid
      "wish_shifts": [         // Shifts that employee wishes to get off or avoid
        ["int", "string"]
      ]
    }
  ]
}

As you can see, the employees array contains a list of employee objects. Each employee object includes key information such as key, firstname, and name. More importantly, it contains two arrays that define employee availability: blocked_days and blocked_shifts. These arrays specify the days and shifts on which an employee is absolutely unavailable, typically due to health reasons or other unavoidable conflicts. In contrast, the wish_days and wish_shifts arrays represent employee preferences, indicating days or shifts they would prefer to have off, but are not necessarily unavailable.

2. Output (Current Behavior)

Unfortunately, the current behavior of the process-solution command results in the loss of the critical blocked_days and blocked_shifts information. After running the processing command, the employee objects in the solution file lack this vital unavailability data.

{
 "solution": {
   //...,
   "employees": [
    {
	 "id": 459,
	 "name": "Sandra Shoemake",
	 "level": "Fachkraft",
	 "target_working_time": 7680,
	 "wishes": {
	  "shift_wishes": [],
	  "day_off_wishes": []
	 }
	},
	// ...
   ],
   // ...
  }
}

Notice how the output JSON includes information like employee id, name, level, and target_working_time. It also includes a wishes object, which correctly captures the shift_wishes and day_off_wishes from the input. However, the blocked_days and blocked_shifts information is conspicuously absent. This omission means that the final solution file doesn't accurately reflect employee unavailability, potentially leading to scheduling conflicts and inefficiencies. This is a significant problem because it undermines the purpose of the scheduling system, which is to create feasible and efficient schedules that respect employee constraints.

Steps to Reproduce

Reproducing this bug is straightforward. By following these steps, you can easily verify the issue:

  1. Prepare the Input File: Ensure that your whishes_and_blocked.json file contains employees with populated blocked_days and/or blocked_shifts arrays. This is the starting point for the scheduling process, and the input file must accurately reflect employee unavailability.
  2. Start the Staff Scheduling Solver: Execute the staff scheduling solver using the following command:
    uv run staff-scheduling solve 3 01.11.2024 30.11.2024
    
    This command initiates the scheduling process, specifying parameters such as the number of solutions to generate (3 in this case) and the date range for the schedule (November 1, 2024, to November 30, 2024). The exact syntax and available options may vary depending on the specific staff scheduling system being used.
  3. Run the Solution Processing Command: Once the solver has generated a solution, run the process-solution command to transform the raw solution data into a usable JSON format. Use the following command:
    uv run staff-scheduling process-solution 3 --filename solution_3_2024-11-01-2024-11-30_0
    
    This command processes the solution file (e.g., solution_3_2024-11-01-2024-11-30_0) and generates the output JSON file. The --filename option specifies the name of the solution file to process. The number 3 refers to the solution ID.
  4. Inspect the Generated Output File: Carefully examine the generated output JSON file. Specifically, look for the employee objects and check whether they contain the blocked_days and blocked_shifts information. As you'll observe, this information is missing, confirming the presence of the bug.

Expected Behavior

The expected behavior of the process-solution command is to preserve all relevant information from the input configuration in the output JSON file. This includes, but is not limited to, the blocked_days and blocked_shifts information. The output JSON should accurately reflect employee unavailability, ensuring that the scheduling solution respects these hard constraints. The blocked objectives should be included, either at the root of the employee object or within a dedicated container (e.g., constraints or merged into wishes if appropriate for the data model), ensuring that unavailability data is preserved for the frontend or downstream reporting.

There are several ways to achieve this:

  • Option 1: Add blocked_days and blocked_shifts to the Employee Object: The simplest approach would be to directly include the blocked_days and blocked_shifts arrays in the employee object in the output JSON. This would maintain a clear and consistent structure, making it easy to access this information.

  • Option 2: Create a constraints Object: A more structured approach would be to create a dedicated constraints object within each employee object. This constraints object would then contain the blocked_days and blocked_shifts arrays, along with any other constraints that apply to the employee. This approach would provide a clear separation of concerns and make it easier to manage complex constraints.

  • Option 3: Merge with wishes (If Appropriate): Depending on the data model, it might be appropriate to merge the blocked_days and blocked_shifts information into the existing wishes object. However, it's important to clearly distinguish between wishes (soft constraints) and blocked days/shifts (hard constraints). This could be achieved by adding a type field to each wish, indicating whether it's a wish or a block.

Regardless of the chosen approach, the key is to ensure that the blocked_days and blocked_shifts information is preserved in the output JSON file. This is essential for creating accurate and feasible staff schedules.

In conclusion, the missing blocked_days and blocked_shifts information in the process-solution output JSON is a critical bug that needs to be addressed. By understanding the data structures, reproducing the issue, and implementing the expected behavior, developers can ensure that the staff scheduling system generates accurate and usable solutions.

For more information on staff scheduling best practices, visit SHRM.