### Run ProcessScheduler Installation Example Source: https://processscheduler.github.io/run This Python script demonstrates how to initialize a scheduling problem, define tasks and workers, assign resources, and solve the problem using the ProcessScheduler library. It serves as a basic test for a successful installation. ```python import processscheduler as ps pb = ps.SchedulingProblem(name="Test", horizon=10) T1 = ps.FixedDurationTask(name="T1", duration=6) T2 = ps.FixedDurationTask(name="T2", duration=4) W1 = ps.Worker(name="W1") T1.add_required_resource(W1) T2.add_required_resource(W1) solver = ps.SchedulingSolver(problem=pb) solution = solver.solve() print(solution) ``` -------------------------------- ### Setup Scheduling Problem and Static Resource Assignment Source: https://processscheduler.github.io/resource_assignment Initializes a scheduling problem, defines tasks and workers with their properties, and assigns resources to a task statically. This setup results in the task waiting for all assigned resources to be available before starting. ```python pb = ps.SchedulingProblem(name="DynamicAssignment") T_1 = ps.VariableDurationTask(name="T_1", work_amount=150) M_1 = ps.Worker(name="M_1", productivity=5) M_2 = ps.Worker(name="M_2", productivity=20) T_1.add_required_resources([M_1, M_2]) ``` -------------------------------- ### Install Additional Dependencies Source: https://processscheduler.github.io/download_install Installs extra dependencies required for development or specific features of ProcessScheduler. This command should be run after cloning the repository and before or after installing the main package. ```shell pip install -e .[dev] ``` -------------------------------- ### Example Usage: Plotly Gantt Chart Source: https://processscheduler.github.io/gantt_chart Illustrates calling `ps.render_gantt_plotly` to generate Gantt charts with Plotly. This example shows rendering in 'Resource' mode, sorting by 'Start', and saving to an HTML file, as well as rendering in 'Task' mode. ```python sol = solver.solve() if sol is not None: # default render_mode is 'Resource' ps.render_gantt_plotly(solution=sol, sort="Start", html_filename="index.html") # a second gantt chart, in 'Task' mode ps.render_gantt_plotly(solution=sol, render_mode='Task') ``` -------------------------------- ### Create SchedulingProblem Instance Source: https://processscheduler.github.io/use-case-software-development Shows how to instantiate the SchedulingProblem class, which is essential for defining scheduling tasks. It requires a name and can be configured with time deltas and start times. ```python problem = ps.SchedulingProblem( name="SoftwareDevelopment", delta_time=timedelta(days=1), start_time=datetime.now() ) ``` -------------------------------- ### Embed YouTube Video Source: https://processscheduler.github.io/use-case-formula-one-change-tires Embeds a YouTube video related to the Formula 1 pitstop example, providing visual context for the simulation. ```python from IPython.display import YouTubeVideo YouTubeVideo("aHSUp7msCIE", width=800, height=300) ``` -------------------------------- ### Install Development Version using Pip Source: https://processscheduler.github.io/download_install Navigates into the cloned repository directory and installs the ProcessScheduler package in development mode. This allows for direct use of the installed package while making changes to the source code. ```shell cd ProcessScheduler pip install . ``` -------------------------------- ### Python: Use Pareto Optimizer for Scheduling Solutions Source: https://processscheduler.github.io/objectives Demonstrates initializing a `SchedulingSolver` with the 'optimize' optimizer and 'pareto' priority. The code iterates through multiple solutions found by the solver, printing task end and start times for each. This method allows traversal of all Pareto-optimal solutions for a given scheduling problem. ```python solver = ps.SchedulingSolver(problem=pb, optimizer="optimize", optimize_priority='pareto') solution = solver.solve() while solution: print("Found solution:") print("\t task_1.end: f{solution.tasks[task_1.end]}") print("\t task_2.start: f{solution.tasks[task_2.start]}") solution = solver.solve() ``` -------------------------------- ### ZeroDurationTask Example Source: https://processscheduler.github.io/task Shows how to create a ZeroDurationTask, representing events or milestones that occur at a specific point in time without consuming any duration. This is analogous to project start dates or deadlines. ```python from processscheduler.task import ZeroDurationTask project_kickup = ZeroDurationTask(name='KickUp') ``` -------------------------------- ### ProcessScheduler Buffer Example Source: https://processscheduler.github.io/buffer This Python code demonstrates setting up a scheduling problem with a task (`T1`) that requires a machine (`M1`) and interacts with two buffers (`Buffer1`, `Buffer2`). It shows how to define task dependencies, resource requirements, and buffer load/unload constraints, then solves and visualizes the schedule. ```python import processscheduler as ps pb = ps.SchedulingProblem(name="BufferExample", horizon=6) machine_1 = ps.Worker(name="M1") task_1 = ps.FixedDurationTask(name="T1", duration=4) ps.TaskStartAt(task=task_1, value=1) task_1.add_required_resource(machine_1) # the buffers buffer_1 = ps.NonConcurrentBuffer(name="Buffer1", initial_level=5) buffer_2 = ps.NonConcurrentBuffer(name="Buffer2", initial_level=0) # buffer constraints bc_1 = ps.TaskUnloadBuffer(task=task_1, buffer=buffer_1, quantity=1) bc_2 = ps.TaskLoadBuffer(task=task_1, buffer=buffer_2, quantity=1) # solve and render solver = ps.SchedulingSolver(problem=pb) solution = solver.solve() ps.render_gantt_matplotlib(solution) ``` -------------------------------- ### Install ProcessScheduler with pip Source: https://processscheduler.github.io/download_install Installs the ProcessScheduler package and its specified version (2.0.0) using the pip package manager. This command also implicitly installs required dependencies like Z3 and pydantic. ```bash pip install ProcessScheduler==2.0.0 ``` -------------------------------- ### Multiple Objective Optimization Constraint Example Source: https://processscheduler.github.io/objectives This snippet illustrates setting up a constraint for a multiple objective optimization problem in ProcessScheduler. It defines a dependency between the end time of task_1 and the start time of task_2, highlighting how this can create a balance or contradiction in optimization goals. ```python pb.add_constraint(task_1._end == 20 - task_2._start) ``` -------------------------------- ### Example of Unsatisfiable Constraints Source: https://processscheduler.github.io/solving Illustrates a scenario where contradictory constraints are defined for tasks, leading to an 'Unsatisfiable' state. In such cases, the solver.solve() method will return False. ```python TaskStartAt(task=cook_the_chicken, value=2) TaskStartAt(task=cook_the_chicken, value=3) ``` -------------------------------- ### Verify ProcessScheduler Installation Source: https://processscheduler.github.io/download_install Checks if the ProcessScheduler package has been successfully installed by importing it into a Python 3 environment. A successful import indicates that the package and its core dependencies are available. ```python >>> import processscheduler as ps ``` -------------------------------- ### Define Task Constraints and Precedences Source: https://processscheduler.github.io/use-case-software-development Demonstrates how to set start times for tasks and define precedence relationships between tasks using the ProcessScheduler library. This is crucial for establishing the workflow and dependencies within a project schedule. ```python ps.TaskStartAt(task=preliminary_design, value=0) ps.TaskPrecedence(task_before=preliminary_design, task_after=core_development) ps.TaskPrecedence(task_before=preliminary_design, task_after=gui_development) ps.TaskPrecedence(task_before=gui_development, task_after=tests_development) ps.TaskPrecedence(task_before=core_development, task_after=tests_development) ps.TaskPrecedence(task_before=tests_development, task_after=integration) ps.TaskPrecedence(task_before=integration, task_after=release) ``` -------------------------------- ### ProcessScheduler Flow Shop Scheduling Example Source: https://processscheduler.github.io/pinedo Sets up and solves a flow shop scheduling problem with 5 jobs and 4 machines. It defines tasks, resources, and precedence, then uses ProcessScheduler to minimize makespan and visualizes the result. ```python pb = ps.SchedulingProblem(name="Pinedo6.1.1") durations = [[5,4,4,3], [5,4,4,6], [3,2,3,3], [6,4,4,2], [3,4,1,5]] # create machines M1 = ps.Worker(name="M1") M2 = ps.Worker(name="M2") M3 = ps.Worker(name="M3") M4 = ps.Worker(name="M4") machines = [M1, M2, M3, M4] # create tasks for job_number in range(5): j = 0 tasks_for_this_job = [] for d in durations[job_number]: t = ps.FixedDurationTask(name=f"{d}(T{job_number+1},{j+1})", duration=d) t.add_required_resource(machines[j]) tasks_for_this_job.append(t) j += 1 # and precedence for i in range(len(tasks_for_this_job)-1): ps.TaskPrecedence(task_before=tasks_for_this_job[i], task_after=tasks_for_this_job[i+1]) ps.ObjectiveMinimizeMakespan() solver = ps.SchedulingSolver(problem=pb) solution = solver.solve() ps.render_gantt_matplotlib(solution) ``` -------------------------------- ### VariableDurationTask Example Source: https://processscheduler.github.io/task Demonstrates the creation of a VariableDurationTask, which is suitable for activities where the duration is not fixed beforehand and may depend on external factors. This task type allows for flexibility in scheduling. ```python from processscheduler.task import VariableDurationTask # Example: The duration of this task depends on the number # of workers handling boxes. move_boxes = VariableDurationTask(name='MoveBoxesFromMachineAToInventory') ``` -------------------------------- ### Example Usage: Matplotlib Gantt Chart Source: https://processscheduler.github.io/gantt_chart Demonstrates how to call the `render_gantt_matplotlib` function after solving a scheduling problem. Shows rendering the default 'Resource' mode and an alternative 'Task' mode. ```python solution = solver.solve() if solution is not None: solution.render_gantt_matplotlib() # default render_mode is 'Resource' # a second gantt chart, in 'Task' mode solution.render_gantt_matplotlib(render_mode='Task') ``` -------------------------------- ### Define Task Release Dates with TaskStartAfter Source: https://processscheduler.github.io/use-case-flow-shop This snippet demonstrates how to define release dates for tasks in a scheduling problem. It initializes release date variables and then uses the `ps.TaskStartAfter` function to enforce that specific tasks cannot start before these defined times. This is crucial for modeling real-world scenarios where resources or materials might not be available until a certain point. ```python r1 = 0 r2 = 9 r3 = 2 r4 = 7 ps.TaskStartAfter(task=J11, value=r1) ps.TaskStartAfter(task=J12, value=r1) ps.TaskStartAfter(task=J13, value=r1) ps.TaskStartAfter(task=J21, value=r2) ps.TaskStartAfter(task=J22, value=r2) ps.TaskStartAfter(task=J23, value=r2) ps.TaskStartAfter(task=J31, value=r3) ps.TaskStartAfter(task=J32, value=r3) ps.TaskStartAfter(task=J33, value=r3) ps.TaskStartAfter(task=J41, value=r4) ps.TaskStartAfter(task=J42, value=r4) ps.TaskStartAfter(task=J43, value=r4) ``` -------------------------------- ### Create Python datetime Objects Source: https://processscheduler.github.io/scheduling_problem Shows how to create Python `datetime` objects, specifically capturing the current date and time using `datetime.now()`. This is useful for setting the start time of a scheduling problem. ```python from datetime import datetime now = datetime.now() ``` -------------------------------- ### FixedDurationTask Example Source: https://processscheduler.github.io/task Illustrates the instantiation of a FixedDurationTask, used for activities with a predetermined and constant duration. This is useful for tasks like cooking or processing that have a known time requirement. ```python from processscheduler.task import FixedDurationTask # I assume one period to be mapped to 15min, cooking will be 1.5 hour # so the chicken requires 6*15mn=1.5h to be cooked cook_chicken = FixedDurationTask(name='CookChicken', duration=6) ``` -------------------------------- ### Single Objective Optimization Example Source: https://processscheduler.github.io/objectives This snippet demonstrates how to set up and solve a single objective optimization problem in ProcessScheduler. It defines a task, an indicator based on the task's end time, and sets the objective to maximize this indicator. It then solves the problem and renders the Gantt chart. ```python pb = ps.SchedulingProblem(name='SingleObjective1', horizon=20) task_1 = ps.FixedDurationTask(name='task1', duration = 3) indicator_1 = ps.IndicatorFromMathExpression(name='Task1End', expression=task_1._end) ps.ObjectiveMaximizeIndicator(name='MaximizeTask1End', target=indicator_1) solution=ps.SchedulingSolver(problem=pb).solve() ps.render_gantt_matplotlib(solution) ``` -------------------------------- ### Create and Plot Constant Function in Python Source: https://processscheduler.github.io/function Demonstrates how to create an instance of the `ConstantFunction` class, which represents a mathematical function f(x)=K. This function can be used for cost or penalty computations. The example also shows how to plot the function using `ps.plot_function`. ```python my_constant_function = ps.ConstantFunction(value=55) ps.plot_function(my_constant_function) ``` -------------------------------- ### Define Custom Constraint using Expression Source: https://processscheduler.github.io/customized_constraints Demonstrates creating a custom constraint by defining an expression using Z3 solver objects. This allows users to specify complex relationships between task start times, end times, and durations when built-in constraints are not sufficient. ```python ps.ConstraintFromExpression(expression=t1.start == t_2.end + t_4.duration) ``` -------------------------------- ### Configure Stabilizer Tasks and Timing Source: https://processscheduler.github.io/use-case-formula-one-change-tires Sets up variable duration tasks for left and right stabilizers, assigns them to specific stabilizer resources, and defines their start and end times relative to the overall process horizon. This demonstrates how to manage tasks that span the entire duration of an activity. ```Python stabilize_left = ps.VariableDurationTask(name="StabilizeLeft") stabilize_right = ps.VariableDurationTask(name="StabilizeRight") stabilize_left.add_required_resource(stabilizers[0]) stabilize_right.add_required_resource(stabilizers[1]) ps.TaskStartAt(task=stabilize_left, value=0) ps.TaskStartAt(task=stabilize_right, value=0) ps.TaskEndAt(task=stabilize_left, value=change_tires_problem._horizon) ps.TaskEndAt(task=stabilize_right, value=change_tires_problem._horizon) ``` -------------------------------- ### Render Gantt Chart with Plotly Source: https://processscheduler.github.io/gantt_chart Defines the `render_gantt_plotly` function for rendering Gantt charts using Plotly. It requires Plotly to be installed and real timepoints for accurate visualization. Supports rendering by 'Task' or 'Resource' and allows specifying output filenames. ```python def render_gantt_plotly( solution: SchedulingSolution, fig_size: Optional[Tuple[int, int]] = None, show_plot: Optional[bool] = True, show_indicators: Optional[bool] = True, render_mode: Optional[str] = "Resource", sort: Optional[str] = None, fig_filename: Optional[str] = None, html_filename: Optional[str] = None ) -> None: ``` -------------------------------- ### Create Custom Indicator with Math Expression (Python) Source: https://processscheduler.github.io/indicator Demonstrates creating custom indicators using the `IndicatorFromMathExpression` class. This allows defining indicators based on mathematical formulas involving task properties like start and end times. The `name` parameter identifies the indicator, and the `expression` parameter defines its calculation. ```python ind = ps.IndicatorFromMathExpression(name="Task1End", expression=task_1._end) ``` ```python ind = ps.IndicatorFromMathExpression(name="SquareDistanceBetweenTasks", expression=(task_1._start - task_2._end) ** 2) ``` -------------------------------- ### Solving and Finding Another Solution Source: https://processscheduler.github.io/solving Demonstrates how to set up a scheduling problem, solve it using `SchedulingSolver`, and then find alternative solutions by calling the `find_another_solution` method with a specific task variable. It highlights that `solve` must be executed before requesting another solution. ```python problem = ps.SchedulingProblem(name='FindAnotherSolution', horizon=6) task_1 = ps.FixedDurationTask(name='task1', duration=2) problem.add_task(task_1) solver = ps.SchedulingSolver(problem=problem) solution = solver.solve() print("Solution for task_1.start:", solution.tasks['task1']) ``` ```python solution = solver.find_another_solution(task_1.start) if solution is not None: print("New solution for task_1.start:", solution.tasks['task1']) ``` -------------------------------- ### Clone ProcessScheduler Git Repository Source: https://processscheduler.github.io/download_install Creates a local copy of the ProcessScheduler GitHub repository. This is the first step to obtaining the source code for development or testing. ```shell git clone https://github.com/tpaviot/ProcessScheduler ``` -------------------------------- ### Import and Instantiate SchedulingProblem Source: https://processscheduler.github.io/scheduling_problem Imports the processscheduler library and creates a SchedulingProblem instance with a specified name and horizon. This is a common way to begin setting up a scheduling problem. ```python import processscheduler as ps my_problem = ps.SchedulingProblem(name="MyFirstSchedulingProblem", horizon=100) ``` -------------------------------- ### Combine Multiple Negated Constraints with And Source: https://processscheduler.github.io/first_order_logic_constraints Shows how to nest logical operations, specifically using the `And` class to combine multiple `Not` constraints. This example expresses a rule where a task must neither start at time 3 nor end at time 9. ```python And(list_of_constraints=[Not(constraint=TaskStartAt(task=t_1, value=3)), Not(constraint=TaskEndAt(task=t_1, value=9))]) ``` -------------------------------- ### Python: Pareto Optimization Solver Output Summary Source: https://processscheduler.github.io/objectives Illustrates a summary of the output from the Pareto optimization solver, showing the total time, objective functions maximized (e.g., MaximizeTask1End, MaximizeTask2Start), and the found solutions. This output helps in understanding the trade-offs explored by the Pareto priority. ```python Solver ========== 'pareto'Total ===================== in0.00s MaximizeTask1End3 MaximizeTask2Start17 Found{solution.tasks} {solution.tasks} Total ===================== in0.00s MaximizeTask1End4 MaximizeTask2Start16 Found{solution.tasks} {solution.tasks} Total ===================== in0.00s MaximizeTask1End5 MaximizeTask2Start15 Found{solution.tasks} {solution.tasks} Total ===================== in0.00s MaximizeTask1End6 MaximizeTask2Start14 Found{solution.tasks} {solution.tasks} Total ===================== in0.00s MaximizeTask1End7 MaximizeTask2Start13 Found{solution.tasks} ``` -------------------------------- ### Negate Task Start Time Constraint with Not Source: https://processscheduler.github.io/first_order_logic_constraints Demonstrates using the `Not` class to express that a task should not start at a specific time. This is useful for constraints not directly available in built-in libraries, allowing for custom logic formulation. ```python Not(constraint=TaskStartAt(task=t_1, value=3)) ``` -------------------------------- ### Incremental Solver Usage Source: https://processscheduler.github.io/objectives Demonstrates how to initialize and use the incremental solver for optimization problems. The incremental solver iteratively searches for better solutions until a maximum time is reached. ```python solver = ps.SchedulingSolver(problem=pb, max_time=300) # 300s is 5 minutes solution = solver.solve() ``` -------------------------------- ### Tasks Start Synced Constraint Source: https://processscheduler.github.io/task_constraints Specifies that two tasks must begin execution at the exact same time. ```python # Example usage for TasksStartSynced # task_a.start = task_b.start ``` -------------------------------- ### Solve and Render Schedule Source: https://processscheduler.github.io/pinedo Sets the optimization objective to minimize the makespan (total completion time) and then initializes and runs the scheduling solver. Finally, it renders the resulting schedule using a Gantt chart. ```python ps.ObjectiveMinimizeMakespan() solver = ps.SchedulingSolver(problem=problem) solution = solver.solve() ps.render_gantt_matplotlib(solution) ``` -------------------------------- ### Instantiate SchedulingSolver with Options Source: https://processscheduler.github.io/solving Creates an instance of the SchedulingSolver, which requires a SchedulingProblem instance. It accepts several optional arguments to control its behavior, such as debug mode, maximum execution time, parallel processing, random value generation, Z3 logic selection, verbosity level, and optimization strategy. ```python solver = SchedulingSolver(problem=scheduling_problem_instance) ``` -------------------------------- ### Solve and Render Schedule Source: https://processscheduler.github.io/use-case-formula-one-change-tires Initializes a `SchedulingSolver` with the defined problem and solves it to find an optimal schedule. The resulting schedule is then rendered as a Gantt chart using Matplotlib, with resources visualized. ```python solver = ps.SchedulingSolver(problem=change_tires_problem) solution_1 = solver.solve() ps.render_gantt_matplotlib(solution_1, fig_size=(10, 5), render_mode="Resource") ``` -------------------------------- ### Initialize Solver with Box Priority Source: https://processscheduler.github.io/objectives This snippet demonstrates how to initialize the `SchedulingSolver` from the `processscheduler` library with the 'box' priority mode. This mode helps the solver find maximum values for objectives, understanding that not all objectives may be achievable simultaneously. The solver is configured with a problem (`pb`), an optimizer type (`'optimize'`), and the specific priority (`'box'`). The `solve()` method is then called to execute the optimization. ```python solver = ps.SchedulingSolver(problem=pb, optimizer="optimize", optimize_priority='box') solver.solve() ``` -------------------------------- ### Create Project Resources Source: https://processscheduler.github.io/use-case-software-development Illustrates the creation of worker resources, defining their names, productivity levels, and associated costs using cost functions. This step is essential for resource allocation and cost estimation in project scheduling. ```python elias = ps.Worker( name="Elias", productivity=2, cost=ps.ConstantCostFunction(value=600) ) # cost in $/day louis = ps.Worker( name="Louis", productivity=2, cost=ps.ConstantCostFunction(value=600) ) elise = ps.Worker( name="Elise", productivity=3, cost=ps.ConstantCostFunction(value=800) ) justine = ps.Worker( name="Justine", productivity=2, cost=ps.ConstantCostFunction(value=1200) ) ``` -------------------------------- ### Define Quadratic Cost Function Source: https://processscheduler.github.io/resource Defines a Python function `quadratic_time_function` that calculates a cost based on time `t` using a quadratic formula. This function serves as an example of a callable cost model. ```python def quadratic_time_function(t): return (t-20)**2 + 154 ``` -------------------------------- ### Solve Scheduling Problem Source: https://processscheduler.github.io/use-case-software-development Initializes the SchedulingSolver with a given problem and executes the solve method to find a solution. This step is crucial for obtaining the scheduling outcome. ```python # solve solver = ps.SchedulingSolver(problem=problem) solution = solver.solve() ``` -------------------------------- ### Task Precedence Constraint Source: https://processscheduler.github.io/task_constraints Ensures that one task is scheduled to start after another task has completed. Supports 'lax', 'strict', or 'tight' precedence types and an optional offset. ```python task_1 = ps.FixedDurationTask(name='Task1', duration=3) task_2 = ps.FixedVariableTask(name='Task2') pc = TaskPrecedence(task_before=task1, task_after=task2, kind='tight', offset=2) ``` -------------------------------- ### Create Basic Worker Source: https://processscheduler.github.io/resource Demonstrates the creation of a basic Worker instance, representing an atomic, countable resource. This is suitable for entities like individual humans or machines. ```python john = Worker(name='JohnBenis') ``` -------------------------------- ### Initialize SchedulingProblem with Datetime Source: https://processscheduler.github.io/scheduling_problem Illustrates how to initialize the `SchedulingProblem` class from the ProcessScheduler library, providing `horizon`, `delta_time` (as a `timedelta` object), and `start_time` (as a `datetime` object). This configures the scheduler with specific time parameters. ```python problem = ps.SchedulingProblem(name='DateTimeBase', horizon=7, delta_time=timedelta(minutes=15), start_time=datetime.now()) ``` -------------------------------- ### Single Task Temporal Constraints Source: https://processscheduler.github.io/task_constraints Defines temporal constraints that apply to individual tasks, specifying conditions for their start and end times. These can be strict or lax, with an optional 'kind' argument. ```python task1 = FixedDurationTask(name="Task1", duration=10) TaskStarAfter(task= task1, value=7, kind="strict") ``` -------------------------------- ### Import Libraries Source: https://processscheduler.github.io/use-case-formula-one-change-tires Imports the necessary processscheduler library and configures the inline backend for SVG figure output. ```python import processscheduler as ps %config InlineBackend.figure_formats = ['svg'] ``` -------------------------------- ### Define Buffer Load and Unload Tasks Source: https://processscheduler.github.io/buffer Illustrates how to associate tasks with buffers for loading and unloading operations. TaskUnloadBuffer removes items at task start, while TaskLoadBuffer adds items upon task completion. ```python c1 = ps.TaskUnloadBuffer(task_1, buffer, quantity=3) c2 = ps.TaskLoadBuffer(task_2, buffer, quantity=6) ``` -------------------------------- ### Import ProcessScheduler and Datetime Modules Source: https://processscheduler.github.io/use-case-software-development Demonstrates how to import the processscheduler library with an alias and necessary datetime modules. It also configures inline plotting format for visualizations. ```python import processscheduler as ps from datetime import timedelta, datetime %config InlineBackend.figure_formats = ['svg'] ``` -------------------------------- ### ProcessScheduler Multi-Objective Optimization (Default Weights) Source: https://processscheduler.github.io/objectives Demonstrates setting up a scheduling problem with multiple objectives using default weights in ProcessScheduler. This involves defining tasks, constraints, indicators, and objectives, then solving the problem and rendering the Gantt chart. ```python import processscheduler as ps pb = ps.SchedulingProblem(name='MultiObjective2', horizon=20) task_1 = ps.FixedDurationTask(name='task1', duration = 3) task_2 = ps.FixedDurationTask(name='task2', duration = 3) pb.add_constraint(task_1._end == 20 - task_2._start) indicator_1 = ps.IndicatorFromMathExpression(name='Task1End', expression=task_1._end) indicator_2 = ps.IndicatorFromMathExpression(name='Task2Start', expression=task_2._start) ps.ObjectiveMaximizeIndicator(name='MaximizeTask1End', target=indicator_1, weight=1) ps.ObjectiveMaximizeIndicator(name='MaximizeTask2Start', target=indicator_2, weight=1) solution = ps.SchedulingSolver(problem=pb).solve() ps.render_gantt_matplotlib(solution) ``` -------------------------------- ### Create and Plot Linear Function in Python Source: https://processscheduler.github.io/function Illustrates the creation of a `LinearFunction` object, representing a function of the form f(x)=s*x+i. This class is useful for defining linear costs or penalties. The example includes plotting the function using `ps.plot_function`. ```python my_linear_function = ps.LinearFunction(slope=1, intercept=2) ps.plot_function(my_linear_function) ``` -------------------------------- ### Add Makespan Objective and Solve Source: https://processscheduler.github.io/use-case-formula-one-change-tires This Python snippet demonstrates how to add a makespan objective to a scheduling problem using the `ps` library. It then initializes a `SchedulingSolver`, solves the problem, and renders the solution as a Gantt chart. ```python # add makespan objective ps.ObjectiveMinimizeMakespan() solver_2 = ps.SchedulingSolver(problem=change_tires_problem) solution_2 = solver_2.solve() ps.render_gantt_matplotlib(solution_2, fig_size=(9, 5), render_mode="Task") ``` -------------------------------- ### Enable Dynamic Resource Assignment Source: https://processscheduler.github.io/resource_assignment Modifies the resource assignment to enable dynamic allocation by setting the 'dynamic' parameter to True for specific resources. This allows resources like M2 to join the task T1 as soon as they become available, even if the task has already started. ```python T_1.add_required_resource(M_1) T_1.add_required_resource(M_2, dynamic=True) ``` -------------------------------- ### VariableDurationTask with Allowed Durations Source: https://processscheduler.github.io/task Shows how to initialize a VariableDurationTask with a list of discrete durations. The solver will select one of these allowed durations to satisfy scheduling constraints. ```python # either 1 or 2 hour for an english lesson english_lesson = VariableDurationTask(name='EnglishLesson', allowed_durations = [1, 2]) ``` -------------------------------- ### Create NonConcurrentBuffer Instances Source: https://processscheduler.github.io/buffer Demonstrates the creation of NonConcurrentBuffer objects with various optional parameters. These include setting a name, initial buffer level, lower bound, and upper bound to define buffer constraints. ```python buff1 = ps.NonConcurrentBuffer(name="Buffer1") buff2 = ps.NonConcurrentBuffer(name="Buffer2", initial_level=10) buff3 = ps.NonConcurrentBuffer(name="Buffer3", lower_bound=0) buff4 = ps.NonConcurrentBuffer(name="Buffer4", upper_bound=20) buff5 = ps.NonConcurrentBuffer(name="Buffer5", initial_level=3, lower_bound=0, upper_bound=10) ``` -------------------------------- ### Optimize Solver Usage Source: https://processscheduler.github.io/objectives Illustrates the usage of the 'optimize' solver, which leverages the z3-solver for guaranteed optimal values. This solver's computation cannot be interrupted, so caution is advised for large problems. ```python solver = ps.SchedulingSolver(problem=pb, optimizer="optimize") # 300s is 5 minutes solution = solver.solve() ``` -------------------------------- ### Implement Logical Implication with Implies Source: https://processscheduler.github.io/first_order_logic_constraints Illustrates the `Implies` class, which takes a condition and a list of constraints to be implied if the condition is true. This allows expressing conditional task relationships, such as 'if task A starts at time X, then task B must end at time Y'. ```python impl = Implies(condition=t_2._start == 4, list_of_constraints=[TasksEndSynced(task_1=t_3,task_2=t_4)]) ``` -------------------------------- ### Minimizing Number of Tardy Jobs Example Source: https://processscheduler.github.io/pinedo This Python code snippet demonstrates how to set up and solve a scheduling problem aimed at minimizing the number of tardy tasks. It defines tasks with durations and due dates, assigns them to a worker resource, and configures an objective function to count tardy tasks. It utilizes the `processscheduler` library. ```python problem = ps.SchedulingProblem(name="PinedoExample3.3.3") J1 = ps.FixedDurationTask(name="J1", duration=7, due_date=9, due_date_is_deadline=False) J2 = ps.FixedDurationTask( name="J2", duration=8, due_date=17, due_date_is_deadline=False ) J3 = ps.FixedDurationTask( name="J3", duration=4, due_date=18, due_date_is_deadline=False ) J4 = ps.FixedDurationTask( name="J4", duration=6, due_date=19, due_date_is_deadline=False ) J5 = ps.FixedDurationTask( name="J5", duration=6, due_date=21, due_date_is_deadline=False ) M1 = ps.Worker(name="M1") for j in [J1, J2, J3, J4, J5]: j.add_required_resource(M1) ind = ps.IndicatorNumberOfTardyTasks() ps.ObjectiveMinimizeIndicator(target=ind, weight=1) ``` -------------------------------- ### Create Scheduling Problem Instance Source: https://processscheduler.github.io/use-case-flow-shop Initializes a SchedulingProblem object for the flow shop scenario. The total horizon is left empty, and only the problem name is set. ```Python flow_shop_problem = ps.SchedulingProblem(name="FlowShop") ``` -------------------------------- ### Minimize Total Completion Time with Deadlines using processscheduler Source: https://processscheduler.github.io/pinedo This Python script utilizes the `processscheduler` library to model and solve a job scheduling problem aimed at minimizing total completion time. It defines tasks with durations and due dates, assigns them to a worker resource, sets the objective function, and then solves the problem, rendering a Gantt chart of the solution. The example is based on a specific problem from the Pinedo book. ```Python import processscheduler as ps """Example 4.1.5 of the Pinedo book. The solution is expected to be: 1,3,6,5,4,2""" problem = ps.SchedulingProblem(name="MultipleObjectiveLatenessTardiness") J1 = ps.FixedDurationTask(name="J1", duration=4, due_date=10) J2 = ps.FixedDurationTask(name="J2", duration=6, due_date=12, due_date_is_deadline=True) J3 = ps.FixedDurationTask(name="J3", duration=2, due_date=14, due_date_is_deadline=True) J4 = ps.FixedDurationTask(name="J4", duration=4, due_date=18, due_date_is_deadline=True) J5 = ps.FixedDurationTask(name="J5", duration=2, due_date=18, due_date_is_deadline=True) M1 = ps.Worker(name="M1") for j in [J1, J2, J3, J4, J5]: j.add_required_resource(M1) ps.ObjectiveMinimizeFlowtime() solver = ps.SchedulingSolver(problem=problem) solution_1 = solver.solve() ps.render_gantt_matplotlib(solution_1) ``` -------------------------------- ### Configure Machine Resources Source: https://processscheduler.github.io/pinedo Sets up the available machines (workers) and assigns them as potential resources for each job. This step defines that any job can be processed by either machine M1 or M2. ```python # two machines machine_1 = ps.Worker(name="M1") machine_2 = ps.Worker(name="M2") # resource assignment: each job can be processed eithe by machine_1 # or machine_2 for j in jobs: j.add_required_resource(ps.SelectWorkers(list_of_workers=[machine_1, machine_2])) ``` -------------------------------- ### Import processscheduler Library Source: https://processscheduler.github.io/use-case-flow-shop Imports the necessary processscheduler library and configures inline plotting for figures. ```Python import processscheduler as ps %config InlineBackend.figure_formats = ['svg'] ``` -------------------------------- ### Instantiate SchedulingProblem with Horizon Source: https://processscheduler.github.io/scheduling_problem Creates a SchedulingProblem instance, setting the name and the time horizon for scheduling tasks. The horizon defines the upper bound of the time interval, subdivided into discrete periods. ```python my_problem = SchedulingProblem(name='MySchedulingProblem', horizon=20) ``` -------------------------------- ### ProcessScheduler Optimize Solver with Lexicographical Priority Source: https://processscheduler.github.io/objectives Demonstrates configuring and using the 'optimize' solver in ProcessScheduler with the 'lex' (lexicographical) priority for multi-objective optimization. This method optimizes objectives sequentially, fixing previous results. ```python solver = ps.SchedulingSolver(problem=pb, optimizer="optimize", optimize_priority='lex') solver.solve() ``` -------------------------------- ### Apply SameWorkers Constraint for Tire Change Source: https://processscheduler.github.io/use-case-formula-one-change-tires This Python code demonstrates how to apply the `SameWorkers` constraint from the `ps` library to ensure that the same worker (e.g., a gunner) performs both the unscrewing and screwing tasks for each tire. It includes setting up the solver and rendering the solution. ```python ps.SameWorkers( select_workers_1=gunner_unscrew_front_left_tyre, select_workers_2=gunner_screw_front_left_tyre, ) ps.SameWorkers( select_workers_1=gunner_unscrew_front_right_tyre, select_workers_2=gunner_screw_front_right_tyre, ) ps.SameWorkers( select_workers_1=gunner_unscrew_rear_left_tyre, select_workers_2=gunner_screw_rear_left_tyre, ) ps.SameWorkers( select_workers_1=gunner_unscrew_rear_right_tyre, select_workers_2=gunner_screw_rear_right_tyre, ) solver_3 = ps.SchedulingSolver(problem=change_tires_problem) solution_3 = solver_3.solve() ps.render_gantt_matplotlib(solution_3, fig_size=(9, 5), render_mode="Task") ``` -------------------------------- ### Create tasks and assign resources Source: https://processscheduler.github.io/use-case-formula-one-change-tires This Python code snippet demonstrates creating fixed duration tasks for a Formula One tire change process. It defines tasks for lifting and unscrewing tires and assigns specific resources (lifters and gunners) to them using the ProcessScheduler library. The `duration` parameter represents time in seconds. ```python # lift tasks and lifters # both lift tasks can be processed by any one of the lifters lift_rear_up = ps.FixedDurationTask(name="LiftRearUp", duration=2) lift_front_up = ps.FixedDurationTask(name="LiftFrontUp", duration=2) lift_rear_up.add_required_resource(lifters[0]) lift_front_up.add_required_resource(lifters[1]) lift_rear_down = ps.FixedDurationTask(name="LiftRearDown", duration=2) lift_front_down = ps.FixedDurationTask(name="LiftFrontDown", duration=2) lift_rear_down.add_required_resource(lifters[0]) lift_front_down.add_required_resource(lifters[1]) # unscrew tasks unscrew_front_left_tyre = ps.FixedDurationTask(name="UnScrewFrontLeftTyre", duration=2) unscrew_front_right_tyre = ps.FixedDurationTask( name="UnScrewFrontRightTyre", duration=2 ) unscrew_rear_left_tyre = ps.FixedDurationTask(name="UnScrewRearLeftTyre", duration=2) unscrew_rear_right_tyre = ps.FixedDurationTask(name="UnScrewRearRightTyre", duration=2) gunner_unscrew_front_left_tyre = ps.SelectWorkers( list_of_workers=gunners, nb_workers_to_select=1 ) unscrew_front_left_tyre.add_required_resource(gunner_unscrew_front_left_tyre) gunner_unscrew_front_right_tyre = ps.SelectWorkers( list_of_workers=gunners, nb_workers_to_select=1 ) unscrew_front_right_tyre.add_required_resource(gunner_unscrew_front_right_tyre) gunner_unscrew_rear_left_tyre = ps.SelectWorkers( list_of_workers=gunners, nb_workers_to_select=1 ) unscrew_rear_left_tyre.add_required_resource(gunner_unscrew_rear_left_tyre) ```