Job Type Capacity Constraints

Job Type Capacity Constraints enable you to limit the number of specific job types that resources can perform within daily shifts, extended periods, and granular time blocks. This feature is essential for healthcare, field service, and other industries where resource specialization and workload limits are critical for operational safety and compliance.

Overview

Resources often have limitations on how many specialized tasks they can perform:
  • Healthcare: A nurse may only perform 3 wound care appointments per day
  • Field Service: A technician may handle only 2 complex installations per shift
  • Consulting: A specialist may conduct maximum 4 initial assessments in the morning
Job type constraints ensure these limits are respected during optimization while maintaining efficient scheduling.

Key Features

Multi-Level Constraints

Set limits at shift-level, period-level, and sub-shift time blocks

Multiple Job Types

Jobs can have multiple job types for flexible classification

Sub-Shift Periods

Different limits within portions of a shift (e.g., morning vs afternoon)

Flexible Limits

Unlimited capacity when no limits are specified

Basic Implementation

Job Type Assignment

Assign job types to jobs using the jobTypes field:
{
  "jobs": [
    {
      "name": "wound-care-patient-1",
      "jobTypes": ["Wound Care"],
      "duration": 1800,
      "location": {
        "lat": 50.8503,
        "lon": 4.3517
      }
    },
    {
      "name": "initial-assessment-patient-2", 
      "jobTypes": ["Initial Assessment"],
      "duration": 2700,
      "location": {
        "lat": 50.8566,
        "lon": 4.3517
      }
    },
    {
      "name": "complex-procedure-patient-3",
      "jobTypes": ["Initial Assessment", "Wound Care"],
      "duration": 3600,
      "location": {
        "lat": 50.8466,
        "lon": 4.3617
      }
    }
  ]
}
Jobs can have multiple job types. Each job type in the list counts toward the respective capacity limits.

Shift-Level Limits

Set daily limits for job types within individual shifts:
{
  "resources": [
    {
      "name": "nurse-specialist",
      "shifts": [
        {
          "start": "2024-01-15T08:00:00Z",
          "end": "2024-01-15T16:00:00Z",
          "jobTypeLimitations": {
            "Wound Care": 3,
            "Initial Assessment": 5,
            "Complex Procedure": 1
          }
        }
      ]
    }
  ]
}

Advanced Period-Based Constraints

Extended Period Limits

Set limits across multiple days or weeks using period rules:
{
  "resources": [
    {
      "name": "specialist-nurse",
      "rules": [
        {
          "period": {
            "from": "2024-01-15T00:00:00Z",
            "to": "2024-01-21T23:59:59Z"
          },
          "jobTypeLimitations": {
            "Complex Procedure": 8,
            "Initial Assessment": 20
          }
        }
      ],
      "shifts": [
        {
          "start": "2024-01-15T08:00:00Z",
          "end": "2024-01-15T16:00:00Z"
        },
        {
          "start": "2024-01-16T08:00:00Z", 
          "end": "2024-01-16T16:00:00Z"
        }
        // ... more shifts
      ]
    }
  ]
}

Sub-Shift Time Blocks

New Feature: Create different limits for specific time periods within a single shift
Perfect for scenarios like morning vs afternoon capacity differences:
{
  "resources": [
    {
      "name": "healthcare-worker",
      "rules": [
        {
          "period": {
            "from": "2024-01-15T08:00:00Z",
            "to": "2024-01-15T12:00:00Z"
          },
          "jobTypeLimitations": {
            "Initial Assessment": 3,
            "Wound Care": 2
          }
        },
        {
          "period": {
            "from": "2024-01-15T12:00:00Z", 
            "to": "2024-01-15T16:00:00Z"
          },
          "jobTypeLimitations": {
            "Initial Assessment": 2,
            "Wound Care": 1
          }
        }
      ],
      "shifts": [
        {
          "start": "2024-01-15T08:00:00Z",
          "end": "2024-01-15T16:00:00Z"
        }
      ]
    }
  ]
}

Use Cases by Industry

Healthcare

{
  "jobTypeLimitations": {
    "Wound Care": 4,
    "Initial Assessment": 6,
    "Medication Administration": 12,
    "Complex Procedure": 2
  }
}
Ensures nurses don’t exceed safe patient care limits

Field Service

{
  "jobTypeLimitations": {
    "Equipment Installation": 2,
    "Maintenance Check": 6,
    "Emergency Repair": 3,
    "Training Session": 1
  }
}
Balance complex work with routine maintenance

Constraint Behavior

Enforcement Logic

Job type constraints are enforced as hard constraints, meaning:
  • ✅ Solutions violating job type limits are considered infeasible
  • ⚠️ Jobs exceeding limits will be assigned to other resources or remain unassigned
  • 📊 Constraint violations appear in the explanation with JOBTYPE_VIOLATION

Overlapping Periods

When multiple period rules apply to the same time:
{
  "rules": [
    {
      "period": {
        "from": "2024-01-15T09:00:00Z",
        "to": "2024-01-15T15:00:00Z" 
      },
      "jobTypeLimitations": {
        "Initial Assessment": 4
      }
    },
    {
      "period": {
        "from": "2024-01-15T12:00:00Z",
        "to": "2024-01-15T18:00:00Z"
      },
      "jobTypeLimitations": {
        "Wound Care": 2
      }
    }
  ]
}
Jobs scheduled in the overlapping time (12:00-15:00) must respect both period rules.

Response and Explanation

Successful Assignment

{
  "trips": [
    {
      "resource": "nurse-specialist",
      "jobs": [
        {
          "name": "wound-care-1",
          "jobTypes": ["Wound Care"],
          "arrivalTime": "2024-01-15T09:00:00Z"
        },
        {
          "name": "initial-assessment-1", 
          "jobTypes": ["Initial Assessment"],
          "arrivalTime": "2024-01-15T10:30:00Z"
        }
      ]
    }
  ]
}

Constraint Violations

When job type limits are exceeded:
{
  "explanation": {
    "score": {
      "feasible": false,
      "hardScore": -100
    },
    "unresolved": [
      {
        "constraint": "JOBTYPE_VIOLATION",
        "score": "-100hard",
        "description": "Resource nurse-specialist exceeds Wound Care limit (3) in period 2024-01-15T08:00:00Z - 2024-01-15T16:00:00Z"
      }
    ]
  },
  "unserved": [
    {
      "name": "wound-care-4",
      "reason": "Job type capacity exceeded"
    }
  ]
}

Best Practices

Migration Guide

From Basic Scheduling

If you’re currently using basic job scheduling without job types:
  1. Identify Job Categories: Group your jobs by complexity or skill requirements
  2. Add Job Types: Start with 2-3 main categories
  3. Set Conservative Limits: Begin with higher limits and adjust downward
  4. Test Gradually: Roll out to a subset of resources first

API Changes

All job type fields are optional and backward compatible:
// Before - still works
{
  "jobs": [{"name": "job1", "duration": 1800}]
}

// After - enhanced with job types
{
  "jobs": [{"name": "job1", "duration": 1800, "jobTypes": ["Standard"]}]
}

Performance Considerations

  • Solver Impact: Minimal overhead (<2% in typical scenarios)
  • Memory Usage: Efficient array-based tracking
  • Scalability: Tested with 50+ job types and 100+ jobs per resource
  • Best Performance: Use 5-10 job types per resource for optimal performance
Job Type Capacity Constraints work seamlessly with other VRP features. They can be combined with capacity constraints, time windows, and priority settings for comprehensive scheduling control.