| name | production-scheduler |
| description | Production scheduling skill with sequencing rules, resource allocation, and schedule optimization. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"production-planning","backlog-id":"SK-IE-029"} |
| graph | {"domains":["domain:industrial-engineering"],"skillAreas":["skill-area:statistical-analysis","skill-area:organizational-design","skill-area:data-analysis"],"roles":["role:operations-analyst","role:research-engineer"]} |
production-scheduler
You are production-scheduler - a specialized skill for production scheduling including job sequencing, resource allocation, and schedule optimization.
Overview
This skill enables AI-powered production scheduling including:
- Job shop scheduling
- Flow shop scheduling
- Priority dispatch rules (SPT, EDD, CR, SLACK)
- Makespan minimization
- Tardiness minimization
- Resource-constrained scheduling
- Gantt chart generation
- Schedule performance metrics
Capabilities
1. Priority Dispatch Rules
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
def apply_dispatch_rules(jobs: pd.DataFrame, rule: str):
"""
Apply priority dispatch rules for job sequencing
jobs: DataFrame with columns ['job_id', 'processing_time', 'due_date', 'arrival_time']
rule: 'SPT', 'LPT', 'EDD', 'CR', 'SLACK', 'FCFS'
"""
jobs = jobs.copy()
current_time = jobs['arrival_time'].min()
if rule == 'SPT':
jobs['priority'] = jobs['processing_time']
sequence = jobs.sort_values('priority')
elif rule == 'LPT':
jobs['priority'] = -jobs['processing_time']
sequence = jobs.sort_values('priority')
elif rule == 'EDD':
jobs['priority'] = jobs['due_date']
sequence = jobs.sort_values('priority')
elif rule == 'CR':
jobs['time_remaining'] = (jobs['due_date'] - current_time).dt.total_seconds() / 3600
jobs['priority'] = jobs['time_remaining'] / jobs['processing_time']
jobs.loc[jobs['priority'] <= 0, 'priority'] = 0.001
sequence = jobs.sort_values('priority')
elif rule == 'SLACK':
jobs['time_remaining'] = (jobs['due_date'] - current_time).dt.total_seconds() / 3600
jobs['priority'] = jobs['time_remaining'] - jobs['processing_time']
sequence = jobs.sort_values('priority')
elif rule == 'FCFS':
sequence = jobs.sort_values('arrival_time')
return {
"rule": rule,
"sequence": sequence['job_id'].tolist(),
"jobs": sequence
}
2. Schedule Performance Metrics
def calculate_schedule_metrics(schedule: pd.DataFrame):
"""
Calculate comprehensive schedule performance metrics
schedule: DataFrame with ['job_id', 'start_time', 'end_time', 'due_date']
"""
schedule = schedule.copy()
schedule['completion_time'] = schedule['end_time']
schedule['lateness'] = (schedule['end_time'] - schedule['due_date']).dt.total_seconds() / 3600
schedule['tardiness'] = schedule['lateness'].apply(lambda x: max(0, x))
schedule['earliness'] = schedule['lateness'].apply(lambda x: abs(min(0, x)))
schedule['is_late'] = schedule['lateness'] > 0
metrics = {
'makespan': (schedule['end_time'].max() - schedule['start_time'].min()).total_seconds() / 3600,
'mean_flow_time': schedule['completion_time'].mean(),
'total_tardiness': schedule['tardiness'].sum(),
'max_tardiness': schedule['tardiness'].max(),
'number_tardy': schedule[].(),
: ( - schedule[].mean()) * ,
: schedule[].mean(),
: schedule[].()
}
{
: metrics,
: schedule
}
3. Job Shop Scheduling
from collections import defaultdict
def job_shop_schedule(jobs: list, machines: list):
"""
Job shop scheduling using dispatching rules
jobs: list of {'job_id': str, 'operations': [(machine, processing_time), ...], 'due_date': datetime}
machines: list of machine IDs
"""
machine_available = {m: 0 for m in machines}
job_completion = defaultdict(lambda: 0)
schedule = []
for job in jobs:
job_id = job['job_id']
prev_end = 0
for op_idx, (machine, proc_time) in enumerate(job['operations']):
start_time = max(machine_available[machine], prev_end)
end_time = start_time + proc_time
schedule.append({
'job_id': job_id,
'operation': op_idx + 1,
'machine': machine,
'start_time': start_time,
'end_time': end_time,
'processing_time': proc_time
})
machine_available[machine] = end_time
prev_end = end_time
job_completion[job_id] = prev_end
return {
"schedule": pd.DataFrame(schedule),
"makespan": max(job_completion.values()),
"machine_utilization": calculate_machine_utilization(schedule, machines)
}
():
makespan = (s[] s schedule)
utilization = {}
machine machines:
machine_ops = [s s schedule s[] == machine]
busy_time = (s[] s machine_ops)
utilization[machine] = busy_time / makespan * makespan >
utilization
4. Flow Shop Scheduling
def johnson_algorithm(jobs: list):
"""
Johnson's algorithm for 2-machine flow shop
Minimizes makespan
jobs: list of {'job_id': str, 'machine1_time': float, 'machine2_time': float}
"""
set_i = []
set_ii = []
for job in jobs:
if job['machine1_time'] <= job['machine2_time']:
set_i.append(job)
else:
set_ii.append(job)
set_i.sort(key=lambda x: x['machine1_time'])
set_ii.sort(key=lambda x: x['machine2_time'], reverse=True)
optimal_sequence = set_i + set_ii
m1_end = 0
m2_end = 0
schedule = []
for job in optimal_sequence:
m1_start = m1_end
m1_end = m1_start + job['machine1_time']
m2_start = max(m1_end, m2_end)
m2_end = m2_start + job['machine2_time']
schedule.append({
'job_id': job['job_id'],
'machine1_start': m1_start,
'machine1_end': m1_end,
'machine2_start': m2_start,
: m2_end
})
{
: [j[] j optimal_sequence],
: m2_end,
: schedule
}
5. Resource-Constrained Scheduling
def resource_constrained_schedule(tasks: list, resources: dict, dependencies: dict):
"""
Schedule tasks with resource constraints and dependencies
tasks: list of {'task_id': str, 'duration': float, 'resources': {resource: amount}}
resources: {resource: available_amount}
dependencies: {task_id: [predecessor_task_ids]}
"""
scheduled = {}
resource_timeline = {r: [] for r in resources}
remaining = set(t['task_id'] for t in tasks)
task_dict = {t['task_id']: t for t in tasks}
current_time = 0
max_time = 1000
while remaining and current_time < max_time:
eligible = []
for task_id in remaining:
predecessors = dependencies.get(task_id, [])
if all(p in scheduled for p in predecessors):
earliest = 0
for p in predecessors:
earliest = max(earliest, scheduled[p]['end_time'])
eligible.append((task_id, earliest))
for task_id, earliest in (eligible, key= x: x[]):
task = task_dict[task_id]
start_time = (earliest, current_time)
can_schedule =
resource, amount task.get(, {}).items():
amount > resources.get(resource, ):
can_schedule =
can_schedule:
end_time = start_time + task[]
scheduled[task_id] = {
: task_id,
: start_time,
: end_time,
: task[]
}
remaining.remove(task_id)
current_time +=
{
: (scheduled.values()),
: (s[] s scheduled.values()) scheduled ,
: (remaining)
}
6. Gantt Chart Generation
def generate_gantt_data(schedule: pd.DataFrame, group_by: str = 'machine'):
"""
Generate data for Gantt chart visualization
schedule: DataFrame with columns appropriate for group_by
group_by: 'machine' or 'job'
"""
gantt_data = []
for _, row in schedule.iterrows():
gantt_data.append({
'Task': row[group_by] if group_by in row else row.get('job_id', 'Unknown'),
'Start': row['start_time'],
'Finish': row['end_time'],
'Resource': row.get('job_id', row.get('machine', 'Unknown')),
'Duration': row['end_time'] - row['start_time']
})
return {
"gantt_data": gantt_data,
"timeline_start": min(g['Start'] for g in gantt_data),
"timeline_end": max(g['Finish'] for g in gantt_data),
"resources": list(set(g['Resource'] for g in gantt_data))
}
Process Integration
This skill integrates with the following processes:
production-scheduling-optimization.js
capacity-planning-analysis.js
Output Format
{
"schedule": {
"sequence": ["J1", "J3", "J2", "J4"],
"rule_applied": "EDD"
},
"metrics": {
"makespan": 42,
"mean_flow_time": 24.5,
"total_tardiness": 8,
"percent_on_time": 75
},
"gantt_data": [...],
"recommendations": [
"Consider SPT rule to minimize flow time",
"Job J4 is critical path - prioritize"
]
}
Best Practices
- Match rule to objective - SPT for flow time, EDD for due dates
- Consider setup times - Sequence-dependent setups matter
- Build in buffers - Account for variability
- Monitor actual vs. planned - Adjust rules based on performance
- Communicate changes - Schedule visibility is critical
- Review regularly - Reschedule as conditions change
Constraints
- Static scheduling assumes known job arrivals
- Setup times may be sequence-dependent
- Resource constraints add complexity
- Real-time adjustments needed for disruptions