Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python easy_score_calculator results in KeyError #1280

Open
luxaritas opened this issue Dec 20, 2024 · 0 comments
Open

Python easy_score_calculator results in KeyError #1280

luxaritas opened this issue Dec 20, 2024 · 0 comments
Labels
bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc.

Comments

@luxaritas
Copy link
Contributor

Describe the bug
Attempting to use easy_score_calculator in a python solver causes a runtime error

Expected behavior
No error

Actual behavior

Traceback (most recent call last):
  File "DefaultSolver.java", line 196, in ai.timefold.solver.core.impl.solver.DefaultSolver.solve
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/_solver.py", line 109, in solve
    java_solution = self._delegate.solve(java_problem)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ai.timefold.jpyinterpreter.types.errors.lookup.ai.timefold.jpyinterpreter.types.errors.lookup.KeyError: ai.timefold.jpyinterpreter.types.errors.lookup.KeyError: HardSoftScore

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/repro.py", line 51, in <module>
    res = solver.solve(problem)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/_solver.py", line 111, in solve
    raise unwrap_python_like_object(e)
_jpyinterpreter.conversions.unwrap_python_like_object.<locals>.WrappedException: 
KeyError: HardSoftScore
Traceback (most recent call last):
  File "DefaultSolver.java", line 196, in solve
  File "DefaultSolver.java", line 225, in solvingStarted
  File "AbstractSolver.java", line 66, in solvingStarted
  File "BestSolutionRecaller.java", line 50, in solvingStarted
  File "EasyScoreDirector.java", line 49, in calculateScore
  File "<unknown>", line -1, in calculateScore
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/score/_annotations.py", line 89, in wrapped_easy_score_calculator
    return easy_score_calculator_function(solution)._to_java_score()
  File "<unknown>", line -1, in $call
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/score/_score.py", line 169, in HardSoftScore
    def _to_java_score(self):
  File "/home/jonathan/Development/eterna/OpenKnotScorePipeline/.venv/lib/python3.12/site-packages/timefold/solver/score/_score.py", line 173, in _to_java_score
    return _java_score_mapping_dict['HardSoftScore'].of(self.hard_score, self.soft_score)
KeyError: HardSoftScore

To Reproduce

from typing import Annotated
from dataclasses import dataclass, field
from timefold.solver.domain import (
    PlanningVariable,
    PlanningEntityCollectionProperty,
    PlanningScore, ValueRangeProvider,
    planning_entity, planning_solution
)
from timefold.solver.score import HardSoftScore, easy_score_calculator
from timefold.solver import SolverFactory
from timefold.solver.config import SolverConfig, ScoreDirectorFactoryConfig, TerminationConfig, Duration

@planning_entity
@dataclass
class ResourceConfiguration:
    cpus: Annotated[int, PlanningVariable(value_range_provider_refs = ['cpu_range'])] = 1

    def get_cpu_range(self) -> Annotated[list[int], ValueRangeProvider(id='cpu_range')]:
        return list(range(1, 5))

@planning_solution
@dataclass
class Schedule:
    resource_configurations: Annotated[list[ResourceConfiguration], PlanningEntityCollectionProperty]

    score: Annotated[HardSoftScore, PlanningScore] = field(default=None)

@easy_score_calculator
def score(solution):
    return HardSoftScore(0, 0)

solver_factory = SolverFactory.create(
    SolverConfig(
        solution_class=Schedule,
        entity_class_list=[ResourceConfiguration],
        score_director_factory_config=ScoreDirectorFactoryConfig(
            easy_score_calculator_function=score,
        ),
        termination_config=TerminationConfig(
            spent_limit=Duration(seconds=1)
        )
    )
)
problem = Schedule([ResourceConfiguration()])
solver_factory.build_solver().solve(problem)

Environment

Timefold Solver Version or Git ref:
1.17.0

Output of java -version:

openjdk version "23" 2024-09-17
OpenJDK Runtime Environment (build 23)
OpenJDK 64-Bit Server VM (build 23, mixed mode, sharing)

Output of uname -a or ver:

Linux 6.6.63-1-MANJARO #1 SMP PREEMPT_DYNAMIC Sat Nov 23 02:15:34 UTC 2024 x86_64 GNU/Linux
@luxaritas luxaritas added bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc. labels Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working process/needs triage Requires initial assessment of validity, priority etc.
Projects
None yet
Development

No branches or pull requests

1 participant