Source code for discrete_optimization.knapsack.transformations.to_generic
# 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.
"""
Transformation from Knapsack to GenSchedulingImpl
"""
from discrete_optimization.generic_tasks_tools.generic_scheduling_impl import (
GenericSchedulingImplProblem,
GenericSchedulingImplSolution,
)
from discrete_optimization.generic_tools.transformation.problem_transformation import (
ProblemTransformation,
)
from discrete_optimization.generic_tools.transformation.transformation_metadata import (
TransformationMetadata,
exact_transformation,
)
from discrete_optimization.knapsack.problem import KnapsackProblem, KnapsackSolution
[docs]
class KnapsackToGenericSchedulingTransformation(
ProblemTransformation[
KnapsackProblem,
KnapsackSolution,
GenericSchedulingImplProblem,
GenericSchedulingImplSolution,
]
):
"""
Transform Knapsack to GenericSchedulingImpl.
"""
[docs]
def get_forward_metadata(self) -> TransformationMetadata:
"""Metadata for forward problem transformation (Knapsack → GenSchedulingImpl).
This direction is EXACT: all constraints can be represented in GenSchedulingImpl.
"""
return exact_transformation(
use_cases=[
"Exact encoding of Knapsack as scheduling problem",
]
)
[docs]
def transform_problem(
self, source_problem: KnapsackProblem
) -> GenericSchedulingImplProblem:
"""Transform KnapsackProblem to GenericSchedulingImpl problem.
Args:
source_problem: KnapsackProblem problem instance
Returns:
Equivalent GenericSchedulingImpl problem
"""
tasks = [i for i in range(source_problem.nb_items)]
non_renewable_resource = {"weight": source_problem.max_capacity}
resource_consumption = {
i: {0: {"weight": source_problem.list_items[i].weight}} for i in tasks
}
from discrete_optimization.generic_tasks_tools.objectives.scheduled_tasks import (
ScheduledTasksComputer,
)
return GenericSchedulingImplProblem(
horizon=1,
durations_per_mode={i: {0: 0} for i in tasks},
resource_consumptions=resource_consumption,
non_renewable_resources=non_renewable_resource,
optional_tasks=set(tasks),
list_objective_computer=[
ScheduledTasksComputer(
weight_objective=-1, # Maximize.
weight_per_task={
i: source_problem.list_items[i].value for i in tasks
},
)
],
)
[docs]
def back_transform_solution(
self, solution: GenericSchedulingImplSolution, source_problem: KnapsackProblem
) -> KnapsackSolution:
"""Transform GenericSchedulingImpl solution back to Knapsack solution.
Returns:
Equivalent Knapsack solution
"""
list_taken = [False for i in range(source_problem.nb_items)]
for i in solution.problem.tasks_list:
if solution.is_present(i):
list_taken[i] = True
return KnapsackSolution(problem=source_problem, list_taken=list_taken)