예제 #1
0
    def test_create_task_variable_duration(self) -> None:
        pb = ps.SchedulingProblem("CreateVariableDurationTask")

        ps.VariableDurationTask("vdt1")
        vdt_2 = ps.VariableDurationTask("vdt2", max_duration=4)
        vdt_3 = ps.VariableDurationTask("vdt3", min_duration=5)

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()

        self.assertTrue(solution)
        self.assertTrue(solution.tasks[vdt_2.name].duration <= 4)
        self.assertTrue(solution.tasks[vdt_3.name].duration >= 5)
예제 #2
0
    def test_create_task_variable_duration_from_list(self) -> None:
        pb = ps.SchedulingProblem("CreateVariableDurationTaskFromList")

        vdt_1 = ps.VariableDurationTask("vdt1", allowed_durations=[3, 4])
        vdt_2 = ps.VariableDurationTask("vdt2", allowed_durations=[5, 6])
        vdt_3 = ps.VariableDurationTask("vdt3", allowed_durations=[7, 8])

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()

        self.assertTrue(solution)
        self.assertTrue(solution.tasks[vdt_1.name].duration in [3, 4])
        self.assertTrue(solution.tasks[vdt_2.name].duration in [5, 6])
        self.assertTrue(solution.tasks[vdt_3.name].duration in [7, 8])
예제 #3
0
 def test_nested_boolean_operators(self) -> None:
     new_problem_or_clear()
     t_1 = ps.VariableDurationTask("t1")
     or_constraint_1 = ps.or_([ps.TaskStartAt(t_1, 1), ps.TaskStartAt(t_1, 2)])
     or_constraint_2 = ps.or_([ps.TaskStartAt(t_1, 4), ps.TaskStartAt(t_1, 5)])
     and_constraint = ps.and_([or_constraint_1, or_constraint_2])
     self.assertIsInstance(and_constraint, ps.BoolRef)
예제 #4
0
 def test_print_objects(self) -> None:
     new_problem_or_clear()
     t1 = ps.FixedDurationTask("task_1", duration=1)
     t2 = ps.VariableDurationTask("task_2")
     worker_1 = ps.Worker("W1")
     self.assertTrue("task_1" in "%s" % t1)
     self.assertTrue("task_2" in "%s" % t2)
     self.assertTrue("W1" in "%s" % worker_1)
    def test_force_schedule_optional_tasks_3(self) -> None:
        """Check an error is raised if ever one of the task is not optional."""
        ps.SchedulingProblem("ForceScheduleOptionalTasks3", horizon=14)
        task_1 = ps.VariableDurationTask("task1")  # this one is not optional
        task_2 = ps.FixedDurationTask("task2", duration=7, optional=True)

        with self.assertRaises(TypeError):
            ps.ForceScheduleNOptionalTasks([task_1, task_2], 2)
예제 #6
0
    def test_task_duration_depend_on_start(self) -> None:
        pb = ps.SchedulingProblem("TaskDurationDependsOnStart", horizon=30)

        task_1 = ps.VariableDurationTask("Task1")
        task_2 = ps.VariableDurationTask("Task2")

        ps.TaskStartAt(task_1, 5)
        pb.add_constraint(task_1.duration == task_1.start * 3)

        ps.TaskStartAt(task_2, 11)
        pb.add_constraint(
            ps.if_then_else(task_2.start < 10, [task_2.duration == 3],
                            [task_2.duration == 1]))

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()
        self.assertTrue(solution)
        self.assertEqual(solution.tasks["Task1"].duration, 15)
        self.assertEqual(solution.tasks["Task2"].duration, 1)
예제 #7
0
    def test_cumulative_productivity(self):
        """Horizon should be 4, 100/29=3.44."""
        problem = ps.SchedulingProblem("CumulativeProductivity")
        t_1 = ps.VariableDurationTask("t1", work_amount=100)

        worker_1 = ps.CumulativeWorker("CumulWorker", size=3, productivity=29)
        t_1.add_required_resource(worker_1)

        problem.add_objective_makespan()
        solution = ps.SchedulingSolver(problem).solve()
        self.assertTrue(solution)
        self.assertEqual(solution.horizon, 4)
예제 #8
0
    def test_work_amount_2(self):
        # try the same problem than above, but with one more resource
        # check that the task duration is lower
        problem = ps.SchedulingProblem("WorkAmount", horizon=4)

        task_1 = ps.VariableDurationTask("task1", work_amount=11)
        # create two workers
        worker_1 = ps.Worker("Worker1", productivity=2)
        worker_2 = ps.Worker("Worker2", productivity=3)
        task_1.add_required_resources([worker_1, worker_2])
        # solve
        self.assertTrue(_solve_problem(problem))
예제 #9
0
    def test_work_amount_1(self):
        problem = ps.SchedulingProblem("WorkAmount")

        task_1 = ps.VariableDurationTask("task1", work_amount=11)
        # create one worker with a productivity of 2
        worker_1 = ps.Worker("Worker1", productivity=2)
        task_1.add_required_resource(worker_1)
        # solve
        solution = _solve_problem(problem)
        self.assertTrue(solution)
        # the expected duration for task 1 is 6
        self.assertEqual(solution.tasks[task_1.name].duration, 6)
예제 #10
0
    def test_schedule_single_variable_duration_task(self) -> None:
        problem = ps.SchedulingProblem("SingleVariableDurationTaskScheduling")
        task = ps.VariableDurationTask("task")

        # add two constraints to set start and end
        ps.TaskStartAt(task, 1)
        ps.TaskEndAt(task, 4)

        solution = _solve_problem(problem)
        self.assertTrue(solution)
        # task should have been scheduled with start at 0
        # and end at 2
        task_solution = solution.tasks[task.name]
        self.assertEqual(task_solution.start, 1)
        self.assertEqual(task_solution.duration, 3)
        self.assertEqual(task_solution.end, 4)
예제 #11
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")
예제 #12
0
    def test_constant_cost_per_period_2(self) -> None:
        problem = ps.SchedulingProblem(
            "IndicatorResourceConstantCostPerPeriod12")
        t_1 = ps.VariableDurationTask("t1", work_amount=100)
        worker_1 = ps.Worker("Worker1",
                             productivity=4,
                             cost=ps.ConstantCostPerPeriod(10))
        worker_2 = ps.Worker("Worker2",
                             productivity=7,
                             cost=ps.ConstantCostPerPeriod(20))
        all_workers = [worker_1, worker_2]
        problem.add_objective_makespan()
        t_1.add_required_resources(all_workers)
        cost_ind = problem.add_indicator_resource_cost(all_workers)

        solution = ps.SchedulingSolver(problem).solve()

        self.assertTrue(solution)
        self.assertEqual(solution.indicators[cost_ind.name], 300)
예제 #13
0
 def test_task_types(self) -> None:
     new_problem_or_clear()
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt5", max_duration=4.5)
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt6", max_duration=-1)
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt7", min_duration=-1)
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt8", work_amount=-1)
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt9", work_amount=1.5)
     with self.assertRaises(TypeError):
         ps.VariableDurationTask("vdt10", work_amount=None)
예제 #14
0
    def test_force_schedule_optional_tasks_2(self) -> None:
        """Just change the number of tasks to be scheduled."""
        pb = ps.SchedulingProblem("ForceScheduleOptionalTasks2", horizon=14)
        task_1 = ps.VariableDurationTask("task1", optional=True)
        task_2 = ps.FixedDurationTask("task2", duration=7, optional=True)
        task_3 = ps.FixedDurationTask("task3", duration=2, optional=True)

        ps.ForceScheduleNOptionalTasks([task_1, task_2, task_3], 2)

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()
        self.assertTrue(solution)

        results = [
            solution.tasks[task_1.name].scheduled,
            solution.tasks[task_2.name].scheduled,
            solution.tasks[task_3.name].scheduled,
        ]

        self.assertEqual(results.count(True), 2)
예제 #15
0
    def test_force_schedule_optional_tasks(self) -> None:
        """task_3 is not scheduled, because task_2 should not."""
        pb = ps.SchedulingProblem("ForceScheduleOptionalTasks", horizon=9)
        task_1 = ps.VariableDurationTask("task1", optional=True)
        task_2 = ps.FixedDurationTask("task2", duration=4, optional=True)
        task_3 = ps.FixedDurationTask("task3", duration=1, optional=True)

        ps.ForceScheduleNOptionalTasks([task_1, task_2, task_3], 1)

        solver = ps.SchedulingSolver(pb)
        solution = solver.solve()
        self.assertTrue(solution)

        results = [
            solution.tasks[task_1.name].scheduled,
            solution.tasks[task_2.name].scheduled,
            solution.tasks[task_3.name].scheduled,
        ]

        self.assertEqual(results.count(True), 1)
예제 #16
0
 def test_task_same_names(self) -> None:
     new_problem_or_clear()
     ps.VariableDurationTask("t1")
     with self.assertRaises(ValueError):
         ps.VariableDurationTask("t1")