syeedalireza's picture
Upload folder using huggingface_hub
7a0a17c verified
"""
OR-Tools CP-SAT single-machine (or multi-machine) scheduling.
Input: list of tasks with duration; output: start times and makespan.
"""
from ortools.sat.python import cp_model
from typing import List, Dict, Any, Optional
def solve_single_machine(tasks: List[Dict[str, Any]], horizon: int = 10000) -> Dict[str, Any]:
"""
tasks: [ {"id": "A", "duration": 2}, ... ]
Returns: {"schedule": [ {"id": "A", "start": 0, "end": 2} ], "makespan": int } or {"error": "..."}
"""
model = cp_model.CpModel()
starts = {}
ends = {}
intervals = []
for t in tasks:
tid = t["id"]
dur = int(t.get("duration", 1))
start = model.NewIntVar(0, horizon, f"s_{tid}")
end = model.NewIntVar(0, horizon, f"e_{tid}")
interval = model.NewIntervalVar(start, dur, end, f"i_{tid}")
starts[tid] = start
ends[tid] = end
intervals.append(interval)
model.AddNoOverlap(intervals)
makespan = model.NewIntVar(0, horizon, "makespan")
for tid, e in ends.items():
model.Add(makespan >= e)
model.Minimize(makespan)
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status != cp_model.OPTIMAL and status != cp_model.FEASIBLE:
return {"error": "No solution found", "status": str(status)}
schedule = []
for t in tasks:
tid = t["id"]
start = solver.Value(starts[tid])
end = solver.Value(ends[tid])
schedule.append({"id": tid, "start": start, "end": end})
return {"schedule": schedule, "makespan": int(solver.ObjectiveValue())}