Getting Started

This guide will walk you through creating your first scheduling model with pycsp3-scheduling.

Your First Scheduling Model

Let’s model a simple scheduling problem: scheduling three tasks on a single machine with no overlap.

Step 1: Import the Libraries

from pycsp3 import satisfy, minimize, solve, SAT, OPTIMUM, Maximum
from pycsp3_scheduling import (
    IntervalVar,
    SeqNoOverlap,
    end_time,
    interval_value,
)

Step 2: Create Interval Variables

Each task is represented by an IntervalVar:

# Three tasks with different durations
task1 = IntervalVar(size=10, name="task1")
task2 = IntervalVar(size=15, name="task2")
task3 = IntervalVar(size=8, name="task3")

The size parameter specifies the duration. The solver will determine the start time.

Step 3: Add Constraints

Tasks on the same machine cannot overlap:

satisfy(SeqNoOverlap([task1, task2, task3]))

Step 4: Define the Objective

Minimize the makespan (completion time of the last task):

minimize(Maximum(end_time(task1), end_time(task2), end_time(task3)))

Step 5: Solve and Extract Results

if solve() in (SAT, OPTIMUM):
    for task in [task1, task2, task3]:
        result = interval_value(task)
        print(f"{task.name}: start={result.start}, end={result.end}")
else:
    print("No solution found")

Complete Example

from pycsp3 import satisfy, minimize, solve, SAT, OPTIMUM, Maximum
from pycsp3_scheduling import IntervalVar, SeqNoOverlap, end_time, interval_value

# Create tasks
task1 = IntervalVar(size=10, name="task1")
task2 = IntervalVar(size=15, name="task2")
task3 = IntervalVar(size=8, name="task3")

# No overlap constraint
satisfy(SeqNoOverlap([task1, task2, task3]))

# Minimize makespan
minimize(Maximum(end_time(task1), end_time(task2), end_time(task3)))

# Solve
if solve() in (SAT, OPTIMUM):
    for task in [task1, task2, task3]:
        result = interval_value(task)
        print(f"{task.name}: start={result.start}, end={result.end}")

Expected output:

task1: start=0, end=10
task2: start=10, end=25
task3: start=25, end=33

Adding Precedence Constraints

Often tasks have dependencies. Let’s say task1 must finish before task2 starts:

from pycsp3_scheduling import end_before_start

# task1 → task2 precedence
satisfy(end_before_start(task1, task2))

Working with Variable Durations

Tasks can have flexible durations:

# Task with duration between 5 and 15 time units
flexible_task = IntervalVar(size=(5, 15), name="flexible")

Optional Tasks

Some tasks may be optional (can be skipped):

# Optional task - solver decides if it should be scheduled
optional_task = IntervalVar(size=10, optional=True, name="optional")

# Check if the task was scheduled
result = interval_value(optional_task)
if result is None:
    print("Task was not scheduled (absent)")
else:
    print(f"Task scheduled at: start={result.start}")

Next Steps