Source code for discrete_optimization.rcpsp_exclusion.problem

#  Copyright (c) 2026 AIRBUS and its affiliates.
#  This source code is licensed under the MIT license found in the
#  LICENSE file in the root directory of this source tree.
#  Copyright (c) 2026 AIRBUS and its affiliates.
#  This source code is licensed under the MIT license found in the
#  LICENSE file in the root directory of this source tree.

from __future__ import annotations

import logging
from collections.abc import Hashable
from typing import Any, Optional, Union

from discrete_optimization.generic_tasks_tools.exclusions import ExclusionResource
from discrete_optimization.generic_tasks_tools.utils import optional_override_implem
from discrete_optimization.rcpsp import RcpspProblem
from discrete_optimization.rcpsp.solution import (
    Task,
)
from discrete_optimization.rcpsp.special_constraints import (
    SpecialConstraintsDescription,
)

logger = logging.getLogger(__name__)


[docs] class RcpspProblemWithExclusion(RcpspProblem): def __init__( self, resources: dict[str, Union[int, list[int]]], non_renewable_resources: list[str], mode_details: dict[Hashable, dict[int, dict[str, int]]], successors: dict[Hashable, list[Hashable]], horizon: int, tasks_list: Optional[list[Hashable]] = None, source_task: Optional[Hashable] = None, sink_task: Optional[Hashable] = None, name_task: Optional[dict[Hashable, str]] = None, calendar_details: Optional[dict[str, list[list[int]]]] = None, special_constraints: Optional[SpecialConstraintsDescription] = None, fixed_permutation: Optional[list[int]] = None, fixed_modes: Optional[list[int]] = None, exclusion_resource_capacity: dict[ExclusionResource, int] = None, exclusion_resource_consumptions: dict[ Task, dict[int, dict[ExclusionResource, int]] ] = None, exclusion_resource_boolean: dict[ Task, dict[int, dict[ExclusionResource, bool]] ] = None, **kwargs: Any, ): super().__init__( resources=resources, non_renewable_resources=non_renewable_resources, mode_details=mode_details, successors=successors, horizon=horizon, tasks_list=tasks_list, source_task=source_task, sink_task=sink_task, name_task=name_task, calendar_details=calendar_details, special_constraints=special_constraints, fixed_permutation=fixed_permutation, fixed_modes=fixed_modes, **kwargs, ) self.exclusion_resource_capacity = exclusion_resource_capacity self.exclusion_resource_consumptions = exclusion_resource_consumptions self.exclusion_resource_boolean = exclusion_resource_boolean
[docs] @optional_override_implem def is_task_mode_excluding_others( self, task: Task, mode: int, resource: ExclusionResource ) -> bool: if task in self.exclusion_resource_boolean: if mode in self.exclusion_resource_boolean[task]: if resource in self.exclusion_resource_boolean[task][mode]: return self.exclusion_resource_boolean[task][mode][resource] return False
[docs] @optional_override_implem def get_task_consumption_exclusion_resource( self, resource: ExclusionResource, task: Task, mode: int ): if task in self.exclusion_resource_consumptions: if mode in self.exclusion_resource_consumptions[task]: if resource in self.exclusion_resource_consumptions[task][mode]: return self.exclusion_resource_consumptions[task][mode][resource] return 0
@property @optional_override_implem def exclusion_resources_list(self) -> list[ExclusionResource]: return list(self.exclusion_resource_capacity.keys())
[docs] @optional_override_implem def get_capacity_exclusion_resource(self, resource: ExclusionResource): return self.exclusion_resource_capacity[resource]