Skip to main content

Scheduling extension for PyCSP3 with interval variables, sequence variables, and scheduling constraints

Project description

pycsp3-scheduling

Scheduling extension for pycsp3 with interval variables, sequence variables, and scheduling constraints.

Features

  • Interval Variables: Represent tasks/activities with start, end, size, length, and optional presence
  • Intensity Functions: Stepwise intensity metadata with granularity scaling for size/length
  • Sequence Variables: Ordered sequences of intervals on disjunctive resources
  • Precedence Constraints: end_before_start, start_at_start, etc.
  • Grouping Constraints: span, alternative, synchronize
  • Sequence Constraints: SeqNoOverlap, first, last, before, previous, same_sequence
  • Forbidden Time Constraints: forbid_start, forbid_end, forbid_extent
  • Presence Constraints: presence_implies, presence_or, presence_xor, chain
  • Overlap Constraints: must_overlap, overlap_at_least, disjunctive
  • Aggregate Expressions: count_present, earliest_start, latest_end, makespan
  • Cumulative Functions: pulse, step_at_start, step_at_end for resource modeling
  • State Functions: Model resource states with transitions
  • XCSP3 Extension: Output scheduling models in extended XCSP3 format
  • Visualization: Gantt charts and resource profiles

Installation

pip install pycsp3-scheduling

For development:

git clone https://github.com/sohaibafifi/pycsp3-scheduling.git
cd pycsp3-scheduling
pip install -e ".[dev]"

Quick Start

from pycsp3 import *
from pycsp3_scheduling import *

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

# Precedence: task1 must finish before task2 starts
satisfy(end_before_start(task1, task2))

# No overlap: task2 and task3 cannot overlap
satisfy(SeqNoOverlap([task2, task3]))

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

Example: Job Shop Scheduling

from pycsp3 import *
from pycsp3_scheduling import *

# Data
n_jobs, n_machines = 3, 3
durations = [[3, 2, 2], [2, 1, 4], [4, 3, 3]]
machines = [[0, 1, 2], [0, 2, 1], [1, 0, 2]]

# Create interval variables for each operation
ops = [[IntervalVar(size=durations[j][o], name=f"op_{j}_{o}")
        for o in range(n_machines)] for j in range(n_jobs)]

# Sequences for each machine
sequences = [SequenceVar(
    intervals=[ops[j][o] for j in range(n_jobs)
               for o in range(n_machines) if machines[j][o] == m],
    name=f"machine_{m}"
) for m in range(n_machines)]

# Precedence within jobs
satisfy(
    end_before_start(ops[j][o], ops[j][o+1])
    for j in range(n_jobs) for o in range(n_machines-1)
)

# No overlap on machines
satisfy(SeqNoOverlap(seq) for seq in sequences)

# Minimize makespan
minimize(Maximum(end_time(ops[j][-1]) for j in range(n_jobs)))

Example: RCPSP (Resource-Constrained Project Scheduling)

from pycsp3 import *
from pycsp3_scheduling import *

# Data
durations = [3, 2, 5, 4, 2]
demands = [[2, 1], [1, 2], [3, 0], [2, 1], [1, 3]]
capacities = [4, 3]
precedences = [(0, 2), (1, 3), (2, 4)]

# Interval variables
tasks = [IntervalVar(size=durations[i], name=f"task_{i}")
         for i in range(len(durations))]

# Precedence constraints
satisfy(end_before_start(tasks[p], tasks[s]) for p, s in precedences)

# Cumulative resource constraints
for r in range(len(capacities)):
    resource = sum(pulse(tasks[i], demands[i][r])
                   for i in range(len(tasks)) if demands[i][r] > 0)
    satisfy(resource <= capacities[r])

# Minimize makespan
minimize(Maximum(end_time(t) for t in tasks))

API Reference

Variables

Function Description
IntervalVar(size, start, end, length, intensity, granularity, optional, name) Create an interval variable
IntervalVarArray(size, ...) Create array of interval variables
SequenceVar(intervals, types, name) Create a sequence variable

Expressions

Function Description
start_of(interval, absent_value=0) Start time of interval
end_of(interval, absent_value=0) End time of interval
size_of(interval, absent_value=0) Size/duration of interval
length_of(interval, absent_value=0) Length of interval
presence_of(interval) Boolean presence status
overlap_length(interval1, interval2, absent_value=0) Overlap duration between two intervals
expr_min(*args) Minimum of scheduling expressions
expr_max(*args) Maximum of scheduling expressions

Element Expressions (Array Indexing)

Function Description
element(array, index) Access array element by interval expression index
element2d(matrix, row, col) Access 2D matrix element by interval expressions
ElementMatrix(matrix) Wrapper for 2D indexing with [] operator

Interop Helpers

Function Description
start_time(interval) pycsp3 variable for start time
end_time(interval) pycsp3 expression for end time
presence_time(interval) pycsp3 variable for presence (optional intervals)
interval_value(interval) Get solved interval values (start, end, size, present)
model_statistics() Get model statistics (variables, constraints counts)
solution_statistics() Get solution statistics after solving

Precedence Constraints

Constraint Semantics (when both present)
start_before_start(a, b, delay) start(b) >= start(a) + delay
start_before_end(a, b, delay) end(b) >= start(a) + delay
end_before_start(a, b, delay) start(b) >= end(a) + delay
end_before_end(a, b, delay) end(b) >= end(a) + delay
start_at_start(a, b, delay) start(b) == start(a) + delay
start_at_end(a, b, delay) start(b) == end(a) + delay
end_at_start(a, b, delay) end(a) == start(b) + delay
end_at_end(a, b, delay) end(b) == end(a) + delay

Grouping Constraints

Constraint Description
span(main, subtasks) Main interval spans all present subtasks
alternative(main, alts, card=1) Select card alternatives matching main
synchronize(main, intervals) All present intervals sync with main

Sequence Constraints

Constraint Description
SeqNoOverlap(sequence, transition_matrix, is_direct) Non-overlap with optional transition times
first(sequence, interval) Constrain interval to be first in sequence
last(sequence, interval) Constrain interval to be last in sequence
before(sequence, interval1, interval2) interval1 must end before interval2 starts
previous(sequence, interval1, interval2) interval1 immediately precedes interval2
same_sequence(seq1, seq2) Common intervals have same position in both
same_common_subsequence(seq1, seq2) Common intervals have same relative order

Sequence Accessor Expressions

Function Description
start_of_next(sequence, interval, absent_value) Start time of next interval in sequence
end_of_next(sequence, interval, absent_value) End time of next interval
size_of_next(sequence, interval, absent_value) Size of next interval
length_of_next(sequence, interval, absent_value) Length of next interval
type_of_next(sequence, interval, absent_value) Type of next interval
start_of_prev(sequence, interval, absent_value) Start time of previous interval
end_of_prev(sequence, interval, absent_value) End time of previous interval
size_of_prev(sequence, interval, absent_value) Size of previous interval
length_of_prev(sequence, interval, absent_value) Length of previous interval
type_of_prev(sequence, interval, absent_value) Type of previous interval

Cumulative Functions

Function Description
pulse(interval, height) Constant consumption during interval
step_at(time, height) Step at fixed time point
step_at_start(interval, height) Step at interval start
step_at_end(interval, height) Step at interval end
height_at_start(interval, cumul) Cumulative height at interval start
height_at_end(interval, cumul) Cumulative height at interval end
cumul_range(cumul, min, max) Constrain cumul to [min, max]
always_in(cumul, interval, min, max) Cumul in range during interval
SeqCumulative(sequence, heights, capacity) Cumulative on sequence with per-interval heights

State Functions

Function Description
StateFunction(transition_matrix) Create state function with optional transitions
TransitionMatrix(n_states) Create transition matrix for state function
always_equal(func, interval, value) State equals value during interval
always_constant(func, interval) State constant during interval
always_no_state(func, interval) No state assigned during interval

Forbidden Time Constraints

Constraint Description
forbid_start(interval, periods) Interval cannot start during forbidden periods
forbid_end(interval, periods) Interval cannot end during forbidden periods
forbid_extent(interval, periods) Interval cannot overlap forbidden periods

Presence Constraints

Constraint Description
presence_implies(a, b) If a is present, b must be present
presence_or(a, b) At least one must be present
presence_xor(a, b) Exactly one must be present
all_present_or_all_absent(intervals) All-or-nothing group
if_present_then(interval, constraint) Apply constraint only when present
at_least_k_present(intervals, k) At least k must be present
at_most_k_present(intervals, k) At most k can be present
exactly_k_present(intervals, k) Exactly k must be present

Chain Constraints

Constraint Description
chain(intervals, delays) Intervals execute in sequence with optional delays
strict_chain(intervals, delays) Intervals execute back-to-back (equality)

Overlap Constraints

Constraint Description
must_overlap(a, b) Two intervals must share some time
overlap_at_least(a, b, min_overlap) Intervals must overlap by at least min_overlap
no_overlap_pairwise(intervals) Simple pairwise no-overlap
disjunctive(intervals, transition_times) Unary resource (at most one active)

Aggregate Expressions

Expression Description
count_present(intervals) Count of present intervals
earliest_start(intervals) Minimum start time among present intervals
latest_end(intervals) Maximum end time among present intervals
span_length(intervals) Total span (latest_end - earliest_start)
makespan(intervals) Alias for latest_end

Requirements

  • Python >= 3.10
  • pycsp3 >= 2.5
  • lxml >= 4.9
  • matplotlib >= 3.7 (optional, for visualization)
  • java >= 8 (optional, for solving with ACE/Choco)

License

MIT License - see LICENSE file.

References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pycsp3_scheduling-0.3.1.tar.gz (401.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pycsp3_scheduling-0.3.1-py3-none-any.whl (84.3 kB view details)

Uploaded Python 3

File details

Details for the file pycsp3_scheduling-0.3.1.tar.gz.

File metadata

  • Download URL: pycsp3_scheduling-0.3.1.tar.gz
  • Upload date:
  • Size: 401.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pycsp3_scheduling-0.3.1.tar.gz
Algorithm Hash digest
SHA256 ec1ceda195325037871a71ab81924b5ff34c1847c19a819c68423c46b53f6b18
MD5 2e69944929fde6c8acf32a7f27fe6d1f
BLAKE2b-256 e8dbeb615ef62755086e1705f6a09a5ed5fd52f24bb94ed84d1afe9c01b241d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycsp3_scheduling-0.3.1.tar.gz:

Publisher: publish.yml on sohaibafifi/pycsp3-scheduling

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pycsp3_scheduling-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pycsp3_scheduling-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 48c926c44289f21fb416a1429d601183dd0f106d2864df091ab40f9449ba9e7d
MD5 f9ce8d5e05eec843fa7c6b72d6cef21c
BLAKE2b-256 f076a18a34a0f89d08542ed55218c003db9b331e75d93f3e79504b27b3390290

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycsp3_scheduling-0.3.1-py3-none-any.whl:

Publisher: publish.yml on sohaibafifi/pycsp3-scheduling

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page