def test_resource_tasks_distance_single_time_period_1(self) -> None:
        """Adding one or more non scheduled optional tasks should not change anything"""
        pb = ps.SchedulingProblem("ResourceTasksDistanceSingleTimePeriod1")
        task_1 = ps.FixedDurationTask("task1", duration=1)
        task_2 = ps.FixedDurationTask("task2", duration=1)

        worker_1 = ps.Worker("Worker1")
        task_1.add_required_resource(worker_1)
        task_2.add_required_resource(worker_1)

        ps.ResourceTasksDistance(worker_1,
                                 distance=4,
                                 mode="exact",
                                 list_of_time_intervals=[[10, 18]])
        ps.TaskPrecedence(task_1, task_2)
        # we add a makespan objective: the two tasks should be scheduled with an horizon of 2
        # because they are outside the time period
        pb.add_objective_makespan()

        solver = ps.SchedulingSolver(pb)

        solution = solver.solve()

        self.assertTrue(solution)
        t1_start = solution.tasks[task_1.name].start
        t2_start = solution.tasks[task_2.name].start
        t1_end = solution.tasks[task_1.name].end
        t2_end = solution.tasks[task_2.name].end
        self.assertEqual(t1_start, 0)
        self.assertEqual(t1_end, 1)
        self.assertEqual(t2_start, 1)
        self.assertEqual(t2_end, 2)
    def test_resource_tasks_distance_single_time_period_2(self) -> None:
        """The same as above, except that we force the tasks to be scheduled
        in the time period so that the distance applies"""
        pb = ps.SchedulingProblem("ResourceTasksDistanceSingleTimePeriod2")
        task_1 = ps.FixedDurationTask("task1", duration=1)
        task_2 = ps.FixedDurationTask("task2", duration=1)

        worker_1 = ps.Worker("Worker1")
        task_1.add_required_resource(worker_1)
        task_2.add_required_resource(worker_1)

        ps.ResourceTasksDistance(worker_1,
                                 distance=4,
                                 mode="exact",
                                 list_of_time_intervals=[[10, 18]])
        # force task 1 to start at 10 (in the time period intervak)
        ps.TaskStartAt(task_1, 10)
        # task_2 must be scheduled after task_1
        ps.TaskPrecedence(task_1, task_2)

        # add a makespan objective, to be sure, to schedule task_2 in the time interal
        pb.add_objective_makespan()

        # as a consequence, task2 should be scheduled 4 periods after and start at 15
        solver = ps.SchedulingSolver(pb)

        solution = solver.solve()

        self.assertTrue(solution)
        self.assertEqual(solution.tasks[task_2.name].start, 15)
        self.assertEqual(solution.tasks[task_2.name].end, 16)
示例#3
0
 def test_create_task_precedence_raise_exception_offset_int(self) -> None:
     new_problem_or_clear()
     t_1 = ps.FixedDurationTask("t1", duration=2)
     t_2 = ps.FixedDurationTask("t2", duration=3)
     with self.assertRaises(ValueError):
         ps.TaskPrecedence(t_1, t_2, offset=1.5,
                           kind="lax")  # should be int
示例#4
0
 def test_create_task_precedence_tight(self) -> None:
     new_problem_or_clear()
     t_1 = ps.FixedDurationTask("t1", duration=2)
     t_2 = ps.FixedDurationTask("t2", duration=3)
     precedence_constraint = ps.TaskPrecedence(t_1,
                                               t_2,
                                               offset=1,
                                               kind="tight")
     self.assertIsInstance(precedence_constraint, ps.TaskPrecedence)
示例#5
0
 def test_create_task_precedence_strict(self) -> None:
     pb = ps.SchedulingProblem("TaskPrecedenceStrict")
     t_1 = ps.FixedDurationTask("t1", duration=2)
     t_2 = ps.FixedDurationTask("t2", duration=3)
     ps.TaskPrecedence(t_1, t_2, offset=1, kind="strict")
     pb.add_objective_makespan()
     solver = ps.SchedulingSolver(pb)
     solution = solver.solve()
     self.assertTrue(solution)
     self.assertEqual(solution.tasks[t_2.name].start,
                      solution.tasks[t_1.name].end + 2)
示例#6
0
    def test_start_latest(self):
        problem = ps.SchedulingProblem("SolveStartLatest", horizon=51)
        # only one task, the solver should schedule a start time at 0
        task_1 = ps.FixedDurationTask("task1", duration=2)
        task_2 = ps.FixedDurationTask("task2", duration=3)

        ps.TaskPrecedence(task_1, task_2)

        problem.add_objective_start_latest()
        solution = _solve_problem(problem)
        self.assertTrue(solution)
        # check that the task is not scheduled to start à 0
        # the only solution is 1
        self.assertEqual(solution.tasks[task_1.name].start, 51 - (3 + 2))
        self.assertEqual(solution.tasks[task_2.name].start, 51 - 3)
示例#7
0
    def test_json_export_1(self):
        pb = ps.SchedulingProblem("JSONExport1", horizon=10)
        # tasks
        task_1 = ps.FixedDurationTask("task1", duration=3)
        task_2 = ps.VariableDurationTask("task2")
        task_3 = ps.ZeroDurationTask("task3")

        # buffers
        buffer_1 = ps.NonConcurrentBuffer("Buffer1", initial_state=10)
        buffer_2 = ps.NonConcurrentBuffer("Buffer2", initial_state=0)

        # resources
        worker_1 = ps.Worker("Worker1")
        worker_2 = ps.Worker("Worker2")
        worker_3 = ps.Worker("Worker3")

        sw_1 = ps.SelectWorkers([worker_1, worker_2, worker_3])
        sw_2 = ps.SelectWorkers([worker_1, worker_2, worker_3])
        sw_3 = ps.SelectWorkers([worker_1, worker_2, worker_3])

        ps.CumulativeWorker("CumulMachine1", size=3)
        ps.CumulativeWorker("CumulMachine2", size=7)

        # assign resources to tasks
        task_1.add_required_resources([worker_1, worker_2])
        task_2.add_required_resource(sw_1)
        task_3.add_required_resource(sw_2)

        # task constraints
        ps.TaskPrecedence(task_1, task_2)
        ps.TaskStartAt(task_1, 5)
        ps.TaskUnloadBuffer(task_1, buffer_1, quantity=3)
        ps.TaskLoadBuffer(task_1, buffer_2, quantity=2)

        # resource constraints
        ps.SameWorkers(sw_1, sw_2)
        ps.DistinctWorkers(sw_2, sw_3)
        ps.WorkLoad(worker_1, {(0, 6): 3, (19, 24): 4}, kind="exact")
        ps.ResourceUnavailable(worker_1, [(1, 3), (6, 8)])
        ps.ResourceTasksDistance(worker_1,
                                 distance=4,
                                 mode="exact",
                                 list_of_time_intervals=[[10, 18]])

        # export to json
        solver = ps.SchedulingSolver(pb)
        ps.export_json_to_file(pb, solver, "test_export_1.json")
    def test_optional_tasks_precedence_2(self) -> None:
        """Task 2 cannot be scheduled."""
        pb = ps.SchedulingProblem("OptionalTasksPrecedence2", horizon=8)
        task_1 = ps.FixedDurationTask("task1", duration=3)  # mandatory
        task_2 = ps.FixedDurationTask("task2", duration=4,
                                      optional=True)  # optional

        pb.add_constraint(ps.TaskStartAt(task_1, 0))
        pb.add_constraint(ps.TaskPrecedence(task_1, task_2, offset=2))

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()
        self.assertTrue(solution)
        self.assertTrue(solution.tasks[task_1.name].scheduled)
        self.assertFalse(solution.tasks[task_2.name].scheduled)
        self.assertEqual(solution.tasks[task_1.name].start, 0)
        self.assertEqual(solution.tasks[task_1.name].end, 3)
示例#9
0
    def test_schedule_two_fixed_duration_task_with_precedence(self) -> None:
        problem = ps.SchedulingProblem("TwoFixedDurationTasksWithPrecedence",
                                       horizon=5)
        task_1 = ps.FixedDurationTask("task1", duration=2)
        task_2 = ps.FixedDurationTask("task2", duration=3)

        # add two constraints to set start and end
        ps.TaskStartAt(task_1, 0)
        ps.TaskPrecedence(task_before=task_1, task_after=task_2)
        solution = _solve_problem(problem)
        self.assertTrue(solution)

        task_1_solution = solution.tasks[task_1.name]
        task_2_solution = solution.tasks[task_2.name]

        self.assertEqual(task_1_solution.start, 0)
        self.assertEqual(task_1_solution.end, 2)
        self.assertEqual(task_2_solution.start, 2)
        self.assertEqual(task_2_solution.end, 5)
    def test_optional_tasks_precedence_1(self) -> None:
        """Tasks can be scheduled."""
        pb = ps.SchedulingProblem("OptionalTasksPrecedence1", horizon=9)
        task_1 = ps.FixedDurationTask("task1", duration=3)  # mandatory
        task_2 = ps.FixedDurationTask("task2", duration=4,
                                      optional=True)  # optional

        pb.add_constraint(ps.TaskStartAt(task_1, 0))
        pb.add_constraint(ps.TaskPrecedence(task_1, task_2, offset=2))

        # Force schedule, otherwise by default it is not scheduled
        pb.add_constraint(task_2.scheduled == True)

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()
        self.assertTrue(solution)
        self.assertTrue(solution.tasks[task_1.name].scheduled)
        self.assertTrue(solution.tasks[task_2.name].scheduled)
        self.assertEqual(solution.tasks[task_1.name].start, 0)
        self.assertEqual(solution.tasks[task_1.name].end, 3)
        self.assertEqual(solution.tasks[task_2.name].start, 5)
        self.assertEqual(solution.tasks[task_2.name].end, 9)
    print("-> Problem size:", problem_size)
    # Teams and Resources

    init_time = time.perf_counter()

    pb = ps.SchedulingProblem("n_queens_type_scheduling", horizon=problem_size)
    R = {i: ps.Worker("W-%i" % i) for i in range(problem_size)}
    T = {
        (i, j): ps.FixedDurationTask("T-%i-%i" % (i, j), duration=1)
        for i in range(n)
        for j in range(problem_size)
    }
    # precedence constrains
    for i in range(problem_size):
        for j in range(1, problem_size):
            ps.TaskPrecedence(T[i, j - 1], T[i, j], offset=0)
    # resource assignment modulo n
    for j in range(problem_size):
        for i in range(problem_size):
            T[(i + j) % problem_size, j].add_required_resource(R[i])

    # create the solver and solve
    solver = ps.SchedulingSolver(pb, max_time=mt, logics=args.logics)
    solution = solver.solve()

    if not solution:
        break

    computation_times.append(time.perf_counter() - init_time)
    plot_abs.append(problem_size)